All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.util.HttpExceptionUtils Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.util;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.net.HttpURLConnection;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * HTTP utility class to help propagate server side exception to the client
 * over HTTP as a JSON payload.
 * 

* It creates HTTP Servlet and JAX-RPC error responses including details of the * exception that allows a client to recreate the remote exception. *

* It parses HTTP client connections and recreates the exception. */ @InterfaceAudience.Private @InterfaceStability.Unstable public class HttpExceptionUtils { public static final String ERROR_JSON = "RemoteException"; public static final String ERROR_EXCEPTION_JSON = "exception"; public static final String ERROR_CLASSNAME_JSON = "javaClassName"; public static final String ERROR_MESSAGE_JSON = "message"; private static final String APPLICATION_JSON_MIME = "application/json"; private static final String ENTER = System.getProperty("line.separator"); /** * Creates a HTTP servlet response serializing the exception in it as JSON. * * @param response the servlet response * @param status the error code to set in the response * @param ex the exception to serialize in the response * @throws IOException thrown if there was an error while creating the * response */ public static void createServletExceptionResponse( HttpServletResponse response, int status, Throwable ex) throws IOException { response.setStatus(status); response.setContentType(APPLICATION_JSON_MIME); Map json = new LinkedHashMap(); json.put(ERROR_MESSAGE_JSON, getOneLineMessage(ex)); json.put(ERROR_EXCEPTION_JSON, ex.getClass().getSimpleName()); json.put(ERROR_CLASSNAME_JSON, ex.getClass().getName()); Map jsonResponse = new LinkedHashMap(); jsonResponse.put(ERROR_JSON, json); Writer writer = response.getWriter(); JsonSerialization.writer().writeValue(writer, jsonResponse); writer.flush(); } /** * Creates a HTTP JAX-RPC response serializing the exception in it as JSON. * * @param status the error code to set in the response * @param ex the exception to serialize in the response * @return the JAX-RPC response with the set error and JSON encoded exception */ public static Response createJerseyExceptionResponse(Response.Status status, Throwable ex) { Map json = new LinkedHashMap(); json.put(ERROR_MESSAGE_JSON, getOneLineMessage(ex)); json.put(ERROR_EXCEPTION_JSON, ex.getClass().getSimpleName()); json.put(ERROR_CLASSNAME_JSON, ex.getClass().getName()); Map response = new LinkedHashMap(); response.put(ERROR_JSON, json); return Response.status(status).type(MediaType.APPLICATION_JSON). entity(response).build(); } private static String getOneLineMessage(Throwable exception) { String message = exception.getMessage(); if (message != null) { int i = message.indexOf(ENTER); if (i > -1) { message = message.substring(0, i); } } return message; } // trick, riding on generics to throw an undeclared exception private static void throwEx(Throwable ex) { HttpExceptionUtils.throwException(ex); } @SuppressWarnings("unchecked") private static void throwException(Throwable ex) throws E { throw (E) ex; } /** * Validates the status of an HttpURLConnection against an * expected HTTP status code. If the current status code is not the expected * one it throws an exception with a detail message using Server side error * messages if available. *

* NOTE: this method will throw the deserialized exception even if not * declared in the throws of the method signature. * * @param conn the HttpURLConnection. * @param expectedStatus the expected HTTP status code. * @throws IOException thrown if the current status code does not match the * expected one. */ @SuppressWarnings("unchecked") public static void validateResponse(HttpURLConnection conn, int expectedStatus) throws IOException { if (conn.getResponseCode() != expectedStatus) { Exception toThrow; InputStream es = null; try { es = conn.getErrorStream(); Map json = JsonSerialization.mapReader().readValue(es); json = (Map) json.get(ERROR_JSON); String exClass = (String) json.get(ERROR_CLASSNAME_JSON); String exMsg = (String) json.get(ERROR_MESSAGE_JSON); if (exClass != null) { try { ClassLoader cl = HttpExceptionUtils.class.getClassLoader(); Class klass = cl.loadClass(exClass); Constructor constr = klass.getConstructor(String.class); toThrow = (Exception) constr.newInstance(exMsg); } catch (Exception ex) { toThrow = new IOException(String.format( "HTTP status [%d], exception [%s], message [%s], URL [%s]", conn.getResponseCode(), exClass, exMsg, conn.getURL())); } } else { String msg = (exMsg != null) ? exMsg : conn.getResponseMessage(); toThrow = new IOException(String.format( "HTTP status [%d], message [%s], URL [%s]", conn.getResponseCode(), msg, conn.getURL())); } } catch (Exception ex) { toThrow = new IOException(String.format( "HTTP status [%d], message [%s], URL [%s], exception [%s]", conn.getResponseCode(), conn.getResponseMessage(), conn.getURL(), ex.toString()), ex); } finally { if (es != null) { try { es.close(); } catch (IOException ex) { //ignore } } } throwEx(toThrow); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy