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 java.io.IOException;
22  
23  import org.apache.hadoop.hbase.Abortable;
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.exceptions.DeserializationException;
26  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
27  import org.apache.hadoop.hbase.protobuf.generated.SnapshotCleanupProtos;
28  import org.apache.hadoop.hbase.util.Bytes;
29  import org.apache.zookeeper.KeeperException;
30  
31  
32  /**
33   * Tracks status of snapshot auto cleanup based on TTL
34   */
35  @InterfaceAudience.Private
36  public class SnapshotCleanupTracker extends ZooKeeperNodeTracker {
37  
38    /**
39     * Constructs a new ZK node tracker.
40     *
41     * <p>After construction, use {@link #start} to kick off tracking.
42     *
43     * @param watcher reference to the {@link ZooKeeperWatcher} which also contains configuration
44     *   and constants
45     * @param abortable used to abort if a fatal error occurs
46     */
47    public SnapshotCleanupTracker(ZooKeeperWatcher watcher, Abortable abortable) {
48      super(watcher, watcher.snapshotCleanupZNode, abortable);
49    }
50  
51    /**
52     * Returns the current state of the snapshot auto cleanup based on TTL
53     *
54     * @return <code>true</code> if the snapshot auto cleanup is enabled,
55     *   <code>false</code> otherwise.
56     */
57    public boolean isSnapshotCleanupEnabled() {
58      byte[] snapshotCleanupZNodeData = super.getData(false);
59      try {
60        // if data in ZK is null, use default of on.
61        return snapshotCleanupZNodeData == null ||
62            parseFrom(snapshotCleanupZNodeData).getSnapshotCleanupEnabled();
63      } catch (DeserializationException dex) {
64        LOG.error("ZK state for Snapshot Cleanup could not be parsed " +
65            Bytes.toStringBinary(snapshotCleanupZNodeData), dex);
66        // return false to be safe.
67        return false;
68      }
69    }
70  
71    /**
72     * Set snapshot auto clean on/off
73     *
74     * @param snapshotCleanupEnabled true if the snapshot auto cleanup should be on,
75     *   false otherwise
76     * @throws KeeperException if ZooKeeper operation fails
77     */
78    public void setSnapshotCleanupEnabled(final boolean snapshotCleanupEnabled)
79        throws KeeperException {
80      byte [] snapshotCleanupZNodeData = toByteArray(snapshotCleanupEnabled);
81      try {
82        ZKUtil.setData(watcher, watcher.snapshotCleanupZNode,
83            snapshotCleanupZNodeData);
84      } catch(KeeperException.NoNodeException nne) {
85        ZKUtil.createAndWatch(watcher, watcher.snapshotCleanupZNode,
86            snapshotCleanupZNodeData);
87      }
88      super.nodeDataChanged(watcher.snapshotCleanupZNode);
89    }
90  
91    private byte[] toByteArray(final boolean isSnapshotCleanupEnabled) {
92      SnapshotCleanupProtos.SnapshotCleanupState.Builder builder =
93          SnapshotCleanupProtos.SnapshotCleanupState.newBuilder();
94      builder.setSnapshotCleanupEnabled(isSnapshotCleanupEnabled);
95      return ProtobufUtil.prependPBMagic(builder.build().toByteArray());
96    }
97  
98    private SnapshotCleanupProtos.SnapshotCleanupState parseFrom(final byte[] pbBytes)
99        throws DeserializationException {
100     ProtobufUtil.expectPBMagicPrefix(pbBytes);
101     SnapshotCleanupProtos.SnapshotCleanupState.Builder builder =
102         SnapshotCleanupProtos.SnapshotCleanupState.newBuilder();
103     try {
104       int magicLen = ProtobufUtil.lengthOfPBMagic();
105       ProtobufUtil.mergeFrom(builder, pbBytes, magicLen, pbBytes.length - magicLen);
106     } catch (IOException e) {
107       throw new DeserializationException(e);
108     }
109     return builder.build();
110   }
111 
112 }