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