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

de.micromata.genome.tpsb.httpmockup.testbuilder.ServletContextTestBuilder Maven / Gradle / Ivy

The newest version!
//
// Copyright (C) 2010-2016 Micromata GmbH
//
// Licensed 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 de.micromata.genome.tpsb.httpmockup.testbuilder;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import de.micromata.genome.tpsb.CommonTestBuilder;
import de.micromata.genome.tpsb.annotations.TpsbBuilder;
import de.micromata.genome.tpsb.annotations.TpsbIgnore;
import de.micromata.genome.tpsb.httpmockup.HttpClientRequestAcceptor;
import de.micromata.genome.tpsb.httpmockup.MockFilterMapDef.FilterDispatchFlags;
import de.micromata.genome.tpsb.httpmockup.MockHttpServletRequest;
import de.micromata.genome.tpsb.httpmockup.MockHttpServletResponse;
import de.micromata.genome.tpsb.httpmockup.MockServletContext;
import de.micromata.genome.tpsb.httpmockup.MockupHttpRequestUtils;
import de.micromata.genome.tpsb.httpmockup.RequestAcceptor;
import de.micromata.genome.util.types.Pair;

/**
 * Creates an execution framework for servlets.
 * 
 * One servlet context currently can only have one servlet registered, but multiple filterfs.
 * 
 * See also https://team.micromata.de/confluence/display/genome/Modul+tpsb-httpmockup
 * 
 * @author Roger Rene Kommer ([email protected])
 * 
 */
@TpsbBuilder
public class ServletContextTestBuilder> extends CommonTestBuilder
{
  protected static final Logger LOG = Logger.getLogger(ServletContextTestBuilder.class);
  protected MockServletContext servletContext = new MockServletContext("unittest");

  protected RequestAcceptor acceptor = servletContext;

  protected MockHttpServletRequest httpRequest = new MockHttpServletRequest(servletContext);

  protected MockHttpServletResponse httpResponse;
  protected int reqResponseCounter = 0;
  private boolean writeRequestResponseLog = false;
  private String requestResponseLogBaseDir = "target";
  private String requestResponseLogBaseName = "";
  private boolean followRedirects = false;
  private boolean storeCookies = true;
  private Map cookies = new HashMap<>();

  protected List> keyValuesToPairList(String... initParams)
  {
    if ((initParams.length % 2) != 0) {
      throw new IllegalArgumentException("initParams has to be even (key, values)");
    }
    List> ret = new ArrayList>();
    for (int i = 0; i < initParams.length; ++i) {
      ret.add(Pair.make(initParams[i], initParams[i + 1]));
      ++i;
    }
    return ret;
  }

  /**
   * Register the servlet all requests will dispatched.
   * 
   * @param servletClass  the class of the servlet to register
   * @param name the name of the servlet to register
   * @param initParams the initial parameters of the servlet
   * @return the servlet which was registered
   */
  public T registerServlet(String name, String path, Class servletClass, String... initParams)
  {
    Map ips = new HashMap();

    for (Pair me : keyValuesToPairList(initParams)) {
      ips.put(me.getFirst(), me.getSecond());
    }
    servletContext.addServlet(name, servletClass, ips);
    servletContext.addServletMapping(name, path);
    return getBuilder();
  }

  public T keepSession(boolean keep)
  {
    servletContext.keepSession(keep);
    return getBuilder();
  }

  /**
   * Register a servlet, all requests will passed through.
   * 
   * @param filterClass the class of the filter to register
   * @param name the name of the filter to register
   * @param initParams the parameter to initialize the filter with
   * @return the registered filter
   */
  public T registerFilter(String name, String path, Class filterClass, String... initParams)
  {
    Map ips = new HashMap();
    for (Pair me : keyValuesToPairList(initParams)) {
      ips.put(me.getFirst(), me.getSecond());
    }

    servletContext.addFilter(name, filterClass, ips);
    servletContext.addFilterMapping(name, path, FilterDispatchFlags.REQUEST.getFlags());
    return getBuilder();
  }

