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 */ 018 019package org.apache.hadoop.fs; 020 021import java.io.*; 022import java.net.URI; 023import java.net.URISyntaxException; 024import java.util.EnumSet; 025import org.apache.hadoop.classification.InterfaceAudience; 026import org.apache.hadoop.classification.InterfaceStability; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.fs.permission.FsPermission; 029import org.apache.hadoop.fs.ContentSummary; 030import org.apache.hadoop.fs.Options.ChecksumOpt; 031import org.apache.hadoop.util.Progressable; 032 033/**************************************************************** 034 * A <code>FilterFileSystem</code> contains 035 * some other file system, which it uses as 036 * its basic file system, possibly transforming 037 * the data along the way or providing additional 038 * functionality. The class <code>FilterFileSystem</code> 039 * itself simply overrides all methods of 040 * <code>FileSystem</code> with versions that 041 * pass all requests to the contained file 042 * system. Subclasses of <code>FilterFileSystem</code> 043 * may further override some of these methods 044 * and may also provide additional methods 045 * and fields. 046 * 047 *****************************************************************/ 048@InterfaceAudience.Public 049@InterfaceStability.Stable 050public class FilterFileSystem extends FileSystem { 051 052 protected FileSystem fs; 053 protected String swapScheme; 054 055 /* 056 * so that extending classes can define it 057 */ 058 public FilterFileSystem() { 059 } 060 061 public FilterFileSystem(FileSystem fs) { 062 this.fs = fs; 063 this.statistics = fs.statistics; 064 } 065 066 /** 067 * Get the raw file system 068 * @return FileSystem being filtered 069 */ 070 public FileSystem getRawFileSystem() { 071 return fs; 072 } 073 074 /** Called after a new FileSystem instance is constructed. 075 * @param name a uri whose authority section names the host, port, etc. 076 * for this FileSystem 077 * @param conf the configuration 078 */ 079 public void initialize(URI name, Configuration conf) throws IOException { 080 super.initialize(name, conf); 081 // this is less than ideal, but existing filesystems sometimes neglect 082 // to initialize the embedded filesystem 083 if (fs.getConf() == null) { 084 fs.initialize(name, conf); 085 } 086 String scheme = name.getScheme(); 087 if (!scheme.equals(fs.getUri().getScheme())) { 088 swapScheme = scheme; 089 } 090 } 091 092 /** Returns a URI whose scheme and authority identify this FileSystem.*/ 093 public URI getUri() { 094 return fs.getUri(); 095 } 096 097 /** 098 * Returns a qualified URI whose scheme and authority identify this 099 * FileSystem. 100 */ 101 @Override 102 protected URI getCanonicalUri() { 103 return fs.getCanonicalUri(); 104 } 105 106 /** Make sure that a path specifies a FileSystem. */ 107 public Path makeQualified(Path path) { 108 Path fqPath = fs.makeQualified(path); 109 // swap in our scheme if the filtered fs is using a different scheme 110 if (swapScheme != null) { 111 try { 112 // NOTE: should deal with authority, but too much other stuff is broken 113 fqPath = new Path( 114 new URI(swapScheme, fqPath.toUri().getSchemeSpecificPart(), null) 115 ); 116 } catch (URISyntaxException e) { 117 throw new IllegalArgumentException(e); 118 } 119 } 120 return fqPath; 121 } 122 123 /////////////////////////////////////////////////////////////// 124 // FileSystem 125 /////////////////////////////////////////////////////////////// 126 127 /** Check that a Path belongs to this FileSystem. */ 128 protected void checkPath(Path path) { 129 fs.checkPath(path); 130 } 131 132 public BlockLocation[] getFileBlockLocations(FileStatus file, long start, 133 long len) throws IOException { 134 return fs.getFileBlockLocations(file, start, len); 135 } 136 137 @Override 138 public Path resolvePath(final Path p) throws IOException { 139 return fs.resolvePath(p); 140 } 141 /** 142 * Opens an FSDataInputStream at the indicated Path. 143 * @param f the file name to open 144 * @param bufferSize the size of the buffer to be used. 145 */ 146 public FSDataInputStream open(Path f, int bufferSize) throws IOException { 147 return fs.open(f, bufferSize); 148 } 149 150 /** {@inheritDoc} */ 151 public FSDataOutputStream append(Path f, int bufferSize, 152 Progressable progress) throws IOException { 153 return fs.append(f, bufferSize, progress); 154 } 155 156 /** {@inheritDoc} */ 157 @Override 158 public FSDataOutputStream create(Path f, FsPermission permission, 159 boolean overwrite, int bufferSize, short replication, long blockSize, 160 Progressable progress) throws IOException { 161 return fs.create(f, permission, 162 overwrite, bufferSize, replication, blockSize, progress); 163 } 164 165 /** 166 * Set replication for an existing file. 167 * 168 * @param src file name 169 * @param replication new replication 170 * @throws IOException 171 * @return true if successful; 172 * false if file does not exist or is a directory 173 */ 174 public boolean setReplication(Path src, short replication) throws IOException { 175 return fs.setReplication(src, replication); 176 } 177 178 /** 179 * Renames Path src to Path dst. Can take place on local fs 180 * or remote DFS. 181 */ 182 public boolean rename(Path src, Path dst) throws IOException { 183 return fs.rename(src, dst); 184 } 185 186 /** Delete a file */ 187 public boolean delete(Path f, boolean recursive) throws IOException { 188 return fs.delete(f, recursive); 189 } 190 191 /** List files in a directory. */ 192 public FileStatus[] listStatus(Path f) throws IOException { 193 return fs.listStatus(f); 194 } 195 196 /** 197 * {@inheritDoc} 198 */ 199 @Override 200 public RemoteIterator<Path> listCorruptFileBlocks(Path path) 201 throws IOException { 202 return fs.listCorruptFileBlocks(path); 203 } 204 205 /** List files and its block locations in a directory. */ 206 public RemoteIterator<LocatedFileStatus> listLocatedStatus(Path f) 207 throws IOException { 208 return fs.listLocatedStatus(f); 209 } 210 211 public Path getHomeDirectory() { 212 return fs.getHomeDirectory(); 213 } 214 215 216 /** 217 * Set the current working directory for the given file system. All relative 218 * paths will be resolved relative to it. 219 * 220 * @param newDir 221 */ 222 public void setWorkingDirectory(Path newDir) { 223 fs.setWorkingDirectory(newDir); 224 } 225 226 /** 227 * Get the current working directory for the given file system 228 * 229 * @return the directory pathname 230 */ 231 public Path getWorkingDirectory() { 232 return fs.getWorkingDirectory(); 233 } 234 235 protected Path getInitialWorkingDirectory() { 236 return fs.getInitialWorkingDirectory(); 237 } 238 239 /** {@inheritDoc} */ 240 @Override 241 public FsStatus getStatus(Path p) throws IOException { 242 return fs.getStatus(p); 243 } 244 245 /** {@inheritDoc} */ 246 @Override 247 public boolean mkdirs(Path f, FsPermission permission) throws IOException { 248 return fs.mkdirs(f, permission); 249 } 250 251 252 /** 253 * The src file is on the local disk. Add it to FS at 254 * the given dst name. 255 * delSrc indicates if the source should be removed 256 */ 257 public void copyFromLocalFile(boolean delSrc, Path src, Path dst) 258 throws IOException { 259 fs.copyFromLocalFile(delSrc, src, dst); 260 } 261 262 /** 263 * The src files are on the local disk. Add it to FS at 264 * the given dst name. 265 * delSrc indicates if the source should be removed 266 */ 267 public void copyFromLocalFile(boolean delSrc, boolean overwrite, 268 Path[] srcs, Path dst) 269 throws IOException { 270 fs.copyFromLocalFile(delSrc, overwrite, srcs, dst); 271 } 272 273 /** 274 * The src file is on the local disk. Add it to FS at 275 * the given dst name. 276 * delSrc indicates if the source should be removed 277 */ 278 public void copyFromLocalFile(boolean delSrc, boolean overwrite, 279 Path src, Path dst) 280 throws IOException { 281 fs.copyFromLocalFile(delSrc, overwrite, src, dst); 282 } 283 284 /** 285 * The src file is under FS, and the dst is on the local disk. 286 * Copy it from FS control to the local dst name. 287 * delSrc indicates if the src will be removed or not. 288 */ 289 public void copyToLocalFile(boolean delSrc, Path src, Path dst) 290 throws IOException { 291 fs.copyToLocalFile(delSrc, src, dst); 292 } 293 294 /** 295 * Returns a local File that the user can write output to. The caller 296 * provides both the eventual FS target name and the local working 297 * file. If the FS is local, we write directly into the target. If 298 * the FS is remote, we write into the tmp local area. 299 */ 300 public Path startLocalOutput(Path fsOutputFile, Path tmpLocalFile) 301 throws IOException { 302 return fs.startLocalOutput(fsOutputFile, tmpLocalFile); 303 } 304 305 /** 306 * Called when we're all done writing to the target. A local FS will 307 * do nothing, because we've written to exactly the right place. A remote 308 * FS will copy the contents of tmpLocalFile to the correct target at 309 * fsOutputFile. 310 */ 311 public void completeLocalOutput(Path fsOutputFile, Path tmpLocalFile) 312 throws IOException { 313 fs.completeLocalOutput(fsOutputFile, tmpLocalFile); 314 } 315 316 /** Return the total size of all files in the filesystem.*/ 317 public long getUsed() throws IOException{ 318 return fs.getUsed(); 319 } 320 321 @Override 322 public long getDefaultBlockSize() { 323 return fs.getDefaultBlockSize(); 324 } 325 326 @Override 327 public short getDefaultReplication() { 328 return fs.getDefaultReplication(); 329 } 330 331 @Override 332 public FsServerDefaults getServerDefaults() throws IOException { 333 return fs.getServerDefaults(); 334 } 335 336 // path variants delegate to underlying filesystem 337 @Override 338 public ContentSummary getContentSummary(Path f) throws IOException { 339 return fs.getContentSummary(f); 340 } 341 342 @Override 343 public long getDefaultBlockSize(Path f) { 344 return fs.getDefaultBlockSize(f); 345 } 346 347 @Override 348 public short getDefaultReplication(Path f) { 349 return fs.getDefaultReplication(f); 350 } 351 352 @Override 353 public FsServerDefaults getServerDefaults(Path f) throws IOException { 354 return fs.getServerDefaults(f); 355 } 356 357 /** 358 * Get file status. 359 */ 360 public FileStatus getFileStatus(Path f) throws IOException { 361 return fs.getFileStatus(f); 362 } 363 364 /** {@inheritDoc} */ 365 public FileChecksum getFileChecksum(Path f) throws IOException { 366 return fs.getFileChecksum(f); 367 } 368 369 /** {@inheritDoc} */ 370 public void setVerifyChecksum(boolean verifyChecksum) { 371 fs.setVerifyChecksum(verifyChecksum); 372 } 373 374 @Override 375 public void setWriteChecksum(boolean writeChecksum) { 376 fs.setWriteChecksum(writeChecksum); 377 } 378 379 @Override 380 public Configuration getConf() { 381 return fs.getConf(); 382 } 383 384 @Override 385 public void close() throws IOException { 386 super.close(); 387 fs.close(); 388 } 389 390 /** {@inheritDoc} */ 391 @Override 392 public void setOwner(Path p, String username, String groupname 393 ) throws IOException { 394 fs.setOwner(p, username, groupname); 395 } 396 397 /** {@inheritDoc} */ 398 @Override 399 public void setTimes(Path p, long mtime, long atime 400 ) throws IOException { 401 fs.setTimes(p, mtime, atime); 402 } 403 404 /** {@inheritDoc} */ 405 @Override 406 public void setPermission(Path p, FsPermission permission 407 ) throws IOException { 408 fs.setPermission(p, permission); 409 } 410 411 @Override 412 protected FSDataOutputStream primitiveCreate(Path f, 413 FsPermission absolutePermission, EnumSet<CreateFlag> flag, 414 int bufferSize, short replication, long blockSize, 415 Progressable progress, ChecksumOpt checksumOpt) 416 throws IOException { 417 return fs.primitiveCreate(f, absolutePermission, flag, 418 bufferSize, replication, blockSize, progress, checksumOpt); 419 } 420 421 @Override 422 @SuppressWarnings("deprecation") 423 protected boolean primitiveMkdir(Path f, FsPermission abdolutePermission) 424 throws IOException { 425 return fs.primitiveMkdir(f, abdolutePermission); 426 } 427 428 @Override // FileSystem 429 public FileSystem[] getChildFileSystems() { 430 return new FileSystem[]{fs}; 431 } 432}