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 */ 018package org.apache.hadoop.fs; 019 020import java.io.IOException; 021 022import org.apache.commons.logging.LogFactory; 023import org.apache.hadoop.classification.InterfaceAudience; 024import org.apache.hadoop.classification.InterfaceStability; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.conf.Configured; 027 028/** 029 * Provides a trash facility which supports pluggable Trash policies. 030 * 031 * See the implementation of the configured TrashPolicy for more 032 * details. 033 */ 034@InterfaceAudience.Public 035@InterfaceStability.Stable 036public class Trash extends Configured { 037 private static final org.apache.commons.logging.Log LOG = 038 LogFactory.getLog(Trash.class); 039 040 private TrashPolicy trashPolicy; // configured trash policy instance 041 042 /** 043 * Construct a trash can accessor. 044 * @param conf a Configuration 045 */ 046 public Trash(Configuration conf) throws IOException { 047 this(FileSystem.get(conf), conf); 048 } 049 050 /** 051 * Construct a trash can accessor for the FileSystem provided. 052 * @param fs the FileSystem 053 * @param conf a Configuration 054 */ 055 public Trash(FileSystem fs, Configuration conf) throws IOException { 056 super(conf); 057 trashPolicy = TrashPolicy.getInstance(conf, fs, fs.getHomeDirectory()); 058 } 059 060 /** 061 * In case of the symlinks or mount points, one has to move the appropriate 062 * trashbin in the actual volume of the path p being deleted. 063 * 064 * Hence we get the file system of the fully-qualified resolved-path and 065 * then move the path p to the trashbin in that volume, 066 * @param fs - the filesystem of path p 067 * @param p - the path being deleted - to be moved to trasg 068 * @param conf - configuration 069 * @return false if the item is already in the trash or trash is disabled 070 * @throws IOException on error 071 */ 072 public static boolean moveToAppropriateTrash(FileSystem fs, Path p, 073 Configuration conf) throws IOException { 074 Path fullyResolvedPath = fs.resolvePath(p); 075 FileSystem fullyResolvedFs = 076 FileSystem.get(fullyResolvedPath.toUri(), conf); 077 // If the trash interval is configured server side then clobber this 078 // configuration so that we always respect the server configuration. 079 try { 080 long trashInterval = fullyResolvedFs.getServerDefaults( 081 fullyResolvedPath).getTrashInterval(); 082 if (0 != trashInterval) { 083 Configuration confCopy = new Configuration(conf); 084 confCopy.setLong(CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY, 085 trashInterval); 086 conf = confCopy; 087 } 088 } catch (Exception e) { 089 // If we can not determine that trash is enabled server side then 090 // bail rather than potentially deleting a file when trash is enabled. 091 LOG.warn("Failed to get server trash configuration", e); 092 throw new IOException("Failed to get server trash configuration", e); 093 } 094 Trash trash = new Trash(fullyResolvedFs, conf); 095 boolean success = trash.moveToTrash(fullyResolvedPath); 096 if (success) { 097 System.out.println("Moved: '" + p + "' to trash at: " + 098 trash.getCurrentTrashDir() ); 099 } 100 return success; 101 } 102 103 /** 104 * Returns whether the trash is enabled for this filesystem 105 */ 106 public boolean isEnabled() { 107 return trashPolicy.isEnabled(); 108 } 109 110 /** Move a file or directory to the current trash directory. 111 * @return false if the item is already in the trash or trash is disabled 112 */ 113 public boolean moveToTrash(Path path) throws IOException { 114 return trashPolicy.moveToTrash(path); 115 } 116 117 /** Create a trash checkpoint. */ 118 public void checkpoint() throws IOException { 119 trashPolicy.createCheckpoint(); 120 } 121 122 /** Delete old checkpoint(s). */ 123 public void expunge() throws IOException { 124 trashPolicy.deleteCheckpoint(); 125 } 126 127 /** get the current working directory */ 128 public Path getCurrentTrashDir() { 129 return trashPolicy.getCurrentTrashDir(); 130 } 131 132 /** get the configured trash policy */ 133 TrashPolicy getTrashPolicy() { 134 return trashPolicy; 135 } 136 137 /** Return a {@link Runnable} that periodically empties the trash of all 138 * users, intended to be run by the superuser. 139 */ 140 public Runnable getEmptier() throws IOException { 141 return trashPolicy.getEmptier(); 142 } 143}