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