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.hdfs.tools.offlineImageViewer; 019 020import org.apache.hadoop.fs.Path; 021import org.apache.hadoop.fs.permission.PermissionStatus; 022import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INode; 023import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INodeDirectory; 024import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INodeFile; 025import org.apache.hadoop.hdfs.server.namenode.FsImageProto.INodeSection.INodeSymlink; 026 027import java.io.IOException; 028import java.io.PrintStream; 029import java.text.SimpleDateFormat; 030import java.util.Date; 031 032/** 033 * A PBImageDelimitedTextWriter generates a text representation of the PB fsimage, 034 * with each element separated by a delimiter string. All of the elements 035 * common to both inodes and inodes-under-construction are included. When 036 * processing an fsimage with a layout version that did not include an 037 * element, such as AccessTime, the output file will include a column 038 * for the value, but no value will be included. 039 * 040 * Individual block information for each file is not currently included. 041 * 042 * The default delimiter is tab, as this is an unlikely value to be included in 043 * an inode path or other text metadata. The delimiter value can be via the 044 * constructor. 045 */ 046public class PBImageDelimitedTextWriter extends PBImageTextWriter { 047 static final String DEFAULT_DELIMITER = "\t"; 048 private static final String DATE_FORMAT="yyyy-MM-dd HH:mm"; 049 private final SimpleDateFormat dateFormatter = 050 new SimpleDateFormat(DATE_FORMAT); 051 052 private final String delimiter; 053 054 PBImageDelimitedTextWriter(PrintStream out, String delimiter, String tempPath) 055 throws IOException { 056 super(out, tempPath); 057 this.delimiter = delimiter; 058 } 059 060 private String formatDate(long date) { 061 return dateFormatter.format(new Date(date)); 062 } 063 064 private void append(StringBuffer buffer, int field) { 065 buffer.append(delimiter); 066 buffer.append(field); 067 } 068 069 private void append(StringBuffer buffer, long field) { 070 buffer.append(delimiter); 071 buffer.append(field); 072 } 073 074 private void append(StringBuffer buffer, String field) { 075 buffer.append(delimiter); 076 buffer.append(field); 077 } 078 079 @Override 080 public String getEntry(String parent, INode inode) { 081 StringBuffer buffer = new StringBuffer(); 082 String inodeName = inode.getName().toStringUtf8(); 083 Path path = new Path(parent.isEmpty() ? "/" : parent, 084 inodeName.isEmpty() ? "/" : inodeName); 085 buffer.append(path.toString()); 086 PermissionStatus p = null; 087 088 switch (inode.getType()) { 089 case FILE: 090 INodeFile file = inode.getFile(); 091 p = getPermission(file.getPermission()); 092 append(buffer, file.getReplication()); 093 append(buffer, formatDate(file.getModificationTime())); 094 append(buffer, formatDate(file.getAccessTime())); 095 append(buffer, file.getPreferredBlockSize()); 096 append(buffer, file.getBlocksCount()); 097 append(buffer, FSImageLoader.getFileSize(file)); 098 append(buffer, 0); // NS_QUOTA 099 append(buffer, 0); // DS_QUOTA 100 break; 101 case DIRECTORY: 102 INodeDirectory dir = inode.getDirectory(); 103 p = getPermission(dir.getPermission()); 104 append(buffer, 0); // Replication 105 append(buffer, formatDate(dir.getModificationTime())); 106 append(buffer, formatDate(0)); // Access time. 107 append(buffer, 0); // Block size. 108 append(buffer, 0); // Num blocks. 109 append(buffer, 0); // Num bytes. 110 append(buffer, dir.getNsQuota()); 111 append(buffer, dir.getDsQuota()); 112 break; 113 case SYMLINK: 114 INodeSymlink s = inode.getSymlink(); 115 p = getPermission(s.getPermission()); 116 append(buffer, 0); // Replication 117 append(buffer, formatDate(s.getModificationTime())); 118 append(buffer, formatDate(s.getAccessTime())); 119 append(buffer, 0); // Block size. 120 append(buffer, 0); // Num blocks. 121 append(buffer, 0); // Num bytes. 122 append(buffer, 0); // NS_QUOTA 123 append(buffer, 0); // DS_QUOTA 124 break; 125 default: 126 break; 127 } 128 assert p != null; 129 append(buffer, p.getPermission().toString()); 130 append(buffer, p.getUserName()); 131 append(buffer, p.getGroupName()); 132 return buffer.toString(); 133 } 134}