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 java.io.IOException;
021import java.io.UnsupportedEncodingException;
022import java.net.URLDecoder;
023import java.net.URLEncoder;
024import org.apache.hadoop.fs.FileSystem;
025import org.apache.hadoop.fs.Path;
026import org.apache.hadoop.hbase.HConstants;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031/**
032 * Common methods and attributes used by SplitLogManager and SplitLogWorker running distributed
033 * splitting of WAL logs.
034 * @deprecated since 2.4.0 and 3.0.0 replaced by procedure-based WAL splitting; see SplitWALManager.
035 */
036@Deprecated
037@InterfaceAudience.Private
038public final class ZKSplitLog {
039  private static final Logger LOG = LoggerFactory.getLogger(ZKSplitLog.class);
040
041  private ZKSplitLog() {
042  }
043
044  /**
045   * Gets the full path node name for the log file being split. This method will url encode the
046   * filename.
047   * @param zkw      zk reference
048   * @param filename log file name (only the basename)
049   */
050  public static String getEncodedNodeName(ZKWatcher zkw, String filename) {
051    return ZNodePaths.joinZNode(zkw.getZNodePaths().splitLogZNode, encode(filename));
052  }
053
054  public static String getFileName(String node) {
055    String basename = node.substring(node.lastIndexOf('/') + 1);
056    return decode(basename);
057  }
058
059  static String encode(String s) {
060    try {
061      return URLEncoder.encode(s, "UTF-8");
062    } catch (UnsupportedEncodingException e) {
063      throw new RuntimeException("URLENCODER doesn't support UTF-8");
064    }
065  }
066
067  static String decode(String s) {
068    try {
069      return URLDecoder.decode(s, "UTF-8");
070    } catch (UnsupportedEncodingException e) {
071      throw new RuntimeException("URLDecoder doesn't support UTF-8");
072    }
073  }
074
075  public static String getRescanNode(ZKWatcher zkw) {
076    return ZNodePaths.joinZNode(zkw.getZNodePaths().splitLogZNode, "RESCAN");
077  }
078
079  /**
080   * @param name the last part in path
081   * @return whether the node name represents a rescan node
082   */
083  public static boolean isRescanNode(String name) {
084    return name.startsWith("RESCAN");
085  }
086
087  /**
088   * Checks if the given path represents a rescan node.
089   * @param zkw  reference to the {@link ZKWatcher} which also contains configuration and constants
090   * @param path the absolute path, starts with '/'
091   * @return whether the path represents a rescan node
092   */
093  public static boolean isRescanNode(ZKWatcher zkw, String path) {
094    String prefix = getRescanNode(zkw);
095    if (path.length() <= prefix.length()) {
096      return false;
097    }
098    for (int i = 0; i < prefix.length(); i++) {
099      if (prefix.charAt(i) != path.charAt(i)) {
100        return false;
101      }
102    }
103    return true;
104  }
105
106  public static Path getSplitLogDir(Path rootdir, String tmpname) {
107    return new Path(new Path(rootdir, HConstants.SPLIT_LOGDIR_NAME), tmpname);
108  }
109
110  public static void markCorrupted(Path rootdir, String logFileName, FileSystem fs) {
111    Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
112    try {
113      fs.createNewFile(file);
114    } catch (IOException e) {
115      LOG.warn("Could not flag a log file as corrupted. Failed to create " + file, e);
116    }
117  }
118
119  public static boolean isCorrupted(Path rootdir, String logFileName, FileSystem fs)
120    throws IOException {
121    Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
122    boolean isCorrupt;
123    isCorrupt = fs.exists(file);
124    return isCorrupt;
125  }
126}