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.backup.example;
019
020import java.io.IOException;
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.conf.Configured;
023import org.apache.hadoop.hbase.client.Connection;
024import org.apache.hadoop.hbase.util.Bytes;
025import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
026import org.apache.hadoop.hbase.zookeeper.ZNodePaths;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.apache.zookeeper.KeeperException;
029
030/**
031 * Example class for how to use the table archiving coordinated via zookeeper
032 */
033@InterfaceAudience.Private
034public class ZKTableArchiveClient extends Configured {
035
036  /** Configuration key for the archive node. */
037  private static final String ZOOKEEPER_ZNODE_HFILE_ARCHIVE_KEY = "zookeeper.znode.hfile.archive";
038  private Connection connection;
039
040  public ZKTableArchiveClient(Configuration conf, Connection connection) {
041    super(conf);
042    this.connection = connection;
043  }
044
045  /**
046   * Turn on backups for all HFiles for the given table.
047   * <p>
048   * All deleted hfiles are moved to the archive directory under the table directory, rather than
049   * being deleted.
050   * <p>
051   * If backups are already enabled for this table, does nothing.
052   * <p>
053   * If the table does not exist, the archiving the table's hfiles is still enabled as a future
054   * table with that name may be created shortly.
055   * @param table name of the table to start backing up
056   * @throws IOException     if an unexpected exception occurs
057   * @throws KeeperException if zookeeper can't be reached
058   */
059  public void enableHFileBackupAsync(final byte[] table) throws IOException, KeeperException {
060    createHFileArchiveManager().enableHFileBackup(table).stop();
061  }
062
063  /**
064   * Disable hfile backups for the given table.
065   * <p>
066   * Previously backed up files are still retained (if present).
067   * <p>
068   * Asynchronous operation - some extra HFiles may be retained, in the archive directory after
069   * disable is called, dependent on the latency in zookeeper to the servers.
070   * @param table name of the table stop backing up
071   * @throws IOException     if an unexpected exception occurs
072   * @throws KeeperException if zookeeper can't be reached
073   */
074  public void disableHFileBackup(String table) throws IOException, KeeperException {
075    disableHFileBackup(Bytes.toBytes(table));
076  }
077
078  /**
079   * Disable hfile backups for the given table.
080   * <p>
081   * Previously backed up files are still retained (if present).
082   * <p>
083   * Asynchronous operation - some extra HFiles may be retained, in the archive directory after
084   * disable is called, dependent on the latency in zookeeper to the servers.
085   * @param table name of the table stop backing up
086   * @throws IOException     if an unexpected exception occurs
087   * @throws KeeperException if zookeeper can't be reached
088   */
089  public void disableHFileBackup(final byte[] table) throws IOException, KeeperException {
090    createHFileArchiveManager().disableHFileBackup(table).stop();
091  }
092
093  /**
094   * Disable hfile backups for all tables.
095   * <p>
096   * Previously backed up files are still retained (if present).
097   * <p>
098   * Asynchronous operation - some extra HFiles may be retained, in the archive directory after
099   * disable is called, dependent on the latency in zookeeper to the servers.
100   * @throws IOException     if an unexpected exception occurs
101   * @throws KeeperException if zookeeper can't be reached
102   */
103  public void disableHFileBackup() throws IOException, KeeperException {
104    createHFileArchiveManager().disableHFileBackup().stop();
105  }
106
107  /**
108   * Determine if archiving is enabled (but not necessarily fully propagated) for a table
109   * @param table name of the table to check
110   * @return <tt>true</tt> if it is, <tt>false</tt> otherwise
111   * @throws IOException     if a connection to ZooKeeper cannot be established
112   * @throws KeeperException if a ZooKeeper operation fails
113   */
114  public boolean getArchivingEnabled(byte[] table) throws IOException, KeeperException {
115    HFileArchiveManager manager = createHFileArchiveManager();
116    try {
117      return manager.isArchivingEnabled(table);
118    } finally {
119      manager.stop();
120    }
121  }
122
123  /**
124   * Determine if archiving is enabled (but not necessarily fully propagated) for a table
125   * @param table name of the table to check
126   * @return <tt>true</tt> if it is, <tt>false</tt> otherwise
127   * @throws IOException     if an unexpected network issue occurs
128   * @throws KeeperException if zookeeper can't be reached
129   */
130  public boolean getArchivingEnabled(String table) throws IOException, KeeperException {
131    return getArchivingEnabled(Bytes.toBytes(table));
132  }
133
134  /**
135   * @return A new {@link HFileArchiveManager} to manage which tables' hfiles should be archived
136   *         rather than deleted.
137   * @throws KeeperException if we can't reach zookeeper
138   * @throws IOException     if an unexpected network issue occurs
139   */
140  private synchronized HFileArchiveManager createHFileArchiveManager()
141    throws KeeperException, IOException {
142    return new HFileArchiveManager(this.connection, this.getConf());
143  }
144
145  /**
146   * @param conf      conf to read for the base archive node
147   * @param zooKeeper zookeeper to used for building the full path
148   * @return get the znode for long-term archival of a table for
149   */
150  public static String getArchiveZNode(Configuration conf, ZKWatcher zooKeeper) {
151    return ZNodePaths.joinZNode(zooKeeper.getZNodePaths().baseZNode, conf
152      .get(ZOOKEEPER_ZNODE_HFILE_ARCHIVE_KEY, TableHFileArchiveTracker.HFILE_ARCHIVE_ZNODE_PARENT));
153  }
154}