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 package org.apache.hadoop.hdfs.client;
019
020 import java.io.FileNotFoundException;
021 import java.io.IOException;
022 import java.net.URI;
023 import java.util.EnumSet;
024
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.CacheFlag;
029 import org.apache.hadoop.fs.FileSystem;
030 import org.apache.hadoop.fs.Path;
031 import org.apache.hadoop.fs.RemoteIterator;
032 import org.apache.hadoop.hdfs.DFSInotifyEventInputStream;
033 import org.apache.hadoop.hdfs.DistributedFileSystem;
034 import org.apache.hadoop.hdfs.protocol.CacheDirectiveEntry;
035 import org.apache.hadoop.hdfs.protocol.CacheDirectiveInfo;
036 import org.apache.hadoop.hdfs.protocol.CachePoolEntry;
037 import org.apache.hadoop.hdfs.protocol.CachePoolInfo;
038 import org.apache.hadoop.hdfs.protocol.EncryptionZone;
039 import org.apache.hadoop.hdfs.protocol.HdfsConstants;
040 import org.apache.hadoop.security.AccessControlException;
041 import org.apache.hadoop.hdfs.tools.DFSAdmin;
042
043 /**
044 * The public API for performing administrative functions on HDFS. Those writing
045 * applications against HDFS should prefer this interface to directly accessing
046 * functionality in DistributedFileSystem or DFSClient.
047 *
048 * Note that this is distinct from the similarly-named {@link DFSAdmin}, which
049 * is a class that provides the functionality for the CLI `hdfs dfsadmin ...'
050 * commands.
051 */
052 @InterfaceAudience.Public
053 @InterfaceStability.Evolving
054 public class HdfsAdmin {
055
056 private DistributedFileSystem dfs;
057
058 /**
059 * Create a new HdfsAdmin client.
060 *
061 * @param uri the unique URI of the HDFS file system to administer
062 * @param conf configuration
063 * @throws IOException in the event the file system could not be created
064 */
065 public HdfsAdmin(URI uri, Configuration conf) throws IOException {
066 FileSystem fs = FileSystem.get(uri, conf);
067 if (!(fs instanceof DistributedFileSystem)) {
068 throw new IllegalArgumentException("'" + uri + "' is not an HDFS URI.");
069 } else {
070 dfs = (DistributedFileSystem)fs;
071 }
072 }
073
074 /**
075 * Set the namespace quota (count of files, directories, and sym links) for a
076 * directory.
077 *
078 * @param src the path to set the quota for
079 * @param quota the value to set for the quota
080 * @throws IOException in the event of error
081 */
082 public void setQuota(Path src, long quota) throws IOException {
083 dfs.setQuota(src, quota, HdfsConstants.QUOTA_DONT_SET);
084 }
085
086 /**
087 * Clear the namespace quota (count of files, directories and sym links) for a
088 * directory.
089 *
090 * @param src the path to clear the quota of
091 * @throws IOException in the event of error
092 */
093 public void clearQuota(Path src) throws IOException {
094 dfs.setQuota(src, HdfsConstants.QUOTA_RESET, HdfsConstants.QUOTA_DONT_SET);
095 }
096
097 /**
098 * Set the disk space quota (size of files) for a directory. Note that
099 * directories and sym links do not occupy disk space.
100 *
101 * @param src the path to set the space quota of
102 * @param spaceQuota the value to set for the space quota
103 * @throws IOException in the event of error
104 */
105 public void setSpaceQuota(Path src, long spaceQuota) throws IOException {
106 dfs.setQuota(src, HdfsConstants.QUOTA_DONT_SET, spaceQuota);
107 }
108
109 /**
110 * Clear the disk space quota (size of files) for a directory. Note that
111 * directories and sym links do not occupy disk space.
112 *
113 * @param src the path to clear the space quota of
114 * @throws IOException in the event of error
115 */
116 public void clearSpaceQuota(Path src) throws IOException {
117 dfs.setQuota(src, HdfsConstants.QUOTA_DONT_SET, HdfsConstants.QUOTA_RESET);
118 }
119
120 /**
121 * Allow snapshot on a directory.
122 * @param path The path of the directory where snapshots will be taken.
123 */
124 public void allowSnapshot(Path path) throws IOException {
125 dfs.allowSnapshot(path);
126 }
127
128 /**
129 * Disallow snapshot on a directory.
130 * @param path The path of the snapshottable directory.
131 */
132 public void disallowSnapshot(Path path) throws IOException {
133 dfs.disallowSnapshot(path);
134 }
135
136 /**
137 * Add a new CacheDirectiveInfo.
138 *
139 * @param info Information about a directive to add.
140 * @param flags {@link CacheFlag}s to use for this operation.
141 * @return the ID of the directive that was created.
142 * @throws IOException if the directive could not be added
143 */
144 public long addCacheDirective(CacheDirectiveInfo info,
145 EnumSet<CacheFlag> flags) throws IOException {
146 return dfs.addCacheDirective(info, flags);
147 }
148
149 /**
150 * Modify a CacheDirective.
151 *
152 * @param info Information about the directive to modify. You must set the ID
153 * to indicate which CacheDirective you want to modify.
154 * @param flags {@link CacheFlag}s to use for this operation.
155 * @throws IOException if the directive could not be modified
156 */
157 public void modifyCacheDirective(CacheDirectiveInfo info,
158 EnumSet<CacheFlag> flags) throws IOException {
159 dfs.modifyCacheDirective(info, flags);
160 }
161
162 /**
163 * Remove a CacheDirective.
164 *
165 * @param id identifier of the CacheDirectiveInfo to remove
166 * @throws IOException if the directive could not be removed
167 */
168 public void removeCacheDirective(long id)
169 throws IOException {
170 dfs.removeCacheDirective(id);
171 }
172
173 /**
174 * List cache directives. Incrementally fetches results from the server.
175 *
176 * @param filter Filter parameters to use when listing the directives, null to
177 * list all directives visible to us.
178 * @return A RemoteIterator which returns CacheDirectiveInfo objects.
179 */
180 public RemoteIterator<CacheDirectiveEntry> listCacheDirectives(
181 CacheDirectiveInfo filter) throws IOException {
182 return dfs.listCacheDirectives(filter);
183 }
184
185 /**
186 * Add a cache pool.
187 *
188 * @param info
189 * The request to add a cache pool.
190 * @throws IOException
191 * If the request could not be completed.
192 */
193 public void addCachePool(CachePoolInfo info) throws IOException {
194 dfs.addCachePool(info);
195 }
196
197 /**
198 * Modify an existing cache pool.
199 *
200 * @param info
201 * The request to modify a cache pool.
202 * @throws IOException
203 * If the request could not be completed.
204 */
205 public void modifyCachePool(CachePoolInfo info) throws IOException {
206 dfs.modifyCachePool(info);
207 }
208
209 /**
210 * Remove a cache pool.
211 *
212 * @param poolName
213 * Name of the cache pool to remove.
214 * @throws IOException
215 * if the cache pool did not exist, or could not be removed.
216 */
217 public void removeCachePool(String poolName) throws IOException {
218 dfs.removeCachePool(poolName);
219 }
220
221 /**
222 * List all cache pools.
223 *
224 * @return A remote iterator from which you can get CachePoolEntry objects.
225 * Requests will be made as needed.
226 * @throws IOException
227 * If there was an error listing cache pools.
228 */
229 public RemoteIterator<CachePoolEntry> listCachePools() throws IOException {
230 return dfs.listCachePools();
231 }
232
233 /**
234 * Create an encryption zone rooted at an empty existing directory, using the
235 * specified encryption key. An encryption zone has an associated encryption
236 * key used when reading and writing files within the zone.
237 *
238 * @param path The path of the root of the encryption zone. Must refer to
239 * an empty, existing directory.
240 * @param keyName Name of key available at the KeyProvider.
241 * @throws IOException if there was a general IO exception
242 * @throws AccessControlException if the caller does not have access to path
243 * @throws FileNotFoundException if the path does not exist
244 */
245 public void createEncryptionZone(Path path, String keyName)
246 throws IOException, AccessControlException, FileNotFoundException {
247 dfs.createEncryptionZone(path, keyName);
248 }
249
250 /**
251 * Get the path of the encryption zone for a given file or directory.
252 *
253 * @param path The path to get the ez for.
254 *
255 * @return The EncryptionZone of the ez, or null if path is not in an ez.
256 * @throws IOException if there was a general IO exception
257 * @throws AccessControlException if the caller does not have access to path
258 * @throws FileNotFoundException if the path does not exist
259 */
260 public EncryptionZone getEncryptionZoneForPath(Path path)
261 throws IOException, AccessControlException, FileNotFoundException {
262 return dfs.getEZForPath(path);
263 }
264
265 /**
266 * Returns a RemoteIterator which can be used to list the encryption zones
267 * in HDFS. For large numbers of encryption zones, the iterator will fetch
268 * the list of zones in a number of small batches.
269 * <p/>
270 * Since the list is fetched in batches, it does not represent a
271 * consistent snapshot of the entire list of encryption zones.
272 * <p/>
273 * This method can only be called by HDFS superusers.
274 */
275 public RemoteIterator<EncryptionZone> listEncryptionZones()
276 throws IOException {
277 return dfs.listEncryptionZones();
278 }
279
280 /**
281 * Exposes a stream of namesystem events. Only events occurring after the
282 * stream is created are available.
283 * See {@link org.apache.hadoop.hdfs.DFSInotifyEventInputStream}
284 * for information on stream usage.
285 * See {@link org.apache.hadoop.hdfs.inotify.Event}
286 * for information on the available events.
287 * <p/>
288 * Inotify users may want to tune the following HDFS parameters to
289 * ensure that enough extra HDFS edits are saved to support inotify clients
290 * that fall behind the current state of the namespace while reading events.
291 * The default parameter values should generally be reasonable. If edits are
292 * deleted before their corresponding events can be read, clients will see a
293 * {@link org.apache.hadoop.hdfs.inotify.MissingEventsException} on
294 * {@link org.apache.hadoop.hdfs.DFSInotifyEventInputStream} method calls.
295 *
296 * It should generally be sufficient to tune these parameters:
297 * dfs.namenode.num.extra.edits.retained
298 * dfs.namenode.max.extra.edits.segments.retained
299 *
300 * Parameters that affect the number of created segments and the number of
301 * edits that are considered necessary, i.e. do not count towards the
302 * dfs.namenode.num.extra.edits.retained quota):
303 * dfs.namenode.checkpoint.period
304 * dfs.namenode.checkpoint.txns
305 * dfs.namenode.num.checkpoints.retained
306 * dfs.ha.log-roll.period
307 * <p/>
308 * It is recommended that local journaling be configured
309 * (dfs.namenode.edits.dir) for inotify (in addition to a shared journal)
310 * so that edit transfers from the shared journal can be avoided.
311 *
312 * @throws IOException If there was an error obtaining the stream.
313 */
314 public DFSInotifyEventInputStream getInotifyEventStream() throws IOException {
315 return dfs.getInotifyEventStream();
316 }
317
318 /**
319 * A version of {@link HdfsAdmin#getInotifyEventStream()} meant for advanced
320 * users who are aware of HDFS edits up to lastReadTxid (e.g. because they
321 * have access to an FSImage inclusive of lastReadTxid) and only want to read
322 * events after this point.
323 */
324 public DFSInotifyEventInputStream getInotifyEventStream(long lastReadTxid)
325 throws IOException {
326 return dfs.getInotifyEventStream(lastReadTxid);
327 }
328
329 /**
330 * Set the source path to the specified storage policy.
331 *
332 * @param src The source path referring to either a directory or a file.
333 * @param policyName The name of the storage policy.
334 */
335 public void setStoragePolicy(final Path src, final String policyName)
336 throws IOException {
337 dfs.setStoragePolicy(src, policyName);
338 }
339 }