View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.zookeeper;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.hadoop.hbase.Abortable;
24  import org.apache.hadoop.hbase.exceptions.DeserializationException;
25  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
26  import org.apache.hadoop.hbase.protobuf.generated.RegionNormalizerProtos;
27  import org.apache.hadoop.hbase.util.Bytes;
28  import org.apache.zookeeper.KeeperException;
29  
30  import java.io.IOException;
31  
32  /**
33   * Tracks region normalizer state up in ZK
34   */
35  public class RegionNormalizerTracker extends ZooKeeperNodeTracker {
36    private static final Log LOG = LogFactory.getLog(RegionNormalizerTracker.class);
37  
38    public RegionNormalizerTracker(ZooKeeperWatcher watcher,
39                               Abortable abortable) {
40      super(watcher, watcher.getRegionNormalizerZNode(), abortable);
41    }
42  
43    /**
44     * Return true if region normalizer is on, false otherwise
45     */
46    public boolean isNormalizerOn() {
47      byte [] upData = super.getData(false);
48      try {
49        // if data in ZK is null, use default of on.
50        return upData == null || parseFrom(upData).getNormalizerOn();
51      } catch (DeserializationException dex) {
52        LOG.error("ZK state for RegionNormalizer could not be parsed "
53          + Bytes.toStringBinary(upData));
54        // return false to be safe.
55        return false;
56      }
57    }
58  
59    /**
60     * Set region normalizer on/off
61     * @param normalizerOn whether normalizer should be on or off
62     * @throws KeeperException
63     */
64    public void setNormalizerOn(boolean normalizerOn) throws KeeperException {
65      byte [] upData = toByteArray(normalizerOn);
66      try {
67        ZKUtil.setData(watcher, watcher.getRegionNormalizerZNode(), upData);
68      } catch(KeeperException.NoNodeException nne) {
69        ZKUtil.createAndWatch(watcher, watcher.getRegionNormalizerZNode(), upData);
70      }
71      super.nodeDataChanged(watcher.getRegionNormalizerZNode());
72    }
73  
74    private byte [] toByteArray(boolean isNormalizerOn) {
75      RegionNormalizerProtos.RegionNormalizerState.Builder builder =
76        RegionNormalizerProtos.RegionNormalizerState.newBuilder();
77      builder.setNormalizerOn(isNormalizerOn);
78      return ProtobufUtil.prependPBMagic(builder.build().toByteArray());
79    }
80  
81    private RegionNormalizerProtos.RegionNormalizerState parseFrom(byte [] pbBytes)
82      throws DeserializationException {
83      ProtobufUtil.expectPBMagicPrefix(pbBytes);
84      RegionNormalizerProtos.RegionNormalizerState.Builder builder =
85        RegionNormalizerProtos.RegionNormalizerState.newBuilder();
86      try {
87        int magicLen = ProtobufUtil.lengthOfPBMagic();
88        ProtobufUtil.mergeFrom(builder, pbBytes, magicLen, pbBytes.length - magicLen);
89      } catch (IOException e) {
90        throw new DeserializationException(e);
91      }
92      return builder.build();
93    }
94  }