/**
* $Id: AdminBrokerProcessor.java 1831 2013-05-16 01:39:51Z shijia.wxr $
*/
package com.alibaba.rocketmq.broker.processor;
import io.netty.channel.ChannelHandlerContext;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.rocketmq.broker.BrokerController;
import com.alibaba.rocketmq.common.MixAll;
import com.alibaba.rocketmq.common.TopicConfig;
import com.alibaba.rocketmq.common.protocol.MQProtos.MQRequestCode;
import com.alibaba.rocketmq.common.protocol.MQProtos.MQResponseCode;
import com.alibaba.rocketmq.common.protocol.header.CreateTopicRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.DeleteTopicRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.GetAllTopicConfigResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.GetBrokerConfigResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.GetEarliestMsgStoretimeRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.GetEarliestMsgStoretimeResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.GetMaxOffsetRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.GetMaxOffsetResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.GetMinOffsetRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.GetMinOffsetResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.QueryConsumerOffsetRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.QueryConsumerOffsetResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.SearchOffsetRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.SearchOffsetResponseHeader;
import com.alibaba.rocketmq.common.protocol.header.UpdateConsumerOffsetRequestHeader;
import com.alibaba.rocketmq.common.protocol.header.UpdateConsumerOffsetResponseHeader;
import com.alibaba.rocketmq.remoting.exception.RemotingCommandException;
import com.alibaba.rocketmq.remoting.netty.NettyRequestProcessor;
import com.alibaba.rocketmq.remoting.protocol.RemotingCommand;
import com.alibaba.rocketmq.remoting.protocol.RemotingProtos.ResponseCode;
/**
* @author vintage.wang@gmail.com shijia.wxr@taobao.com
*
*/
public class AdminBrokerProcessor implements NettyRequestProcessor {
private static final Logger log = LoggerFactory.getLogger(MixAll.BrokerLoggerName);
private final BrokerController brokerController;
public AdminBrokerProcessor(final BrokerController brokerController) {
this.brokerController = brokerController;
}
@Override
public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
MQRequestCode code = MQRequestCode.valueOf(request.getCode());
log.info("broker receive admin [" + code + "] request, " + request + " client: "
+ ctx.channel().remoteAddress());
switch (code) {
// ���´���Topic
case UPDATE_AND_CREATE_TOPIC:
return this.updateAndCreateTopic(ctx, request);
// ɾ��Topic
case DELETE_TOPIC:
return this.deleteTopic(ctx, request);
// ��ȡTopic����
case GET_ALL_TOPIC_CONFIG:
return this.getAllTopicConfig(ctx, request);
// ����Broker���� TODO ���ܴ��ڲ�������
case UPDATE_BROKER_CONFIG:
return this.updateBrokerConfig(ctx, request);
// ��ȡBroker����
case GET_BROKER_CONFIG:
return this.getBrokerConfig(ctx, request);
// ����ʱ���ѯOffset
case SEARCH_OFFSET_BY_TIMESTAMP:
return this.searchOffsetByTimestamp(ctx, request);
case GET_MAX_OFFSET:
return this.getMaxOffset(ctx, request);
case GET_MIN_OFFSET:
return this.getMinOffset(ctx, request);
case GET_EARLIEST_MSG_STORETIME:
return this.getEarliestMsgStoretime(ctx, request);
// ����Consumer Offset
case UPDATE_CONSUMER_OFFSET:
return this.updateConsumerOffset(ctx, request);
case QUERY_CONSUMER_OFFSET:
return this.queryConsumerOffset(ctx, request);
// ��ȡBroker����ʱ��Ϣ
case GET_BROKER_RUNTIME_INFO:
break;
case PULL_ALL_CONSUMER_OFFSET:
break;
case QUERY_BROKER_OFFSET:
break;
case QUERY_MESSAGE:
break;
case REGISTER_BROKER:
break;
case REGISTER_ORDER_TOPIC:
break;
case SEND_MESSAGE:
break;
case TRIGGER_DELETE_FILES:
break;
case UNREGISTER_BROKER:
break;
case UNREGISTER_ORDER_TOPIC:
break;
case UPDATE_NAMESRV_CONFIG:
break;
default:
break;
}
return null;
}
private RemotingCommand updateAndCreateTopic(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
final CreateTopicRequestHeader requestHeader =
(CreateTopicRequestHeader) request.decodeCommandCustomHeader(CreateTopicRequestHeader.class);
TopicConfig topicConfig = new TopicConfig(requestHeader.getTopic());
topicConfig.setReadQueueNums(requestHeader.getReadQueueNums());
topicConfig.setWriteQueueNums(requestHeader.getWriteQueueNums());
topicConfig.setTopicFilterType(requestHeader.getTopicFilterTypeEnum());
topicConfig.setPerm(requestHeader.getPerm());
this.brokerController.getTopicConfigManager().updateTopicConfig(topicConfig);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand deleteTopic(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
DeleteTopicRequestHeader requestHeader =
(DeleteTopicRequestHeader) request.decodeCommandCustomHeader(DeleteTopicRequestHeader.class);
this.brokerController.getTopicConfigManager().deleteTopicConfig(requestHeader.getTopic());
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand getAllTopicConfig(ChannelHandlerContext ctx, RemotingCommand request) {
final RemotingCommand response =
RemotingCommand.createResponseCommand(GetAllTopicConfigResponseHeader.class);
final GetAllTopicConfigResponseHeader responseHeader =
(GetAllTopicConfigResponseHeader) response.getCustomHeader();
String content = this.brokerController.getTopicConfigManager().encodeIncludeSysTopic();
if (content != null && content.length() > 0) {
try {
response.setBody(content.getBytes(MixAll.DEFAULT_CHARSET));
}
catch (UnsupportedEncodingException e) {
log.error("", e);
response.setCode(ResponseCode.SYSTEM_ERROR_VALUE);
response.setRemark("UnsupportedEncodingException " + e);
return response;
}
}
else {
log.error("No topic in this broker, client: " + ctx.channel().remoteAddress());
response.setCode(ResponseCode.SYSTEM_ERROR_VALUE);
response.setRemark("No topic in this broker");
return response;
}
responseHeader.setVersion(brokerController.getTopicConfigManager().getCurrentDataVersion());
responseHeader.setBrokerName(brokerController.getBrokerConfig().getBrokerName());
responseHeader.setBrokerId(brokerController.getBrokerConfig().getBrokerId());
responseHeader.setClusterName(brokerController.getBrokerConfig().getBrokerClusterName());
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand updateBrokerConfig(ChannelHandlerContext ctx, RemotingCommand request) {
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
byte[] body = request.getBody();
if (body != null) {
try {
String bodyStr = new String(body, MixAll.DEFAULT_CHARSET);
Properties properties = MixAll.string2Properties(bodyStr);
if (properties != null) {
log.info("updateBrokerConfig, new config: " + properties + " client: "
+ ctx.channel().remoteAddress());
this.brokerController.updateAllConfig(properties);
}
else {
log.error("string2Properties error");
response.setCode(ResponseCode.SYSTEM_ERROR_VALUE);
response.setRemark("string2Properties error");
return response;
}
}
catch (UnsupportedEncodingException e) {
log.error("", e);
response.setCode(ResponseCode.SYSTEM_ERROR_VALUE);
response.setRemark("UnsupportedEncodingException " + e);
return response;
}
}
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand getBrokerConfig(ChannelHandlerContext ctx, RemotingCommand request) {
final RemotingCommand response =
RemotingCommand.createResponseCommand(GetBrokerConfigResponseHeader.class);
final GetBrokerConfigResponseHeader responseHeader =
(GetBrokerConfigResponseHeader) response.getCustomHeader();
String content = this.brokerController.encodeAllConfig();
if (content != null && content.length() > 0) {
try {
response.setBody(content.getBytes(MixAll.DEFAULT_CHARSET));
}
catch (UnsupportedEncodingException e) {
log.error("", e);
response.setCode(ResponseCode.SYSTEM_ERROR_VALUE);
response.setRemark("UnsupportedEncodingException " + e);
return response;
}
}
responseHeader.setVersion(this.brokerController.getConfigDataVersion());
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand getBrokerRuntimeInfo(ChannelHandlerContext ctx, RemotingCommand request) {
final RemotingCommand response = RemotingCommand.createResponseCommand(null);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand searchOffsetByTimestamp(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response = RemotingCommand.createResponseCommand(SearchOffsetResponseHeader.class);
final SearchOffsetResponseHeader responseHeader = (SearchOffsetResponseHeader) response.getCustomHeader();
final SearchOffsetRequestHeader requestHeader =
(SearchOffsetRequestHeader) request.decodeCommandCustomHeader(SearchOffsetRequestHeader.class);
long offset =
this.brokerController.getMessageStore().getOffsetInQueueByTime(requestHeader.getTopic(),
requestHeader.getQueueId(), requestHeader.getTimestamp());
responseHeader.setOffset(offset);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand getMaxOffset(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response = RemotingCommand.createResponseCommand(GetMaxOffsetResponseHeader.class);
final GetMaxOffsetResponseHeader responseHeader = (GetMaxOffsetResponseHeader) response.getCustomHeader();
final GetMaxOffsetRequestHeader requestHeader =
(GetMaxOffsetRequestHeader) request.decodeCommandCustomHeader(GetMaxOffsetRequestHeader.class);
long offset =
this.brokerController.getMessageStore().getMaxOffsetInQuque(requestHeader.getTopic(),
requestHeader.getQueueId());
responseHeader.setOffset(offset);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand getMinOffset(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response = RemotingCommand.createResponseCommand(GetMinOffsetResponseHeader.class);
final GetMinOffsetResponseHeader responseHeader = (GetMinOffsetResponseHeader) response.getCustomHeader();
final GetMinOffsetRequestHeader requestHeader =
(GetMinOffsetRequestHeader) request.decodeCommandCustomHeader(GetMinOffsetRequestHeader.class);
long offset =
this.brokerController.getMessageStore().getMinOffsetInQuque(requestHeader.getTopic(),
requestHeader.getQueueId());
responseHeader.setOffset(offset);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand getEarliestMsgStoretime(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response =
RemotingCommand.createResponseCommand(GetEarliestMsgStoretimeResponseHeader.class);
final GetEarliestMsgStoretimeResponseHeader responseHeader =
(GetEarliestMsgStoretimeResponseHeader) response.getCustomHeader();
final GetEarliestMsgStoretimeRequestHeader requestHeader =
(GetEarliestMsgStoretimeRequestHeader) request
.decodeCommandCustomHeader(GetEarliestMsgStoretimeRequestHeader.class);
long timestamp =
this.brokerController.getMessageStore().getEarliestMessageTime(requestHeader.getTopic(),
requestHeader.getQueueId());
responseHeader.setTimestamp(timestamp);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand updateConsumerOffset(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response =
RemotingCommand.createResponseCommand(UpdateConsumerOffsetResponseHeader.class);
final UpdateConsumerOffsetResponseHeader responseHeader =
(UpdateConsumerOffsetResponseHeader) response.getCustomHeader();
final UpdateConsumerOffsetRequestHeader requestHeader =
(UpdateConsumerOffsetRequestHeader) request
.decodeCommandCustomHeader(UpdateConsumerOffsetRequestHeader.class);
this.brokerController.getConsumerOffsetManager().commitOffset(requestHeader.getConsumerGroup(),
requestHeader.getTopic(), requestHeader.getQueueId(), requestHeader.getCommitOffset());
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
return response;
}
private RemotingCommand queryConsumerOffset(ChannelHandlerContext ctx, RemotingCommand request)
throws RemotingCommandException {
final RemotingCommand response =
RemotingCommand.createResponseCommand(QueryConsumerOffsetResponseHeader.class);
final QueryConsumerOffsetResponseHeader responseHeader =
(QueryConsumerOffsetResponseHeader) response.getCustomHeader();
final QueryConsumerOffsetRequestHeader requestHeader =
(QueryConsumerOffsetRequestHeader) request
.decodeCommandCustomHeader(QueryConsumerOffsetRequestHeader.class);
long offset =
this.brokerController.getConsumerOffsetManager().queryOffset(requestHeader.getConsumerGroup(),
requestHeader.getTopic(), requestHeader.getQueueId());
if (offset >= 0) {
responseHeader.setOffset(offset);
response.setCode(ResponseCode.SUCCESS_VALUE);
response.setRemark(null);
}
else {
response.setCode(MQResponseCode.QUERY_NOT_FOUND_VALUE);
response.setRemark("Not found, maybe this group consumer boot first");
}
return response;
}
}