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  package org.apache.hadoop.hbase.zookeeper;
19  
20  import java.io.IOException;
21  import java.io.UnsupportedEncodingException;
22  import java.net.URLDecoder;
23  import java.net.URLEncoder;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.fs.FileSystem;
29  import org.apache.hadoop.fs.Path;
30  import org.apache.hadoop.hbase.HConstants;
31  import org.apache.hadoop.hbase.master.SplitLogManager;
32  import org.apache.hadoop.hbase.regionserver.SplitLogWorker;
33  
34  /**
35   * Common methods and attributes used by {@link SplitLogManager} and {@link SplitLogWorker}
36   * running distributed splitting of WAL logs.
37   */
38  @InterfaceAudience.Private
39  public class ZKSplitLog {
40    private static final Log LOG = LogFactory.getLog(ZKSplitLog.class);
41  
42    /**
43     * Gets the full path node name for the log file being split.
44     * This method will url encode the filename.
45     * @param zkw zk reference
46     * @param filename log file name (only the basename)
47     */
48    public static String getEncodedNodeName(ZooKeeperWatcher zkw, String filename) {
49      return ZKUtil.joinZNode(zkw.splitLogZNode, encode(filename));
50    }
51  
52    public static String getFileName(String node) {
53      String basename = node.substring(node.lastIndexOf('/') + 1);
54      return decode(basename);
55    }
56  
57    static String encode(String s) {
58      try {
59        return URLEncoder.encode(s, "UTF-8");
60      } catch (UnsupportedEncodingException e) {
61        throw new RuntimeException("URLENCODER doesn't support UTF-8");
62      }
63    }
64  
65    static String decode(String s) {
66      try {
67        return URLDecoder.decode(s, "UTF-8");
68      } catch (UnsupportedEncodingException e) {
69        throw new RuntimeException("URLDecoder doesn't support UTF-8");
70      }
71    }
72  
73    public static String getRescanNode(ZooKeeperWatcher zkw) {
74      return ZKUtil.joinZNode(zkw.splitLogZNode, "RESCAN");
75    }
76  
77    /**
78     * @param name the last part in path
79     * @return whether the node name represents a rescan node
80     */
81    public static boolean isRescanNode(String name) {
82      return name.startsWith("RESCAN");
83    }
84  
85    /**
86     * @param zkw
87     * @param path the absolute path, starts with '/'
88     * @return whether the path represents a rescan node
89     */
90    public static boolean isRescanNode(ZooKeeperWatcher zkw, String path) {
91      String prefix = getRescanNode(zkw);
92      if (path.length() <= prefix.length()) {
93        return false;
94      }
95      for (int i = 0; i < prefix.length(); i++) {
96        if (prefix.charAt(i) != path.charAt(i)) {
97          return false;
98        }
99      }
100     return true;
101   }
102 
103   public static boolean isTaskPath(ZooKeeperWatcher zkw, String path) {
104     String dirname = path.substring(0, path.lastIndexOf('/'));
105     return dirname.equals(zkw.splitLogZNode);
106   }
107 
108   public static Path getSplitLogDir(Path rootdir, String tmpname) {
109     return new Path(new Path(rootdir, HConstants.SPLIT_LOGDIR_NAME), tmpname);
110   }
111 
112 
113   public static String getSplitLogDirTmpComponent(final String worker, String file) {
114     return worker + "_" + ZKSplitLog.encode(file);
115   }
116 
117   public static void markCorrupted(Path rootdir, String logFileName,
118       FileSystem fs) {
119     Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
120     try {
121       fs.createNewFile(file);
122     } catch (IOException e) {
123       LOG.warn("Could not flag a log file as corrupted. Failed to create " +
124           file, e);
125     }
126   }
127 
128   public static boolean isCorrupted(Path rootdir, String logFileName,
129       FileSystem fs) throws IOException {
130     Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
131     boolean isCorrupt;
132     isCorrupt = fs.exists(file);
133     return isCorrupt;
134   }
135 
136 }