Package com.ibm.sbt.service.basic

Source Code of com.ibm.sbt.service.basic.AbstractFileProxyService

package com.ibm.sbt.service.basic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;

import com.ibm.commons.runtime.NoAccessSignal;
import com.ibm.commons.runtime.mime.MIME;
import com.ibm.commons.util.PathUtil;
import com.ibm.commons.util.StringUtil;
import com.ibm.sbt.services.client.ClientService;
import com.ibm.sbt.services.client.ClientService.Args;
import com.ibm.sbt.services.client.ClientService.Content;
import com.ibm.sbt.services.client.ClientService.ContentFile;
import com.ibm.sbt.services.client.ClientService.Handler;
import com.ibm.sbt.services.client.ClientServicesException;
import com.ibm.sbt.services.endpoints.Endpoint;
import com.ibm.sbt.services.endpoints.EndpointFactory;
import com.ibm.sbt.services.util.AuthUtil;
import com.ibm.sbt.services.util.SSLUtil;

/**
*
* @author Vineet Kanwal
**/
public abstract class AbstractFileProxyService extends ProxyEndpointService {

  protected enum Operations {
    UPLOAD_FILE("UploadFile"),
    DOWNLOAD_FILE("DownloadFile"),
    UPDATE_PROFILE_PHOTO("UpdateProfilePhoto"),
    UPLOAD_NEW_VERSION("UploadNewVersion"),
    UPDATE_COMMUNITY_LOGO("UpdateCommunityLogo"),
    UPLOAD_COMMUNITY_FILE("UploadCommunityFile");

    private Operations(final String text) {
      this.text = text;
    }

    private final String text;

    @Override
    public String toString() {
      return text;
    }

  }

  protected Map<String, String> parameters = new HashMap<String, String>();

  protected String operation = null;

  protected String method = null;

  private Long length = 0L;
 
  protected static String MIMETYPE_DEFAULT = "application/octet-stream";
  protected static String MIMETYPE_UNKNOWN = "unknown/unknown";

  protected abstract String getRequestURI(String smethod, String authType, Map<String, String[]> params) throws ServletException;

  @Override
  protected void initProxy(HttpServletRequest request, HttpServletResponse response) throws ServletException {
    // TODO can this be moved to parametrers
    String pathinfo = request.getPathInfo().substring(request.getPathInfo().indexOf("/files"));
    String[] pathTokens = pathinfo.split("/");
    if (pathTokens.length >= 6) {
      // /files/<<endpointName>>/serviceTpe/fileName
      String endPointName = pathTokens[2];
      this.endpoint = (Endpoint) EndpointFactory.getEndpoint(endPointName);
      if (!endpoint.isAllowClientAccess()) {
        throw new ServletException(StringUtil.format("Client access forbidden for the specified endpoint {0}", endPointName));
      }
      operation = pathTokens[4];
      getParameters(pathTokens);
      method = request.getMethod();
      requestURI = getRequestURI(request.getMethod(), AuthUtil.INSTANCE.getAuthValue(endpoint), request.getParameterMap());
      return;
    }
    throw new ServletException(StringUtil.format("Invalid url {0}", pathinfo));
  }

  protected abstract void getParameters(String[] tokens) throws ServletException;

