/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio; import alluxio.security.LoginUser; import alluxio.security.authentication.AuthenticatedClientUser; import alluxio.util.SecurityUtils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import javax.ws.rs.core.Response; /** * Utilities for handling REST calls. */ public final class RestUtils { private static final Logger LOG = LoggerFactory.getLogger(RestUtils.class); /** * Calls the given {@link RestUtils.RestCallable} and handles any exceptions thrown. * * @param <T> the return type of the callable * @param callable the callable to call * @return the response object */ public static <T> Response call(RestUtils.RestCallable<T> callable) { try { if (SecurityUtils.isSecurityEnabled() && AuthenticatedClientUser.get() == null) { AuthenticatedClientUser.set(LoginUser.get().getName()); } } catch (IOException e) { LOG.error("Failed to set AuthenticatedClientUser in REST service handler.", e); return createErrorResponse(e.getMessage()); } try { return createResponse(callable.call()); } catch (Exception e) { LOG.error("Unexpected error invoking rest endpoint", e); return createErrorResponse(e.getMessage()); } } /** * An interface representing a callable. * * @param <T> the return type of the callable */ public interface RestCallable<T> { /** * The REST endpoint implementation. * * @return the return value from the callable */ T call() throws Exception; } /** * Creates a response using the given object. * * @param object the object to respond with * @return the response */ private static Response createResponse(Object object) { if (object instanceof Void) { return Response.ok().build(); } if (object instanceof String) { // Need to explicitly encode the string as JSON because Jackson will not do it automatically. ObjectMapper mapper = new ObjectMapper(); try { return Response.ok(mapper.writeValueAsString(object)).build(); } catch (JsonProcessingException e) { return createErrorResponse(e.getMessage()); } } return Response.ok(object).build(); } /** * Creates an error response using the given message. * * @param message the message to respond with * @return the response */ private static Response createErrorResponse(String message) { return Response.serverError().entity(message).build(); } private RestUtils() {} // prevent instantiation }