Package org.platformlayer

Source Code of org.platformlayer.PlatformLayerHttpRequest

package org.platformlayer;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.ConnectException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;

import org.platformlayer.http.HttpMethod;
import org.platformlayer.http.HttpRequest;
import org.platformlayer.http.HttpResponse;
import org.platformlayer.http.SslConfiguration;
import org.platformlayer.rest.Utf8StringByteSource;
import org.platformlayer.xml.JaxbHelper;
import org.platformlayer.xml.JsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fathomdb.Casts;
import com.fathomdb.crypto.ssl.AcceptAllHostnameVerifier;
import com.fathomdb.crypto.ssl.PublicKeyTrustManager;
import com.fathomdb.io.IoUtils;

class PlatformLayerHttpRequest implements Closeable {
  private static final Logger log = LoggerFactory.getLogger(PlatformLayerHttpRequest.class);

  final PlatformLayerHttpTransport client;
  final HttpRequest httpRequest;
  HttpResponse response;

  PrintStream debug;

  public PlatformLayerHttpRequest(PlatformLayerHttpTransport client, HttpMethod method, URI uri,
      List<String> trustKeys) throws PlatformLayerClientException {
    this.client = client;

    KeyManager keyManager = null;
    TrustManager trustManager = null;
    HostnameVerifier hostnameVerifier = null;

    if (trustKeys != null) {
      trustManager = new PublicKeyTrustManager(trustKeys);
      hostnameVerifier = new AcceptAllHostnameVerifier();
    }

    SslConfiguration sslConfiguration = new SslConfiguration(keyManager, trustManager, hostnameVerifier);

    this.httpRequest = client.getHttpStrategy().buildConfiguration(sslConfiguration).buildRequest(method, uri);
  }

  void populateHttpRequest(Format acceptFormat, Format contentFormat) throws PlatformLayerClientException {
    if (acceptFormat != null) {
      switch (acceptFormat) {
      case XML:
        httpRequest.setRequestHeader("Accept", "application/xml");
        break;
      case JSON:
        httpRequest.setRequestHeader("Accept", "application/json");
        break;
      case TEXT:
        httpRequest.setRequestHeader("Accept", "text/plain");
        break;

      default:
        throw new IllegalStateException();
      }
    }

    if (contentFormat != null) {
      switch (contentFormat) {
      case XML:
        httpRequest.setRequestHeader("Content-Type", "application/xml");
        break;
      case JSON:
        httpRequest.setRequestHeader("Content-Type", "application/json");
        break;
      case TEXT:
        httpRequest.setRequestHeader("Content-Type", "text/plain");
        break;

      default:
        throw new IllegalStateException();
      }
    }

    this.client.getAuthenticationToken().populateRequest(httpRequest);
  }

  HttpResponse getResponse() throws IOException {
    if (response == null) {
      response = httpRequest.doRequest();
    }
    return response;
  }

  InputStream getInputStream() throws IOException {
    return getResponse().getInputStream();
  }

  @Override
  public void close() throws IOException {
    if (response != null) {
      response.close();
      response = null;
    }
  }

  InputStream getErrorStream() throws IOException {
    return getResponse().getErrorStream();
  }

  public <T> T doRequest(Class<T> retvalClass, Format acceptFormat, Object sendData, Format sendDataFormat)
      throws PlatformLayerClientException {
    try {
      populateHttpRequest(acceptFormat, sendDataFormat);

      if (debug != null) {
        debug.println("Request: " + httpRequest);
      }

      if (sendData != null) {
        if (sendData instanceof String) {
          if (debug != null) {
            debug.println("Data: " + sendData);
          }

          String sendDataString = (String) sendData;
          httpRequest.setRequestContent(new Utf8StringByteSource(sendDataString));
        } else {
          switch (sendDataFormat) {
          case XML:
            if (debug != null) {
              debug.println("Data: [XML Content]");
            }

            JaxbHelper jaxbHelper = JaxbHelper.get(sendData.getClass());
            String xml = jaxbHelper.marshal(sendData, false);
            httpRequest.setRequestContent(new Utf8StringByteSource(xml));
            // jaxbHelper.marshal(sendData, false, getOutputStream());
            break;
          case JSON:
            if (debug != null) {
              debug.println("Data: [JSON Content]");
            }

            JsonHelper jsonHelper = JsonHelper.build(sendData.getClass());
            String json = jsonHelper.marshal(sendData, false);
            httpRequest.setRequestContent(new Utf8StringByteSource(json));
            // jsonHelper.marshal(sendData, false, getOutputStream());
            break;
          default:
            throw new IllegalStateException();
          }
        }
      }
    } catch (JAXBException e) {
      throw new PlatformLayerClientException("Error while building request", e);
    } catch (IOException e) {
      throw new PlatformLayerClientException("Error while building request", e);
    }
    // catch (XMLStreamException e) {
    // throw new PlatformLayerClientException("Error while building request", e);
    // } catch (TransformerException e) {
    // throw new PlatformLayerClientException("Error while building request", e);
    // } catch (JSONException e) {
    // throw new PlatformLayerClientException("Error while building request", e);
    // }

    try {
      processHttpResponseCode(getResponse());

      if (retvalClass == null) {
        return null;
      } else if (String.class.equals(retvalClass)) {
        InputStream is = getInputStream();

        String text = null;
        if (is != null) {
          text = IoUtils.readAll(is);
        }

        if (debug != null) {
          debug.println("Response: " + text);
        }

        return Casts.as(text, retvalClass);
      } else if (StreamingResponse.class.equals(retvalClass)) {
        return Casts.as(new StreamingResponse(getResponse()), retvalClass);
      } else {
        if (debug != null) {
          debug.println("Response: XML/JSON content");
        }

        InputStream is = getInputStream();

        return JaxbHelper.deserializeXmlObject(is, retvalClass, true);
      }
    } catch (ConnectException e) {
      throw new PlatformLayerClientException("Error connecting to PlatformLayer service", e);
    } catch (UnmarshalException e) {
      throw new PlatformLayerClientException("Error while reading PlatformLayer response", e);
    } catch (IOException e) {
      throw new PlatformLayerClientException("Error communicating with PlatformLayer service", e);
    }
  }

  private void processHttpResponseCode(HttpResponse response) throws PlatformLayerClientException, IOException {
    // Send the HTTP request
    int httpResponseCode = response.getHttpResponseCode();

    if (debug != null) {
      debug.println("Response: " + response);

      Map<String, List<String>> headers = response.getHeaderFields();
      for (Entry<String, List<String>> entry : headers.entrySet()) {
        String key = entry.getKey();
        if (key == null) {
          // Ignore entry "key=null, value=HTTP/1.1 200 OK"
          continue;
        }

        for (String value : entry.getValue()) {
          debug.println(key + ": " + value);
        }
      }
    }

    switch (httpResponseCode) {
    case 200: // OK
    case 201: // Created
    case 202: // Async accepted
    case 204: // No content
      break;
    case 203: // Cached
      String lastModified = getResponse().getResponseHeaderField("Last-Modified");
      // Map<String, List<String>> headerFields = httpConn.getHeaderFields();
      log.debug("Cached content at: " + httpRequest.getUrl() + " lastModified=" + lastModified);
      break;
    case 401:
      throw new PlatformLayerAuthenticationException("Not authorized (or authorization timed out)");
    case 404:
      throw new PlatformLayerClientNotFoundException("Not found", 404, httpRequest.getUrl());
    case 500:
      throw buildExceptionFromErrorStream(httpResponseCode);

    default:
      throw buildExceptionFromErrorStream(httpResponseCode);
    }
  }

  private PlatformLayerClientException buildExceptionFromErrorStream(int httpResponseCode) throws IOException {
    InputStream errorStream = null;
    String errorText = null;
    try {
      errorStream = getErrorStream();
      if (errorStream != null) {
        errorText = IoUtils.readAll(errorStream);
      }
    } catch (IOException e) {
      log.warn("Could not read error response from request", e);
    } finally {
      IoUtils.safeClose(errorStream);
    }

    String faultReason = parseFaultReason(errorText);
    if (faultReason == null) {
      return new PlatformLayerClientException("Unexpected error from PlatformLayer.  ResponseCode="
          + httpResponseCode + " Details=" + errorText, httpResponseCode);
    } else {
      return new PlatformLayerClientException(faultReason, httpResponseCode);
    }
  }

  private String parseFaultReason(String xml) {
    if (xml == null) {
      return null;
    }

    return xml;

    // try {
    // // The rather odd ByteArrayInputStream(xml.getBytes()) is so that we can print the response even if we have a
    // problem parsing it
    // ServiceFault cloudServersAPIFault = JaxbHelper.deserializeXmlObject(new ByteArrayInputStream(xml.getBytes()),
    // ServiceFault.class);
    // return cloudServersAPIFault;
    // } catch (OpenstackException e) {
    // log.warn("Could not parse error response: " + xml, e);
    // return null;
    // }
  }

}
TOP

Related Classes of org.platformlayer.PlatformLayerHttpRequest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.