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 java.util.List; 026import java.util.Map; 027 028import org.apache.hadoop.classification.InterfaceAudience; 029import org.apache.hadoop.classification.InterfaceStability; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.fs.permission.AclEntry; 032import org.apache.hadoop.fs.permission.AclStatus; 033import org.apache.hadoop.fs.permission.FsAction; 034import org.apache.hadoop.fs.permission.FsPermission; 035import org.apache.hadoop.fs.Options.ChecksumOpt; 036import org.apache.hadoop.fs.Options.Rename; 037import org.apache.hadoop.security.AccessControlException; 038import org.apache.hadoop.util.Progressable; 039 040/**************************************************************** 041 * A <code>FilterFileSystem</code> contains 042 * some other file system, which it uses as 043 * its basic file system, possibly transforming 044 * the data along the way or providing additional 045 * functionality. The class <code>FilterFileSystem</code> 046 * itself simply overrides all methods of 047 * <code>FileSystem</code> with versions that 048 * pass all requests to the contained file 049 * system. Subclasses of <code>FilterFileSystem</code> 050 * may further override some of these methods 051 * and may also provide additional methods 052 * and fields. 053 * 054 *****************************************************************/ 055@InterfaceAudience.Public 056@InterfaceStability.Stable 057public class FilterFileSystem extends FileSystem { 058 059 protected FileSystem fs; 060 protected String swapScheme; 061 062 /* 063 * so that extending classes can define it 064 */ 065 public FilterFileSystem() { 066 } 067 068 public FilterFileSystem(FileSystem fs) { 069 this.fs = fs; 070 this.statistics = fs.statistics; 071 } 072 073 /** 074 * Get the raw file system 075 * @return FileSystem being filtered 076 */ 077 public FileSystem getRawFileSystem() { 078 return fs; 079 } 080 081 /** Called after a new FileSystem instance is constructed. 082 * @param name a uri whose authority section names the host, port, etc. 083 * for this FileSystem 084 * @param conf the configuration 085 */ 086 @Override 087 public void initialize(URI name, Configuration conf) throws IOException { 088 super.initialize(name, conf); 089 // this is less than ideal, but existing filesystems sometimes neglect 090 // to initialize the embedded filesystem 091 if (fs.getConf() == null) { 092 fs.initialize(name, conf); 093 } 094 String scheme = name.getScheme(); 095 if (!scheme.equals(fs.getUri().getScheme())) { 096 swapScheme = scheme; 097 } 098 } 099 100 /** Returns a URI whose scheme and authority identify this FileSystem.*/ 101 @Override 102 public URI getUri() { 103 return fs.getUri(); 104 } 105 106 107 @Override 108 protected URI getCanonicalUri() { 109 return fs.getCanonicalUri(); 110 } 111 112 @Override 113 protected URI canonicalizeUri(URI uri) { 114 return fs.canonicalizeUri(uri); 115 } 116 117 /** Make sure that a path specifies a FileSystem. */ 118 @Override 119 public Path makeQualified(Path path) { 120 Path fqPath = fs.makeQualified(path); 121 // swap in our scheme if the filtered fs is using a different scheme 122 if (swapScheme != null) { 123 try { 124 // NOTE: should deal with authority, but too much other stuff is broken 125 fqPath = new Path( 126 new URI(swapScheme, fqPath.toUri().getSchemeSpecificPart(), null) 127 ); 128 } catch (URISyntaxException e) { 129 throw new IllegalArgumentException(e); 130 } 131 } 132 return fqPath; 133 } 134 135 /////////////////////////////////////////////////////////////// 136 // FileSystem 137 /////////////////////////////////////////////////////////////// 138 139 /** Check that a Path belongs to this FileSystem. */ 140 @Override 141 protected void checkPath(Path path) { 142 fs.checkPath(path); 143 } 144 145 @Override 146 public BlockLocation[] getFileBlockLocations(FileStatus file, long start, 147 long len) throws IOException { 148 return fs.getFileBlockLocations(file, start, len); 149 } 150 151 @Override 152 public Path resolvePath(final Path p) throws IOException { 153 return fs.resolvePath(p); 154 } 155 /** 156 * Opens an FSDataInputStream at the indicated Path. 157 * @param f the file name to open 158 * @param bufferSize the size of the buffer to be used. 159 */ 160 @Override 161 public FSDataInputStream open(Path f, int bufferSize) throws IOException { 162 return fs.open(f, bufferSize); 163 } 164 165 @Override 166 public FSDataOutputStream append(Path f, int bufferSize, 167 Progressable progress) throws IOException { 168 return fs.append(f, bufferSize, progress); 169 } 170 171 @Override 172 public void concat(Path f, Path[] psrcs) throws IOException { 173 fs.concat(f, psrcs); 174 } 175 176 @Override 177 public FSDataOutputStream create(Path f, FsPermission permission, 178 boolean overwrite, int bufferSize, short replication, long blockSize, 179 Progressable progress) throws IOException { 180 return fs.create(f, permission, 181 overwrite, bufferSize, replication, blockSize, progress); 182 } 183 184 @Override 185 public FSDataOutputStream create(Path f, 186 FsPermission permission, 187 EnumSet<CreateFlag> flags, 188 int bufferSize, 189 short replication, 190 long blockSize, 191 Progressable progress, 192 ChecksumOpt checksumOpt) throws IOException { 193 return fs.create(f, permission, 194 flags, bufferSize, replication, blockSize, progress, checksumOpt); 195 } 196 197 @Override 198 @Deprecated 199 public FSDataOutputStream createNonRecursive(Path f, FsPermission permission, 200 EnumSet<CreateFlag> flags, int bufferSize, short replication, long blockSize, 201 Progressable progress) throws IOException { 202 203 return fs.createNonRecursive(f, permission, flags, bufferSize, replication, blockSize, 204 progress); 205 } 206 207 /** 208 * Set replication for an existing file. 209 * 210 * @param src file name 211 * @param replication new replication 212 * @throws IOException 213 * @return true if successful; 214 * false if file does not exist or is a directory 215 */ 216 @Override 217 public boolean setReplication(Path src, short replication) throws IOException { 218 return fs.setReplication(src, replication); 219 } 220 221 /** 222 * Renames Path src to Path dst. Can take place on local fs 223 * or remote DFS. 224 */ 225 @Override 226 public boolean rename(Path src, Path dst) throws IOException { 227 return fs.rename(src, dst); 228 } 229 230 @Override 231 protected void rename(Path src, Path dst, Rename... options) 232 throws IOException { 233 fs.rename(src, dst, options); 234 } 235 236 @Override 237 public boolean truncate(Path f, final long newLength) throws IOException { 238 return fs.truncate(f, newLength); 239 } 240 241 /** Delete a file */ 242 @Override 243 public boolean delete(Path f, boolean recursive) throws IOException { 244 return fs.delete(f, recursive); 245 } 246 247 /** List files in a directory. */ 248 @Override 249 public FileStatus[] listStatus(Path f) throws IOException { 250 return fs.listStatus(f); 251 } 252 253 @Override 254 public RemoteIterator<Path> listCorruptFileBlocks(Path path) 255 throws IOException { 256 return fs.listCorruptFileBlocks(path); 257 } 258 259 /** List files and its block locations in a directory. */ 260 @Override 261 public RemoteIterator<LocatedFileStatus> listLocatedStatus(Path f) 262 throws IOException { 263 return fs.listLocatedStatus(f); 264 } 265 266 /** Return a remote iterator for listing in a directory */ 267 @Override 268 public RemoteIterator<FileStatus> listStatusIterator(Path f) 269 throws IOException { 270 return fs.listStatusIterator(f); 271 } 272 273 @Override 274 public Path getHomeDirectory() { 275 return fs.getHomeDirectory(); 276 } 277 278 279 /** 280 * Set the current working directory for the given file system. All relative 281 * paths will be resolved relative to it. 282 * 283 * @param newDir 284 */ 285 @Override 286 public void setWorkingDirectory(Path newDir) { 287 fs.setWorkingDirectory(newDir); 288 } 289 290 /** 291 * Get the current working directory for the given file system 292 * 293 * @return the directory pathname 294 */ 295 @Override 296 public Path getWorkingDirectory() { 297 return fs.getWorkingDirectory(); 298 } 299 300 @Override 301 protected Path getInitialWorkingDirectory() { 302 return fs.getInitialWorkingDirectory(); 303 } 304 305 @Override 306 public FsStatus getStatus(Path p) throws IOException { 307 return fs.getStatus(p); 308 } 309 310 @Override 311 public boolean mkdirs(Path f, FsPermission permission) throws IOException { 312 return fs.mkdirs(f, permission); 313 } 314 315 316 /** 317 * The src file is on the local disk. Add it to FS at 318 * the given dst name. 319 * delSrc indicates if the source should be removed 320 */ 321 @Override 322 public void copyFromLocalFile(boolean delSrc, Path src, Path dst) 323 throws IOException { 324 fs.copyFromLocalFile(delSrc, src, dst); 325 } 326 327 /** 328 * The src files are on the local disk. Add it to FS at 329 * the given dst name. 330 * delSrc indicates if the source should be removed 331 */ 332 @Override 333 public void copyFromLocalFile(boolean delSrc, boolean overwrite, 334 Path[] srcs, Path dst) 335 throws IOException { 336 fs.copyFromLocalFile(delSrc, overwrite, srcs, dst); 337 } 338 339 /** 340 * The src file is on the local disk. Add it to FS at 341 * the given dst name. 342 * delSrc indicates if the source should be removed 343 */ 344 @Override 345 public void copyFromLocalFile(boolean delSrc, boolean overwrite, 346 Path src, Path dst) 347 throws IOException { 348 fs.copyFromLocalFile(delSrc, overwrite, src, dst); 349 } 350 351 /** 352 * The src file is under FS, and the dst is on the local disk. 353 * Copy it from FS control to the local dst name. 354 * delSrc indicates if the src will be removed or not. 355 */ 356 @Override 357 public void copyToLocalFile(boolean delSrc, Path src, Path dst) 358 throws IOException { 359 fs.copyToLocalFile(delSrc, src, dst); 360 } 361 362 /** 363 * Returns a local File that the user can write output to. The caller 364 * provides both the eventual FS target name and the local working 365 * file. If the FS is local, we write directly into the target. If 366 * the FS is remote, we write into the tmp local area. 367 */ 368 @Override 369 public Path startLocalOutput(Path fsOutputFile, Path tmpLocalFile) 370 throws IOException { 371 return fs.startLocalOutput(fsOutputFile, tmpLocalFile); 372 } 373 374 /** 375 * Called when we're all done writing to the target. A local FS will 376 * do nothing, because we've written to exactly the right place. A remote 377 * FS will copy the contents of tmpLocalFile to the correct target at 378 * fsOutputFile. 379 */ 380 @Override 381 public void completeLocalOutput(Path fsOutputFile, Path tmpLocalFile) 382 throws IOException { 383 fs.completeLocalOutput(fsOutputFile, tmpLocalFile); 384 } 385 386 /** Return the total size of all files in the filesystem.*/ 387 @Override 388 public long getUsed() throws IOException{ 389 return fs.getUsed(); 390 } 391 392 @Override 393 public long getDefaultBlockSize() { 394 return fs.getDefaultBlockSize(); 395 } 396 397 @Override 398 public short getDefaultReplication() { 399 return fs.getDefaultReplication(); 400 } 401 402 @Override 403 public FsServerDefaults getServerDefaults() throws IOException { 404 return fs.getServerDefaults(); 405 } 406 407 // path variants delegate to underlying filesystem 408 @Override 409 public long getDefaultBlockSize(Path f) { 410 return fs.getDefaultBlockSize(f); 411 } 412 413 @Override 414 public short getDefaultReplication(Path f) { 415 return fs.getDefaultReplication(f); 416 } 417 418 @Override 419 public FsServerDefaults getServerDefaults(Path f) throws IOException { 420 return fs.getServerDefaults(f); 421 } 422 423 /** 424 * Get file status. 425 */ 426 @Override 427 public FileStatus getFileStatus(Path f) throws IOException { 428 return fs.getFileStatus(f); 429 } 430 431 @Override 432 public void access(Path path, FsAction mode) throws AccessControlException, 433 FileNotFoundException, IOException { 434 fs.access(path, mode); 435 } 436 437 public void createSymlink(final Path target, final Path link, 438 final boolean createParent) throws AccessControlException, 439 FileAlreadyExistsException, FileNotFoundException, 440 ParentNotDirectoryException, UnsupportedFileSystemException, 441 IOException { 442 fs.createSymlink(target, link, createParent); 443 } 444 445 public FileStatus getFileLinkStatus(final Path f) 446 throws AccessControlException, FileNotFoundException, 447 UnsupportedFileSystemException, IOException { 448 return fs.getFileLinkStatus(f); 449 } 450 451 public boolean supportsSymlinks() { 452 return fs.supportsSymlinks(); 453 } 454 455 public Path getLinkTarget(Path f) throws IOException { 456 return fs.getLinkTarget(f); 457 } 458 459 protected Path resolveLink(Path f) throws IOException { 460 return fs.resolveLink(f); 461 } 462 463 @Override 464 public FileChecksum getFileChecksum(Path f) throws IOException { 465 return fs.getFileChecksum(f); 466 } 467 468 @Override 469 public FileChecksum getFileChecksum(Path f, long length) throws IOException { 470 return fs.getFileChecksum(f, length); 471 } 472 473 @Override 474 public void setVerifyChecksum(boolean verifyChecksum) { 475 fs.setVerifyChecksum(verifyChecksum); 476 } 477 478 @Override 479 public void setWriteChecksum(boolean writeChecksum) { 480 fs.setWriteChecksum(writeChecksum); 481 } 482 483 @Override 484 public Configuration getConf() { 485 return fs.getConf(); 486 } 487 488 @Override 489 public void close() throws IOException { 490 super.close(); 491 fs.close(); 492 } 493 494 @Override 495 public void setOwner(Path p, String username, String groupname 496 ) throws IOException { 497 fs.setOwner(p, username, groupname); 498 } 499 500 @Override 501 public void setTimes(Path p, long mtime, long atime 502 ) throws IOException { 503 fs.setTimes(p, mtime, atime); 504 } 505 506 @Override 507 public void setPermission(Path p, FsPermission permission 508 ) throws IOException { 509 fs.setPermission(p, permission); 510 } 511 512 @Override 513 protected FSDataOutputStream primitiveCreate(Path f, 514 FsPermission absolutePermission, EnumSet<CreateFlag> flag, 515 int bufferSize, short replication, long blockSize, 516 Progressable progress, ChecksumOpt checksumOpt) 517 throws IOException { 518 return fs.primitiveCreate(f, absolutePermission, flag, 519 bufferSize, replication, blockSize, progress, checksumOpt); 520 } 521 522 @Override 523 @SuppressWarnings("deprecation") 524 protected boolean primitiveMkdir(Path f, FsPermission abdolutePermission) 525 throws IOException { 526 return fs.primitiveMkdir(f, abdolutePermission); 527 } 528 529 @Override // FileSystem 530 public FileSystem[] getChildFileSystems() { 531 return new FileSystem[]{fs}; 532 } 533 534 @Override // FileSystem 535 public Path createSnapshot(Path path, String snapshotName) 536 throws IOException { 537 return fs.createSnapshot(path, snapshotName); 538 } 539 540 @Override // FileSystem 541 public void renameSnapshot(Path path, String snapshotOldName, 542 String snapshotNewName) throws IOException { 543 fs.renameSnapshot(path, snapshotOldName, snapshotNewName); 544 } 545 546 @Override // FileSystem 547 public void deleteSnapshot(Path path, String snapshotName) 548 throws IOException { 549 fs.deleteSnapshot(path, snapshotName); 550 } 551 552 @Override 553 public void modifyAclEntries(Path path, List<AclEntry> aclSpec) 554 throws IOException { 555 fs.modifyAclEntries(path, aclSpec); 556 } 557 558 @Override 559 public void removeAclEntries(Path path, List<AclEntry> aclSpec) 560 throws IOException { 561 fs.removeAclEntries(path, aclSpec); 562 } 563 564 @Override 565 public void removeDefaultAcl(Path path) throws IOException { 566 fs.removeDefaultAcl(path); 567 } 568 569 @Override 570 public void removeAcl(Path path) throws IOException { 571 fs.removeAcl(path); 572 } 573 574 @Override 575 public void setAcl(Path path, List<AclEntry> aclSpec) throws IOException { 576 fs.setAcl(path, aclSpec); 577 } 578 579 @Override 580 public AclStatus getAclStatus(Path path) throws IOException { 581 return fs.getAclStatus(path); 582 } 583 584 @Override 585 public void setXAttr(Path path, String name, byte[] value) 586 throws IOException { 587 fs.setXAttr(path, name, value); 588 } 589 590 @Override 591 public void setXAttr(Path path, String name, byte[] value, 592 EnumSet<XAttrSetFlag> flag) throws IOException { 593 fs.setXAttr(path, name, value, flag); 594 } 595 596 @Override 597 public byte[] getXAttr(Path path, String name) throws IOException { 598 return fs.getXAttr(path, name); 599 } 600 601 @Override 602 public Map<String, byte[]> getXAttrs(Path path) throws IOException { 603 return fs.getXAttrs(path); 604 } 605 606 @Override 607 public Map<String, byte[]> getXAttrs(Path path, List<String> names) 608 throws IOException { 609 return fs.getXAttrs(path, names); 610 } 611 612 @Override 613 public List<String> listXAttrs(Path path) throws IOException { 614 return fs.listXAttrs(path); 615 } 616 617 @Override 618 public void removeXAttr(Path path, String name) throws IOException { 619 fs.removeXAttr(path, name); 620 } 621}