  /**
   * Creates an fresh POST request.
   * 
   * @param urlParams the url params as key value list.
   * @return the builder
   */
  public T createNewPostRequest(String... urlParams)
  {

    httpRequest = new MockHttpServletRequest(servletContext);
    StringBuilder sb = new StringBuilder();
    for (Pair me : keyValuesToPairList(urlParams)) {
      if (sb.length() > 0) {
        sb.append("&");
      }
      try {
        sb.append(URLEncoder.encode(me.getFirst(), CharEncoding.UTF_8)).append("=")
            .append(URLEncoder.encode(me.getSecond(), CharEncoding.UTF_8));
      } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
      }
    }
    httpRequest.setQueryString(sb.toString());
    return getBuilder();
  }

  public T createNewGetRequest(String url)
  {
    httpRequest = new MockHttpServletRequest(servletContext);
    httpRequest.setMethod("GET");
    MockupHttpRequestUtils.parseRequestUrlToRequest(httpRequest, url);
    return getBuilder();
  }

  /**
   * If remote url is set, HttpClient will be used to send requests.
   * 
   * @param baseUrl base url without servlet path.
   * @return the builder itstelf
   */
  public T setRemoteUrl(String baseUrl)
  {
    acceptor = new HttpClientRequestAcceptor(baseUrl);
    return getBuilder();
  }

  /**
   * sets the HTTP method.
   * 
   * @param method the method to request
   * @return the builder
   */
  public T setRequestMethod(String method)
  {
    httpRequest.setMethod(method);
    return getBuilder();
  }

  public T dumpResponse()
  {
    System.out.println(httpResponse.toString());
    return getBuilder();
  }

  /**
   * Add a request header.
   * 
   * @param key the key to add to the header
   * @param value the value to add to the header
   * @return the builder
   */
  public T addRequestHeader(String key, String value)
  {
    httpRequest.addHeader(key, value);
    return getBuilder();
  }

  /**
   * Sets the request data as utf-8 bytes.
   * 
   * @param data the data to set on the reuest
   * @return the builder
   */
  public T setRequestData(String data)
  {
    httpRequest.setRequestData(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(data));
    return getBuilder();
  }

  /**
   * Sets the request data as utf-8 bytes.
   * 
   * @param data the data to set
   * @return the builder itself
   */
  @TpsbIgnore
  public T setRequestData(byte[] data)
  {
    httpRequest.setRequestData(data);
    return getBuilder();
  }

  public T setContextPath(String contextPath)
  {
    servletContext.setContextPath(contextPath);
    return getBuilder();
  }

  /**
   * Executes the Http request and store response in httpResponse.
   * 
   * @return the builder
   */
  public T executeServletRequest()
  {
    executeServletIntern(0);

    return getBuilder();
  }

  private void checkRedirect(int recCount)
  {
    if (followRedirects == false || recCount > 3) {
      return;
    }
    if (httpResponse.getStatus() != 302) {
      return;
    }
    String loc = httpResponse.getHeader("Location");
    if (StringUtils.isBlank(loc) == true) {
      return;
    }
    createNewGetRequest(loc);
    executeServletIntern(++recCount);
  }

  protected void executeServletIntern(int recCount)
  {
    try {
      applyCookies();
      httpResponse = new MockHttpServletResponse();
      ++reqResponseCounter;
      writeRequestToLog();
      acceptor.acceptRequest(httpRequest, httpResponse);
      storeCookies();
      writeResponseToLog();
      checkRedirect(recCount);
    } catch (RuntimeException ex) {
      ex.printStackTrace();
      throw ex;
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }

  private void applyCookies()
  {

    if (storeCookies == false) {
      return;
    }
    httpRequest.setCookies(cookies.values().toArray(new Cookie[] {}));
  }

  private void storeCookies()
  {
    if (storeCookies == false) {
      return;
    }
    Cookie[] cooks = httpResponse.getCookies();
    if (cooks == null) {
      return;
    }
    for (Cookie c : cooks) {
      cookies.put(c.getName(), c);
    }
  }

  private boolean prepareForLog()
  {
    if (writeRequestResponseLog == false) {
      return false;
    }
    File f = new File(this.requestResponseLogBaseDir);
    if (f.exists() == false) {
      return f.mkdirs();
    }
    return true;

  }

  private void writeResponseToLog()
  {
    if (prepareForLog() == false) {
      return;
    }
    String filen = "" + reqResponseCounter + "_" + requestResponseLogBaseName + "_Response.txt";
    Path p = Paths.get(getRequestResponseLogBaseDir(), filen);
    try {
      FileUtils.write(p.toFile(), this.httpResponse.toString());
    } catch (IOException e) {
      LOG.error("Cannot write response log: " + e.getMessage(), e);
    }
  }

  private void writeRequestToLog()
  {
    if (prepareForLog() == false) {
      return;
    }
    String filen = "" + reqResponseCounter + "_" + requestResponseLogBaseName + "_Request.txt";
    Path p = Paths.get(getRequestResponseLogBaseDir(), filen);
    try {
      FileUtils.write(p.toFile(), this.httpRequest.toString());
    } catch (IOException e) {
      LOG.error("Cannot write Request log: " + e.getMessage(), e);
    }
  }

  /**
   * Check if http status in response is given.
   * 
   * @param status the status of the reponse
   * @return the builder
   */
  public T validateResponseStatus(int status)
  {
    if (httpResponse.getStatus() != status) {
      fail("Expect http status " + status + "; got " + httpResponse.getStatus());
    }
    return getBuilder();
  }

  /**
   * Delete session associated.
   * 
   * @return the builder
   */
  public T destroySession()
  {
    servletContext.setSession(null);
    return getBuilder();
  }

  @TpsbIgnore
  public byte[] getResponseData()
  {
    return httpResponse.getOutputBytes();
  }

  public MockServletContext getServletContext()
  {
    return servletContext;
  }

  public void setServletContext(MockServletContext servletContext)
  {
    this.servletContext = servletContext;
  }

  public MockHttpServletRequest getHttpRequest()
  {
    return httpRequest;
  }

  public void setHttpRequest(MockHttpServletRequest httpRequest)
  {
    this.httpRequest = httpRequest;
  }

  public MockHttpServletResponse getHttpResponse()
  {
    return httpResponse;
  }

  public void setHttpResponse(MockHttpServletResponse httpResponse)
  {
    this.httpResponse = httpResponse;
  }

  public boolean isWriteRequestResponseLog()
  {
    return writeRequestResponseLog;
  }

  public T setWriteRequestResponseLog(boolean writeRequestResponseLog)
  {
    this.writeRequestResponseLog = writeRequestResponseLog;
    return getBuilder();
  }

  public String getRequestResponseLogBaseDir()
  {
    return requestResponseLogBaseDir;
  }

  public T setRequestResponseLogBaseDir(String requestResponseLogBaseDir)
  {
    this.requestResponseLogBaseDir = requestResponseLogBaseDir;
    return getBuilder();
  }

  public String getRequestResponseLogBaseName()
  {
    return requestResponseLogBaseName;
  }

  public T setRequestResponseLogBaseName(String requestResponseLogBaseName)
  {
    this.requestResponseLogBaseName = requestResponseLogBaseName;
    return getBuilder();
  }

  public boolean isFollowRedirects()
  {
    return followRedirects;
  }

  public T setFollowRedirects(boolean followRedirects)
  {
    this.followRedirects = followRedirects;
    return getBuilder();
  }

  public boolean isStoreCookies()
  {
    return storeCookies;
  }

  public T setStoreCookies(boolean storeCookies)
  {
    this.storeCookies = storeCookies;
    return getBuilder();
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy