package com.alibaba.rocketmq.namesrv.processor; import static com.alibaba.rocketmq.common.protocol.MQProtos.MQRequestCode.REGISTER_BROKER_SINGLE_VALUE; import static com.alibaba.rocketmq.common.protocol.MQProtos.MQRequestCode.REGISTER_ORDER_TOPIC_SINGLE_VALUE; import static com.alibaba.rocketmq.namesrv.sync.TaskType.REG_BROKER; import static com.alibaba.rocketmq.namesrv.sync.TaskType.REG_TOPIC; import static com.alibaba.rocketmq.namesrv.sync.TaskType.UNREG_BROKER; import static com.alibaba.rocketmq.remoting.protocol.RemotingProtos.ResponseCode.SUCCESS_VALUE; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.rocketmq.common.MixAll; import com.alibaba.rocketmq.common.namesrv.NamesrvConfig; import com.alibaba.rocketmq.common.protocol.MQProtos.MQRequestCode; import com.alibaba.rocketmq.common.protocol.header.namesrv.RegisterBrokerRequestHeader; import com.alibaba.rocketmq.common.protocol.header.namesrv.RegisterOrderTopicRequestHeader; import com.alibaba.rocketmq.common.protocol.header.namesrv.UnRegisterBrokerRequestHeader; import com.alibaba.rocketmq.namesrv.common.Result; import com.alibaba.rocketmq.namesrv.sync.Exec; import com.alibaba.rocketmq.namesrv.sync.FutureGroup; import com.alibaba.rocketmq.namesrv.sync.TaskGroup; import com.alibaba.rocketmq.namesrv.sync.TaskGroupExecutor; import com.alibaba.rocketmq.namesrv.sync.TaskType; import com.alibaba.rocketmq.remoting.common.RemotingHelper; import com.alibaba.rocketmq.remoting.protocol.RemotingCommand; /** * @author lansheng.zj@taobao.com */ public class ChangeSpreadProcessor { private static final Logger log = LoggerFactory.getLogger(MixAll.NamesrvLoggerName); private Map<Integer, TaskGroup<Result, String[]>> taskGroupMap; private TaskGroupExecutor<Result, String[]> clientTaskGroupExecutor; private NamesrvConfig namesrvConf; public ChangeSpreadProcessor(NamesrvConfig namesrvConf) { this.namesrvConf = namesrvConf; taskGroupMap = createTaskMap(); clientTaskGroupExecutor = new TaskGroupExecutor<Result, String[]>(new ThreadFactory() { private AtomicInteger index = new AtomicInteger(0); @Override public Thread newThread(Runnable r) { return new Thread(r, "client-taskgroup-executor-" + index.getAndIncrement()); } }); } public void init() { namesrvConf.addPropertyChangeListener("namesrvAddr", new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // copyOnWirte taskGroupMap = createTaskMap(); } }); } public Map<Integer, TaskGroup<Result, String[]>> createTaskMap() { Map<Integer, TaskGroup<Result, String[]>> map = new HashMap<Integer, TaskGroup<Result, String[]>>(); map.put(REG_BROKER, createTaskGroup(REG_BROKER)); map.put(REG_TOPIC, createTaskGroup(REG_TOPIC)); map.put(UNREG_BROKER, createTaskGroup(UNREG_BROKER)); return map; } public FutureGroup<Result> spreadChange(int type, String[] values) { TaskGroup<Result, String[]> taskGroup = null; switch (type) { case REG_BROKER: taskGroup = taskGroupMap.get(REG_BROKER); break; case REG_TOPIC: taskGroup = taskGroupMap.get(REG_TOPIC); break; case UNREG_BROKER: taskGroup = taskGroupMap.get(UNREG_BROKER); break; default: // TODO } return clientTaskGroupExecutor.groupCommit(taskGroup, values); } /** * ���������� * * @param type * �������� {@link TaskType} * @return */ public TaskGroup<Result, String[]> createTaskGroup(int type) { // �ų�������������ע������ TaskGroup<Result, String[]> taskGroup = new TaskGroup<Result, String[]>(); String namesrv = namesrvConf.getNamesrvAddr(); if (null != namesrv && !"".equals(namesrv)) { String[] addresses = namesrv.split(";"); for (String address : addresses) { if (!MixAll.isLocalAddr(address)) { switch (type) { case REG_BROKER: taskGroup.addTask(address, createRegBrokerTask(address)); break; case REG_TOPIC: taskGroup.addTask(address, createRegTopicTask(address)); break; case UNREG_BROKER: taskGroup.addTask(address, createUnRegBrokerTask(address)); break; default: // TODO } } } } return taskGroup; } public Exec<Result, String[]> createRegBrokerTask(final String address) { return new Exec<Result, String[]>() { @Override public void beforeExec() { // TODO } @Override public Result doExec(String[] brokerAddr) throws Exception { RegisterBrokerRequestHeader regBrokerRequestHeader = new RegisterBrokerRequestHeader(); regBrokerRequestHeader.setBrokerAddr(brokerAddr[0]); RemotingCommand request = RemotingCommand.createRequestCommand(REGISTER_BROKER_SINGLE_VALUE, regBrokerRequestHeader); RemotingCommand response = RemotingHelper.invokeSync(address, request, namesrvConf.getSyncTimeout()); if (SUCCESS_VALUE == response.getCode()) { // TODO return Result.SUCCESS; } else { // record failure log.error("register broker single fail. code" + response.getCode() + ",remark:" + response.getRemark()); return new Result(false, "code:" + response.getCode() + ",remark:" + response.getRemark()); } } }; } public Exec<Result, String[]> createRegTopicTask(final String address) { return new Exec<Result, String[]>() { @Override public void beforeExec() { // TODO } @Override public Result doExec(String[] ts) throws Exception { RegisterOrderTopicRequestHeader regOrderTopicRequestHeader = new RegisterOrderTopicRequestHeader(); regOrderTopicRequestHeader.setTopic(ts[0]); regOrderTopicRequestHeader.setOrderTopicString(ts[1]); RemotingCommand request = RemotingCommand.createRequestCommand(REGISTER_ORDER_TOPIC_SINGLE_VALUE, regOrderTopicRequestHeader); RemotingCommand response = RemotingHelper.invokeSync(address, request, namesrvConf.getSyncTimeout()); if (SUCCESS_VALUE == response.getCode()) { // TODO return Result.SUCCESS; } else { // record failure log.error("register order topic single fail. code" + response.getCode() + ",remark:" + response.getRemark()); return new Result(false, "code:" + response.getCode() + ",remark:" + response.getRemark()); } } }; } public Exec<Result, String[]> createUnRegBrokerTask(final String address) { return new Exec<Result, String[]>() { @Override public void beforeExec() { // TODO } @Override public Result doExec(String[] brokerName) throws Exception { UnRegisterBrokerRequestHeader unRegisterBrokerRequestHeader = new UnRegisterBrokerRequestHeader(); unRegisterBrokerRequestHeader.setBrokerName(brokerName[0]); RemotingCommand request = RemotingCommand.createRequestCommand(MQRequestCode.UNREGISTER_BROKER_SINGLE_VALUE, unRegisterBrokerRequestHeader); RemotingCommand response = RemotingHelper.invokeSync(address, request, namesrvConf.getSyncTimeout()); if (SUCCESS_VALUE == response.getCode()) { // TODO return Result.SUCCESS; } else { // record failure log.error("register broker single fail. code" + response.getCode() + ",remark:" + response.getRemark()); return new Result(false, "code:" + response.getCode() + ",remark:" + response.getRemark()); } } }; } public void shutdown() { clientTaskGroupExecutor.shutdown(); } }