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.http.server;
020
021 import org.apache.hadoop.classification.InterfaceAudience;
022 import org.apache.hadoop.conf.Configuration;
023 import org.apache.hadoop.fs.FileSystem;
024 import org.apache.hadoop.fs.XAttrCodec;
025 import org.apache.hadoop.fs.XAttrSetFlag;
026 import org.apache.hadoop.fs.http.client.HttpFSFileSystem;
027 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.AccessTimeParam;
028 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.AclPermissionParam;
029 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.BlockSizeParam;
030 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.DataParam;
031 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.DestinationParam;
032 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.FilterParam;
033 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.GroupParam;
034 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.LenParam;
035 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.ModifiedTimeParam;
036 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OffsetParam;
037 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OperationParam;
038 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OverwriteParam;
039 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.OwnerParam;
040 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.PermissionParam;
041 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.RecursiveParam;
042 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.ReplicationParam;
043 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.SourcesParam;
044 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrEncodingParam;
045 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrNameParam;
046 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrSetFlagParam;
047 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrValueParam;
048 import org.apache.hadoop.lib.service.FileSystemAccess;
049 import org.apache.hadoop.lib.service.FileSystemAccessException;
050 import org.apache.hadoop.lib.service.Groups;
051 import org.apache.hadoop.lib.service.Instrumentation;
052 import org.apache.hadoop.lib.servlet.FileSystemReleaseFilter;
053 import org.apache.hadoop.lib.wsrs.InputStreamEntity;
054 import org.apache.hadoop.lib.wsrs.Parameters;
055 import org.apache.hadoop.security.UserGroupInformation;
056 import org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation;
057 import org.json.simple.JSONObject;
058 import org.slf4j.Logger;
059 import org.slf4j.LoggerFactory;
060 import org.slf4j.MDC;
061
062 import javax.ws.rs.Consumes;
063 import javax.ws.rs.DELETE;
064 import javax.ws.rs.GET;
065 import javax.ws.rs.POST;
066 import javax.ws.rs.PUT;
067 import javax.ws.rs.Path;
068 import javax.ws.rs.PathParam;
069 import javax.ws.rs.Produces;
070 import javax.ws.rs.QueryParam;
071 import javax.ws.rs.core.Context;
072 import javax.ws.rs.core.MediaType;
073 import javax.ws.rs.core.Response;
074 import javax.ws.rs.core.UriBuilder;
075 import javax.ws.rs.core.UriInfo;
076 import java.io.IOException;
077 import java.io.InputStream;
078 import java.net.URI;
079 import java.security.AccessControlException;
080 import java.text.MessageFormat;
081 import java.util.EnumSet;
082 import java.util.List;
083 import java.util.Map;
084
085 /**
086 * Main class of HttpFSServer server.
087 * <p/>
088 * The <code>HttpFSServer</code> class uses Jersey JAX-RS to binds HTTP requests to the
089 * different operations.
090 */
091 @Path(HttpFSFileSystem.SERVICE_VERSION)
092 @InterfaceAudience.Private
093 public class HttpFSServer {
094 private static Logger AUDIT_LOG = LoggerFactory.getLogger("httpfsaudit");
095
096 /**
097 * Executes a {@link FileSystemAccess.FileSystemExecutor} using a filesystem for the effective
098 * user.
099 *
100 * @param ugi user making the request.
101 * @param executor FileSystemExecutor to execute.
102 *
103 * @return FileSystemExecutor response
104 *
105 * @throws IOException thrown if an IO error occurrs.
106 * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown
107 * exceptions are handled by {@link HttpFSExceptionProvider}.
108 */
109 private <T> T fsExecute(UserGroupInformation ugi, FileSystemAccess.FileSystemExecutor<T> executor)
110 throws IOException, FileSystemAccessException {
111 FileSystemAccess fsAccess = HttpFSServerWebApp.get().get(FileSystemAccess.class);
112 Configuration conf = HttpFSServerWebApp.get().get(FileSystemAccess.class).getFileSystemConfiguration();
113 return fsAccess.execute(ugi.getShortUserName(), conf, executor);
114 }
115
116 /**
117 * Returns a filesystem instance. The fileystem instance is wired for release at the completion of
118 * the current Servlet request via the {@link FileSystemReleaseFilter}.
119 * <p/>
120 * If a do-as user is specified, the current user must be a valid proxyuser, otherwise an
121 * <code>AccessControlException</code> will be thrown.
122 *
123 * @param ugi principal for whom the filesystem instance is.
124 *
125 * @return a filesystem for the specified user or do-as user.
126 *
127 * @throws IOException thrown if an IO error occurred. Thrown exceptions are
128 * handled by {@link HttpFSExceptionProvider}.
129 * @throws FileSystemAccessException thrown if a FileSystemAccess releated error occurred. Thrown
130 * exceptions are handled by {@link HttpFSExceptionProvider}.
131 */
132 private FileSystem createFileSystem(UserGroupInformation ugi)
133 throws IOException, FileSystemAccessException {
134 String hadoopUser = ugi.getShortUserName();
135 FileSystemAccess fsAccess = HttpFSServerWebApp.get().get(FileSystemAccess.class);
136 Configuration conf = HttpFSServerWebApp.get().get(FileSystemAccess.class).getFileSystemConfiguration();
137 FileSystem fs = fsAccess.createFileSystem(hadoopUser, conf);
138 FileSystemReleaseFilter.setFileSystem(fs);
139 return fs;
140 }
141
142 private void enforceRootPath(HttpFSFileSystem.Operation op, String path) {
143 if (!path.equals("/")) {
144 throw new UnsupportedOperationException(
145 MessageFormat.format("Operation [{0}], invalid path [{1}], must be '/'",
146 op, path));
147 }
148 }
149
150 /**
151 * Special binding for '/' as it is not handled by the wildcard binding.
152 *
153 * @param op the HttpFS operation of the request.
154 * @param params the HttpFS parameters of the request.
155 *
156 * @return the request response.
157 *
158 * @throws IOException thrown if an IO error occurred. Thrown exceptions are
159 * handled by {@link HttpFSExceptionProvider}.
160 * @throws FileSystemAccessException thrown if a FileSystemAccess releated
161 * error occurred. Thrown exceptions are handled by
162 * {@link HttpFSExceptionProvider}.
163 */
164 @GET
165 @Produces(MediaType.APPLICATION_JSON)
166 public Response getRoot(@QueryParam(OperationParam.NAME) OperationParam op,
167 @Context Parameters params)
168 throws IOException, FileSystemAccessException {
169 return get("", op, params);
170 }
171
172 private String makeAbsolute(String path) {
173 return "/" + ((path != null) ? path : "");
174 }
175
176 /**
177 * Binding to handle GET requests, supported operations are
178 *
179 * @param path the path for operation.
180 * @param op the HttpFS operation of the request.
181 * @param params the HttpFS parameters of the request.
182 *
183 * @return the request response.
184 *
185 * @throws IOException thrown if an IO error occurred. Thrown exceptions are
186 * handled by {@link HttpFSExceptionProvider}.
187 * @throws FileSystemAccessException thrown if a FileSystemAccess releated
188 * error occurred. Thrown exceptions are handled by
189 * {@link HttpFSExceptionProvider}.
190 */
191 @GET
192 @Path("{path:.*}")
193 @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
194 public Response get(@PathParam("path") String path,
195 @QueryParam(OperationParam.NAME) OperationParam op,
196 @Context Parameters params)
197 throws IOException, FileSystemAccessException {
198 UserGroupInformation user = HttpUserGroupInformation.get();
199 Response response;
200 path = makeAbsolute(path);
201 MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name());
202 switch (op.value()) {
203 case OPEN: {
204 //Invoking the command directly using an unmanaged FileSystem that is
205 // released by the FileSystemReleaseFilter
206 FSOperations.FSOpen command = new FSOperations.FSOpen(path);
207 FileSystem fs = createFileSystem(user);
208 InputStream is = command.execute(fs);
209 Long offset = params.get(OffsetParam.NAME, OffsetParam.class);
210 Long len = params.get(LenParam.NAME, LenParam.class);
211 AUDIT_LOG.info("[{}] offset [{}] len [{}]",
212 new Object[]{path, offset, len});
213 InputStreamEntity entity = new InputStreamEntity(is, offset, len);
214 response =
215 Response.ok(entity).type(MediaType.APPLICATION_OCTET_STREAM).build();
216 break;
217 }
218 case GETFILESTATUS: {
219 FSOperations.FSFileStatus command =
220 new FSOperations.FSFileStatus(path);
221 Map json = fsExecute(user, command);
222 AUDIT_LOG.info("[{}]", path);
223 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
224 break;
225 }
226 case LISTSTATUS: {
227 String filter = params.get(FilterParam.NAME, FilterParam.class);
228 FSOperations.FSListStatus command = new FSOperations.FSListStatus(
229 path, filter);
230 Map json = fsExecute(user, command);
231 AUDIT_LOG.info("[{}] filter [{}]", path,
232 (filter != null) ? filter : "-");
233 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
234 break;
235 }
236 case GETHOMEDIRECTORY: {
237 enforceRootPath(op.value(), path);
238 FSOperations.FSHomeDir command = new FSOperations.FSHomeDir();
239 JSONObject json = fsExecute(user, command);
240 AUDIT_LOG.info("");
241 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
242 break;
243 }
244 case INSTRUMENTATION: {
245 enforceRootPath(op.value(), path);
246 Groups groups = HttpFSServerWebApp.get().get(Groups.class);
247 List<String> userGroups = groups.getGroups(user.getShortUserName());
248 if (!userGroups.contains(HttpFSServerWebApp.get().getAdminGroup())) {
249 throw new AccessControlException(
250 "User not in HttpFSServer admin group");
251 }
252 Instrumentation instrumentation =
253 HttpFSServerWebApp.get().get(Instrumentation.class);
254 Map snapshot = instrumentation.getSnapshot();
255 response = Response.ok(snapshot).build();
256 break;
257 }
258 case GETCONTENTSUMMARY: {
259 FSOperations.FSContentSummary command =
260 new FSOperations.FSContentSummary(path);
261 Map json = fsExecute(user, command);
262 AUDIT_LOG.info("[{}]", path);
263 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
264 break;
265 }
266 case GETFILECHECKSUM: {
267 FSOperations.FSFileChecksum command =
268 new FSOperations.FSFileChecksum(path);
269 Map json = fsExecute(user, command);
270 AUDIT_LOG.info("[{}]", path);
271 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
272 break;
273 }
274 case GETFILEBLOCKLOCATIONS: {
275 response = Response.status(Response.Status.BAD_REQUEST).build();
276 break;
277 }
278 case GETACLSTATUS: {
279 FSOperations.FSAclStatus command =
280 new FSOperations.FSAclStatus(path);
281 Map json = fsExecute(user, command);
282 AUDIT_LOG.info("ACL status for [{}]", path);
283 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
284 break;
285 }
286 case GETXATTRS: {
287 List<String> xattrNames = params.getValues(XAttrNameParam.NAME,
288 XAttrNameParam.class);
289 XAttrCodec encoding = params.get(XAttrEncodingParam.NAME,
290 XAttrEncodingParam.class);
291 FSOperations.FSGetXAttrs command = new FSOperations.FSGetXAttrs(path,
292 xattrNames, encoding);
293 @SuppressWarnings("rawtypes")
294 Map json = fsExecute(user, command);
295 AUDIT_LOG.info("XAttrs for [{}]", path);
296 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
297 break;
298 }
299 case LISTXATTRS: {
300 FSOperations.FSListXAttrs command = new FSOperations.FSListXAttrs(path);
301 @SuppressWarnings("rawtypes")
302 Map json = fsExecute(user, command);
303 AUDIT_LOG.info("XAttr names for [{}]", path);
304 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
305 break;
306 }
307 default: {
308 throw new IOException(
309 MessageFormat.format("Invalid HTTP GET operation [{0}]",
310 op.value()));
311 }
312 }
313 return response;
314 }
315
316
317 /**
318 * Binding to handle DELETE requests.
319 *
320 * @param path the path for operation.
321 * @param op the HttpFS operation of the request.
322 * @param params the HttpFS parameters of the request.
323 *
324 * @return the request response.
325 *
326 * @throws IOException thrown if an IO error occurred. Thrown exceptions are
327 * handled by {@link HttpFSExceptionProvider}.
328 * @throws FileSystemAccessException thrown if a FileSystemAccess releated
329 * error occurred. Thrown exceptions are handled by
330 * {@link HttpFSExceptionProvider}.
331 */
332 @DELETE
333 @Path("{path:.*}")
334 @Produces(MediaType.APPLICATION_JSON)
335 public Response delete(@PathParam("path") String path,
336 @QueryParam(OperationParam.NAME) OperationParam op,
337 @Context Parameters params)
338 throws IOException, FileSystemAccessException {
339 UserGroupInformation user = HttpUserGroupInformation.get();
340 Response response;
341 path = makeAbsolute(path);
342 MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name());
343 switch (op.value()) {
344 case DELETE: {
345 Boolean recursive =
346 params.get(RecursiveParam.NAME, RecursiveParam.class);
347 AUDIT_LOG.info("[{}] recursive [{}]", path, recursive);
348 FSOperations.FSDelete command =
349 new FSOperations.FSDelete(path, recursive);
350 JSONObject json = fsExecute(user, command);
351 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
352 break;
353 }
354 default: {
355 throw new IOException(
356 MessageFormat.format("Invalid HTTP DELETE operation [{0}]",
357 op.value()));
358 }
359 }
360 return response;
361 }
362
363 /**
364 * Binding to handle POST requests.
365 *
366 * @param is the inputstream for the request payload.
367 * @param uriInfo the of the request.
368 * @param path the path for operation.
369 * @param op the HttpFS operation of the request.
370 * @param params the HttpFS parameters of the request.
371 *
372 * @return the request response.
373 *
374 * @throws IOException thrown if an IO error occurred. Thrown exceptions are
375 * handled by {@link HttpFSExceptionProvider}.
376 * @throws FileSystemAccessException thrown if a FileSystemAccess releated
377 * error occurred. Thrown exceptions are handled by
378 * {@link HttpFSExceptionProvider}.
379 */
380 @POST
381 @Path("{path:.*}")
382 @Consumes({"*/*"})
383 @Produces({MediaType.APPLICATION_JSON})
384 public Response post(InputStream is,
385 @Context UriInfo uriInfo,
386 @PathParam("path") String path,
387 @QueryParam(OperationParam.NAME) OperationParam op,
388 @Context Parameters params)
389 throws IOException, FileSystemAccessException {
390 UserGroupInformation user = HttpUserGroupInformation.get();
391 Response response;
392 path = makeAbsolute(path);
393 MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name());
394 switch (op.value()) {
395 case APPEND: {
396 Boolean hasData = params.get(DataParam.NAME, DataParam.class);
397 if (!hasData) {
398 response = Response.temporaryRedirect(
399 createUploadRedirectionURL(uriInfo,
400 HttpFSFileSystem.Operation.APPEND)).build();
401 } else {
402 FSOperations.FSAppend command =
403 new FSOperations.FSAppend(is, path);
404 fsExecute(user, command);
405 AUDIT_LOG.info("[{}]", path);
406 response = Response.ok().type(MediaType.APPLICATION_JSON).build();
407 }
408 break;
409 }
410 case CONCAT: {
411 System.out.println("HTTPFS SERVER CONCAT");
412 String sources = params.get(SourcesParam.NAME, SourcesParam.class);
413
414 FSOperations.FSConcat command =
415 new FSOperations.FSConcat(path, sources.split(","));
416 fsExecute(user, command);
417 AUDIT_LOG.info("[{}]", path);
418 System.out.println("SENT RESPONSE");
419 response = Response.ok().build();
420 break;
421 }
422 default: {
423 throw new IOException(
424 MessageFormat.format("Invalid HTTP POST operation [{0}]",
425 op.value()));
426 }
427 }
428 return response;
429 }
430
431 /**
432 * Creates the URL for an upload operation (create or append).
433 *
434 * @param uriInfo uri info of the request.
435 * @param uploadOperation operation for the upload URL.
436 *
437 * @return the URI for uploading data.
438 */
439 protected URI createUploadRedirectionURL(UriInfo uriInfo, Enum<?> uploadOperation) {
440 UriBuilder uriBuilder = uriInfo.getRequestUriBuilder();
441 uriBuilder = uriBuilder.replaceQueryParam(OperationParam.NAME, uploadOperation).
442 queryParam(DataParam.NAME, Boolean.TRUE);
443 return uriBuilder.build(null);
444 }
445
446
447 /**
448 * Binding to handle PUT requests.
449 *
450 * @param is the inputstream for the request payload.
451 * @param uriInfo the of the request.
452 * @param path the path for operation.
453 * @param op the HttpFS operation of the request.
454 * @param params the HttpFS parameters of the request.
455 *
456 * @return the request response.
457 *
458 * @throws IOException thrown if an IO error occurred. Thrown exceptions are
459 * handled by {@link HttpFSExceptionProvider}.
460 * @throws FileSystemAccessException thrown if a FileSystemAccess releated
461 * error occurred. Thrown exceptions are handled by
462 * {@link HttpFSExceptionProvider}.
463 */
464 @PUT
465 @Path("{path:.*}")
466 @Consumes({"*/*"})
467 @Produces({MediaType.APPLICATION_JSON})
468 public Response put(InputStream is,
469 @Context UriInfo uriInfo,
470 @PathParam("path") String path,
471 @QueryParam(OperationParam.NAME) OperationParam op,
472 @Context Parameters params)
473 throws IOException, FileSystemAccessException {
474 UserGroupInformation user = HttpUserGroupInformation.get();
475 Response response;
476 path = makeAbsolute(path);
477 MDC.put(HttpFSFileSystem.OP_PARAM, op.value().name());
478 switch (op.value()) {
479 case CREATE: {
480 Boolean hasData = params.get(DataParam.NAME, DataParam.class);
481 if (!hasData) {
482 response = Response.temporaryRedirect(
483 createUploadRedirectionURL(uriInfo,
484 HttpFSFileSystem.Operation.CREATE)).build();
485 } else {
486 Short permission = params.get(PermissionParam.NAME,
487 PermissionParam.class);
488 Boolean override = params.get(OverwriteParam.NAME,
489 OverwriteParam.class);
490 Short replication = params.get(ReplicationParam.NAME,
491 ReplicationParam.class);
492 Long blockSize = params.get(BlockSizeParam.NAME,
493 BlockSizeParam.class);
494 FSOperations.FSCreate command =
495 new FSOperations.FSCreate(is, path, permission, override,
496 replication, blockSize);
497 fsExecute(user, command);
498 AUDIT_LOG.info(
499 "[{}] permission [{}] override [{}] replication [{}] blockSize [{}]",
500 new Object[]{path, permission, override, replication, blockSize});
501 response = Response.status(Response.Status.CREATED).build();
502 }
503 break;
504 }
505 case SETXATTR: {
506 String xattrName = params.get(XAttrNameParam.NAME,
507 XAttrNameParam.class);
508 String xattrValue = params.get(XAttrValueParam.NAME,
509 XAttrValueParam.class);
510 EnumSet<XAttrSetFlag> flag = params.get(XAttrSetFlagParam.NAME,
511 XAttrSetFlagParam.class);
512
513 FSOperations.FSSetXAttr command = new FSOperations.FSSetXAttr(
514 path, xattrName, xattrValue, flag);
515 fsExecute(user, command);
516 AUDIT_LOG.info("[{}] to xAttr [{}]", path, xattrName);
517 response = Response.ok().build();
518 break;
519 }
520 case REMOVEXATTR: {
521 String xattrName = params.get(XAttrNameParam.NAME, XAttrNameParam.class);
522 FSOperations.FSRemoveXAttr command = new FSOperations.FSRemoveXAttr(
523 path, xattrName);
524 fsExecute(user, command);
525 AUDIT_LOG.info("[{}] removed xAttr [{}]", path, xattrName);
526 response = Response.ok().build();
527 break;
528 }
529 case MKDIRS: {
530 Short permission = params.get(PermissionParam.NAME,
531 PermissionParam.class);
532 FSOperations.FSMkdirs command =
533 new FSOperations.FSMkdirs(path, permission);
534 JSONObject json = fsExecute(user, command);
535 AUDIT_LOG.info("[{}] permission [{}]", path, permission);
536 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
537 break;
538 }
539 case RENAME: {
540 String toPath = params.get(DestinationParam.NAME, DestinationParam.class);
541 FSOperations.FSRename command =
542 new FSOperations.FSRename(path, toPath);
543 JSONObject json = fsExecute(user, command);
544 AUDIT_LOG.info("[{}] to [{}]", path, toPath);
545 response = Response.ok(json).type(MediaType.APPLICATION_JSON).build();
546 break;
547 }
548 case SETOWNER: {
549 String owner = params.get(OwnerParam.NAME, OwnerParam.class);
550 String group = params.get(GroupParam.NAME, GroupParam.class);
551 FSOperations.FSSetOwner command =
552 new FSOperations.FSSetOwner(path, owner, group);
553 fsExecute(user, command);
554 AUDIT_LOG.info("[{}] to (O/G)[{}]", path, owner + ":" + group);
555 response = Response.ok().build();
556 break;
557 }
558 case SETPERMISSION: {
559 Short permission = params.get(PermissionParam.NAME,
560 PermissionParam.class);
561 FSOperations.FSSetPermission command =
562 new FSOperations.FSSetPermission(path, permission);
563 fsExecute(user, command);
564 AUDIT_LOG.info("[{}] to [{}]", path, permission);
565 response = Response.ok().build();
566 break;
567 }
568 case SETREPLICATION: {
569 Short replication = params.get(ReplicationParam.NAME,
570 ReplicationParam.class);
571 FSOperations.FSSetReplication command =
572 new FSOperations.FSSetReplication(path, replication);
573 JSONObject json = fsExecute(user, command);
574 AUDIT_LOG.info("[{}] to [{}]", path, replication);
575 response = Response.ok(json).build();
576 break;
577 }
578 case SETTIMES: {
579 Long modifiedTime = params.get(ModifiedTimeParam.NAME,
580 ModifiedTimeParam.class);
581 Long accessTime = params.get(AccessTimeParam.NAME,
582 AccessTimeParam.class);
583 FSOperations.FSSetTimes command =
584 new FSOperations.FSSetTimes(path, modifiedTime, accessTime);
585 fsExecute(user, command);
586 AUDIT_LOG.info("[{}] to (M/A)[{}]", path,
587 modifiedTime + ":" + accessTime);
588 response = Response.ok().build();
589 break;
590 }
591 case SETACL: {
592 String aclSpec = params.get(AclPermissionParam.NAME,
593 AclPermissionParam.class);
594 FSOperations.FSSetAcl command =
595 new FSOperations.FSSetAcl(path, aclSpec);
596 fsExecute(user, command);
597 AUDIT_LOG.info("[{}] to acl [{}]", path, aclSpec);
598 response = Response.ok().build();
599 break;
600 }
601 case REMOVEACL: {
602 FSOperations.FSRemoveAcl command =
603 new FSOperations.FSRemoveAcl(path);
604 fsExecute(user, command);
605 AUDIT_LOG.info("[{}] removed acl", path);
606 response = Response.ok().build();
607 break;
608 }
609 case MODIFYACLENTRIES: {
610 String aclSpec = params.get(AclPermissionParam.NAME,
611 AclPermissionParam.class);
612 FSOperations.FSModifyAclEntries command =
613 new FSOperations.FSModifyAclEntries(path, aclSpec);
614 fsExecute(user, command);
615 AUDIT_LOG.info("[{}] modify acl entry with [{}]", path, aclSpec);
616 response = Response.ok().build();
617 break;
618 }
619 case REMOVEACLENTRIES: {
620 String aclSpec = params.get(AclPermissionParam.NAME,
621 AclPermissionParam.class);
622 FSOperations.FSRemoveAclEntries command =
623 new FSOperations.FSRemoveAclEntries(path, aclSpec);
624 fsExecute(user, command);
625 AUDIT_LOG.info("[{}] remove acl entry [{}]", path, aclSpec);
626 response = Response.ok().build();
627 break;
628 }
629 case REMOVEDEFAULTACL: {
630 FSOperations.FSRemoveDefaultAcl command =
631 new FSOperations.FSRemoveDefaultAcl(path);
632 fsExecute(user, command);
633 AUDIT_LOG.info("[{}] remove default acl", path);
634 response = Response.ok().build();
635 break;
636 }
637 default: {
638 throw new IOException(
639 MessageFormat.format("Invalid HTTP PUT operation [{0}]",
640 op.value()));
641 }
642 }
643 return response;
644 }
645
646 }