package org.archive.hadoop.io;
import java.text.SimpleDateFormat;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class HDFSTouch implements Tool {
protected Configuration conf;
public final static String TOOL_NAME = "hdfs-touch";
public final static String TMP_FILENAME = ".tmp_touch_latest";
public final static String FORMAT_STR = "yyyy-MM-dd HH:mm:ss";
public final static String HTTP_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
protected SimpleDateFormat formats[] = {
new SimpleDateFormat(FORMAT_STR),
new SimpleDateFormat(HTTP_FORMAT)
};
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(), new HDFSTouch(), args);
System.exit(res);
}
public void setConf(Configuration conf) {
this.conf = conf;
}
public Configuration getConf() {
return conf;
}
public static void print_usage() {
System.err.println("Usage: " + TOOL_NAME + " [ -d ] HDFS_URL [ TIMESTAMP ]");
System.err.println("Updates the mtime and atime of HDFS_URL to current time, or optional TIMESTAMP");
System.err.println("Accepts following TIMESTAMP formats:");
System.err.println(" " + FORMAT_STR);
System.err.println(" " + HTTP_FORMAT);
}
protected long parseFormats(String arg) {
long mtime = -1;
for (SimpleDateFormat format : formats) {
try {
mtime = format.parse(arg).getTime();
return mtime;
} catch (Exception exc) {
}
}
if (mtime == -1) {
System.err.println("Error parsing timestamp: " + arg + "\nExpected format: " + FORMAT_STR + " or " + HTTP_FORMAT);
mtime = System.currentTimeMillis();
}
return mtime;
}
public int run(String[] args) throws Exception {
if (args.length < 1) {
print_usage();
return 1;
}
String filePath = null;
boolean updateDir = false;
if (args.length == 1) {
filePath = args[0];
} else {
updateDir = (args[0].equals("-d"));
filePath = args[1];
}
Path path = new Path(filePath);
FileSystem fs = path.getFileSystem(conf);
if (fs.getFileStatus(path).isDir()) {
System.err.println("Can't touch directories in this version\n" +
"This is a directory: " + path);
return 1;
}
long mtime = System.currentTimeMillis();
if (args.length >= 3) {
mtime = parseFormats(args[2]);
}
long atime = mtime;
fs.setTimes(path, mtime, atime);
if (updateDir) {
Path tempFilePath = new Path(path.getParent(), TMP_FILENAME);
// Create empty output stream
FSDataOutputStream out = fs.create(tempFilePath);
out.close();
// Delete tmp file
fs.delete(tempFilePath, false);
}
return 0;
}
}