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.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
050 public 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 }