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