/*
* (C) 2007-2012 Alibaba Group Holding Limited.
*
* Licensed 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.
* Authors:
* wuhua <wq163@163.com>
*/
package com.taobao.metamorphosis.metaslave;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.taobao.metamorphosis.cluster.Broker;
import com.taobao.metamorphosis.cluster.Partition;
import com.taobao.metamorphosis.server.assembly.MetaMorphosisBroker;
import com.taobao.metamorphosis.utils.MetaZookeeper;
/**
* �����zk����,�����master��zk�ϵ�ע��
*
* @author ��,dennis
* @since 2011-6-24 ����05:46:36
*/
class SlaveZooKeeper {
private static final Log log = LogFactory.getLog(SlaveZooKeeper.class);
private final MetaMorphosisBroker broker;
private final SubscribeHandler subscribeHandler;
private final MasterBrokerIdListener masterBrokerIdListener;
private final String masterBrokerIdsPath;
private final String masterConfigFileChecksumPath;
public SlaveZooKeeper(final MetaMorphosisBroker broker, final SubscribeHandler subscribeHandler) {
this.broker = broker;
this.subscribeHandler = subscribeHandler;
int brokerId = this.broker.getMetaConfig().getBrokerId();
this.masterBrokerIdsPath = this.getMetaZookeeper().brokerIdsPathOf(brokerId, -1);
this.masterConfigFileChecksumPath = this.getMetaZookeeper().masterConfigChecksum(brokerId);
this.masterBrokerIdListener = new MasterBrokerIdListener();
}
public void start() {
// ����zk��Ϣ�仯
this.getZkClient().subscribeDataChanges(this.masterBrokerIdsPath, this.masterBrokerIdListener);
this.getZkClient().subscribeDataChanges(this.masterConfigFileChecksumPath, this.masterBrokerIdListener);
}
public String getMasterServerUrl() {
final Broker masterBroker =
this.getMetaZookeeper().getMasterBrokerById(this.broker.getMetaConfig().getBrokerId());
return masterBroker != null ? masterBroker.getZKString() : null;
}
public Map<String, List<Partition>> getPartitionsForTopicsFromMaster() {
return this.getMetaZookeeper().getPartitionsForSubTopicsFromMaster(this.getMasterTopics(),
this.broker.getMetaConfig().getBrokerId());
}
private Set<String> getMasterTopics() {
return this.getMetaZookeeper().getTopicsByBrokerIdFromMaster(this.broker.getMetaConfig().getBrokerId());
}
private ZkClient getZkClient() {
return this.broker.getBrokerZooKeeper().getZkClient();
}
private MetaZookeeper getMetaZookeeper() {
return this.broker.getBrokerZooKeeper().getMetaZookeeper();
}
private final class MasterBrokerIdListener implements IZkDataListener {
@Override
public synchronized void handleDataChange(final String dataPath, final Object data) throws Exception {
int zkSyncTimeMs;
try {
zkSyncTimeMs = SlaveZooKeeper.this.broker.getMetaConfig().getZkConfig().zkSyncTimeMs;
}
catch (final Exception e) {
zkSyncTimeMs = 5000;
// ignore
}
// �ȴ�zk����ͬ���������������
Thread.sleep(zkSyncTimeMs);
if (dataPath.equals(SlaveZooKeeper.this.masterBrokerIdsPath)) {
// ����slave��������master������ʱ
log.info("data changed in zk,path=" + dataPath);
SlaveZooKeeper.this.subscribeHandler.start();
}
else if (dataPath.equals(SlaveZooKeeper.this.masterConfigFileChecksumPath)) {
log.info("Restart slave...");
SlaveZooKeeper.this.subscribeHandler.restart();
log.info("Restart slave successfully.");
}
else {
log.warn("Unknown data path:" + dataPath);
}
}
@Override
public void handleDataDeleted(final String dataPath) throws Exception {
log.info("data deleted in zk,path=" + dataPath);
if (dataPath.equals(SlaveZooKeeper.this.masterBrokerIdsPath)) {
// ����RemotingClientWrapper�Ļ���,close�Ĵ���Ҫ����connect�Ĵ������������رյ�����,
// Ҫ�����ڶ���master��Ϣǰ������һ��,����Ҫ������ر�һ��
// ���������Ӻر��и��ؾ��⸺��
SlaveZooKeeper.this.subscribeHandler.closeConnectIfNeed();
}
}
}
}