001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.zookeeper; 019 020import org.apache.hadoop.hbase.Abortable; 021import org.apache.yetus.audience.InterfaceAudience; 022import org.apache.zookeeper.KeeperException; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 027import org.apache.hadoop.hbase.shaded.protobuf.generated.ZooKeeperProtos; 028 029/** 030 * Tracker on cluster settings up in zookeeper. This is not related to 031 * {@link org.apache.hadoop.hbase.ClusterMetrics}. That class is a data structure that holds 032 * snapshot of current view on cluster. This class is about tracking cluster attributes up in 033 * zookeeper. 034 */ 035@InterfaceAudience.Private 036public class ClusterStatusTracker extends ZKNodeTracker { 037 private static final Logger LOG = LoggerFactory.getLogger(ClusterStatusTracker.class); 038 039 /** 040 * Creates a cluster status tracker. 041 * <p> 042 * After construction, use {@link #start} to kick off tracking. 043 * @param watcher reference to the {@link ZKWatcher} which also contains configuration and 044 * constants 045 * @param abortable used to abort if a fatal error occurs 046 */ 047 public ClusterStatusTracker(ZKWatcher watcher, Abortable abortable) { 048 super(watcher, watcher.getZNodePaths().clusterStateZNode, abortable); 049 } 050 051 /** 052 * Checks if cluster is up. 053 * @return true if the cluster up ('shutdown' is its name up in zk) znode exists with data, false 054 * if not 055 */ 056 public boolean isClusterUp() { 057 return super.getData(false) != null; 058 } 059 060 /** 061 * Sets the cluster as up. 062 * @throws KeeperException unexpected zk exception 063 */ 064 public void setClusterUp() throws KeeperException { 065 byte[] upData = toByteArray(); 066 try { 067 ZKUtil.createAndWatch(watcher, watcher.getZNodePaths().clusterStateZNode, upData); 068 } catch (KeeperException.NodeExistsException nee) { 069 ZKUtil.setData(watcher, watcher.getZNodePaths().clusterStateZNode, upData); 070 } 071 } 072 073 /** 074 * Sets the cluster as down by deleting the znode. 075 * @throws KeeperException unexpected zk exception 076 */ 077 public void setClusterDown() throws KeeperException { 078 try { 079 ZKUtil.deleteNode(watcher, watcher.getZNodePaths().clusterStateZNode); 080 } catch (KeeperException.NoNodeException nne) { 081 LOG.warn("Attempted to set cluster as down but already down, cluster " + "state node (" 082 + watcher.getZNodePaths().clusterStateZNode + ") not found"); 083 } 084 } 085 086 /** Returns Content of the clusterup znode as a serialized pb with the pb magic as prefix. */ 087 static byte[] toByteArray() { 088 ZooKeeperProtos.ClusterUp.Builder builder = ZooKeeperProtos.ClusterUp.newBuilder(); 089 builder.setStartDate(new java.util.Date().toString()); 090 return ProtobufUtil.prependPBMagic(builder.build().toByteArray()); 091 } 092}