  @Override
  public void serviceProxy(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {     
    try {
      initProxy(request, response);
      String smethod = request.getMethod();
      DefaultHttpClient client = getClient(request, getSocketReadTimeout());
      URI url = getRequestURI(request);
      HttpRequestBase method = createMethod(smethod, url, request);
      if (prepareForwardingMethod(method, request, client)) {
        if (smethod.equalsIgnoreCase("POST") || (smethod.equalsIgnoreCase("PUT"))) {
          FileItemFactory factory = new DiskFileItemFactory();
          // Create a new file upload handler
          ServletFileUpload upload = new ServletFileUpload(factory);         
          // Parse the request
          @SuppressWarnings("unchecked")
          List<FileItem> fileItems = upload.parseRequest(request);
          if (fileItems.size() == 0) {
            writeErrorResponse(HttpServletResponse.SC_BAD_REQUEST, "No File Item found in Multipart Form data", new String[] {}, new String[] {}, response, request);
            return;
          }
          for (FileItem uploadedFile : fileItems) {            
            InputStream uploadedFileContent = uploadedFile.getInputStream();
            Map<String, String[]> params = request.getParameterMap() != null ? request.getParameterMap() : new HashMap<String, String[]>();
            String contentType = uploadedFile.getContentType();
            if (StringUtil.isEmpty(contentType) || MIMETYPE_UNKNOWN.equalsIgnoreCase(contentType)) {
              String fileExt = MIME.getFileExtension(parameters.get("FileName"));
              contentType = MIME.getMIMETypeFromExtension(fileExt);
            }
            Content content = new com.ibm.sbt.services.client.ClientService.ContentStream(uploadedFile.getName(), uploadedFileContent, uploadedFile.getSize(), contentType);         
            Map<String, String> headers = createHeaders();           
            headers.put("Content-Type", contentType);
            xhr(request, response, url.getPath(), params, headers, content, getFormat());
          }
        } else if (smethod.equalsIgnoreCase("GET")) {
          xhr(request, response, requestURI, new HashMap<String, String[]>(), new HashMap<String, String>(), null, ClientService.FORMAT_INPUTSTREAM);

        }
      }
    } catch (Exception e) {
      if (e instanceof ClientServicesException) {
        writeErrorResponse(((ClientServicesException) e).getResponseStatusCode(), "Unexpected Exception", new String[] { "exception" }, new String[] { e.toString() }, response, request);
      } else {
        writeErrorResponse("Unexpected Exception", new String[] { "exception" }, new String[] { e.toString() }, response, request);
      }
    } finally {
      termProxy(request, response);       
    }
  }

  protected abstract Handler getFormat()

  protected abstract Map<String, String> createHeaders();

  protected abstract Content getFileContent(File file, long length, String name);

  private boolean addParameter(StringBuilder b, boolean first, String name, String value) throws ClientServicesException {
    try {
      if (value != null) {
        b.append(first ? '?' : '&');
        b.append(name);
        b.append('=');
        b.append(URLEncoder.encode(value, "UTF-8"));
        return false;
      }
      return first;
    } catch (UnsupportedEncodingException ex) {
      throw new ClientServicesException(ex);
    }
  }

  private String composeRequestUrl(Args args, Map<String, String[]> parameters) throws ClientServicesException {
    // Compose the URL
    StringBuilder b = new StringBuilder(256);
    String baseUrl = endpoint.getUrl();
    String serviceUrl = args.getServiceUrl();
    String url = PathUtil.concat(baseUrl, serviceUrl, '/');
    if (url.charAt(url.length() - 1) == '/') {
      url = url.substring(0, url.length() - 1);
    }
    b.append(url);

    if (parameters != null) {
      boolean first = true;
      for (Map.Entry<String, String[]> e : parameters.entrySet()) {
        String name = e.getKey();
        if (StringUtil.isNotEmpty(name)) {
          String[] values = e.getValue();
          for (String value : values) {
            first = addParameter(b, first, name, value);
          }
        }
      }
    }
    return b.toString();
  }

  protected void forceAuthentication(Args args) throws ClientServicesException {
    if (endpoint != null) {
      endpoint.authenticate(true);
    } else {
      throw new NoAccessSignal(StringUtil.format("Authorization needed for service {0}", getUrlPath(args)));
    }
  }

  protected String getBaseUrl() {
    if (endpoint != null) {
      return endpoint.getUrl();
    }
    return null;
  }

  protected String getUrlPath(Args args) {
    String baseUrl = getBaseUrl();
    String serviceUrl = args.getServiceUrl();
    return PathUtil.concat(baseUrl, serviceUrl, '/');
  }

  private void xhr(HttpServletRequest request, HttpServletResponse response, String serviceUrl, Map<String, String[]> parameters, Map<String, String> headers, Content content, Handler format)
      throws ClientServicesException, ClientProtocolException, IOException, ServletException, URISyntaxException {
    Args args = new Args();
    args.setServiceUrl(serviceUrl);
    args.setHandler(format);
    args.setHeaders(headers);

    String smethod = request.getMethod();
    HttpRequestBase method = createMethod(smethod, new URI(composeRequestUrl(args, parameters)), request);
    DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
    if (endpoint.isForceTrustSSLCertificate()) {
      defaultHttpClient = SSLUtil.wrapHttpClient(defaultHttpClient);
    }
    if (endpoint.isForceDisableExpectedContinue()) {
      defaultHttpClient.getParams().setParameter(
          CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
    }
    endpoint.initialize(defaultHttpClient);

    for (Map.Entry<String, String> e : args.getHeaders().entrySet()) {
      String headerName = e.getKey();
      String headerValue = e.getValue();
      method.addHeader(headerName, headerValue);
    }
    if (content != null) {
      content.initRequestContent(defaultHttpClient, method, args);
    }
    endpoint.updateHeaders(defaultHttpClient, method);
    //getting to interface to avoid
    //java.lang.NoSuchMethodError: org/apache/http/impl/client/DefaultHttpClient.execute(Lorg/apache/http/client/methods/HttpUriRequest;)Lorg/apache/http/client/methods/CloseableHttpResponse;
    //when run from different version of HttpClient (that's why it is deprecated)
    HttpClient httpClient = defaultHttpClient;

    HttpResponse clientResponse = httpClient.execute(method);

    if ("get".equalsIgnoreCase(smethod) && (clientResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_UNAUTHORIZED)
        || (endpoint != null && endpoint.getAuthenticationErrorCode() == clientResponse.getStatusLine().getStatusCode())) {
      forceAuthentication(args);
    }
    prepareResponse(method, request, response, clientResponse, true);
  }
}
TOP

Related Classes of com.ibm.sbt.service.basic.AbstractFileProxyService

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.