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