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 extends HttpServlet> 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 extends Filter> 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();
}
}