org.apache.hadoop.test.mock.MockRequestMatcher.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.test.mock.MockRequestMatcher.java

Source

/**
 * 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.test.mock;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.xmlmatchers.XmlMatchers.isEquivalentTo;
import static org.xmlmatchers.transform.XmlConverters.the;
import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;

public class MockRequestMatcher {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    private String from;
    private MockResponseProvider response;
    private Set<String> methods = null;
    private String pathInfo = null;
    private String requestURL = null;
    Map<String, String> headers = null;
    Set<Cookie> cookies = null;
    private Map<String, Object> attributes = null;
    private Map<String, String> queryParams = null;
    private String contentType = null;
    private String characterEncoding = null;
    private Integer contentLength = null;
    private byte[] entity = null;
    private Map<String, String[]> formParams = null;

    public MockRequestMatcher(MockResponseProvider response) {
        this.response = response;
    }

    public MockResponseProvider respond() {
        return response;
    }

    public MockRequestMatcher from(String from) {
        this.from = from;
        return this;
    }

    public MockRequestMatcher method(String... methods) {
        if (this.methods == null) {
            this.methods = new HashSet<String>();
        }
        if (methods != null) {
            for (String method : methods) {
                this.methods.add(method);
            }
        }
        return this;
    }

    public MockRequestMatcher pathInfo(String pathInfo) {
        this.pathInfo = pathInfo;
        return this;
    }

    public MockRequestMatcher requestUrl(String requestUrl) {
        this.requestURL = requestUrl;
        return this;
    }

    public MockRequestMatcher header(String name, String value) {
        if (headers == null) {
            headers = new HashMap<String, String>();
        }
        headers.put(name, value);
        return this;
    }

    public MockRequestMatcher cookie(Cookie cookie) {
        if (cookies == null) {
            cookies = new HashSet<Cookie>();
        }
        cookies.add(cookie);
        return this;
    }

    public MockRequestMatcher attribute(String name, Object value) {
        if (this.attributes == null) {
            this.attributes = new HashMap<String, Object>();
        }
        attributes.put(name, value);
        return this;
    }

    public MockRequestMatcher queryParam(String name, String value) {
        if (this.queryParams == null) {
            this.queryParams = new HashMap<String, String>();
        }
        queryParams.put(name, value);
        return this;
    }

    public MockRequestMatcher formParam(String name, String... values) {
        if (entity != null) {
            throw new IllegalStateException("Entity already specified.");
        }
        if (formParams == null) {
            formParams = new HashMap<String, String[]>();
        }
        String[] currentValues = formParams.get(name);
        if (currentValues == null) {
            currentValues = values;
        } else if (values != null) {
            currentValues = ArrayUtils.addAll(currentValues, values);
        }
        formParams.put(name, currentValues);
        return this;
    }

    public MockRequestMatcher content(String string, Charset charset) {
        content(string.getBytes(charset));
        return this;
    }

    public MockRequestMatcher content(byte[] entity) {
        if (formParams != null) {
            throw new IllegalStateException("Form params already specified.");
        }
        this.entity = entity;
        return this;
    }

    public MockRequestMatcher content(URL url) throws IOException {
        content(url.openStream());
        return this;
    }

    public MockRequestMatcher content(InputStream stream) throws IOException {
        content(IOUtils.toByteArray(stream));
        return this;
    }

    public MockRequestMatcher contentType(String contentType) {
        this.contentType = contentType;
        return this;
    }

    public MockRequestMatcher contentLength(int length) {
        this.contentLength = length;
        return this;
    }

    public MockRequestMatcher characterEncoding(String charset) {
        this.characterEncoding = charset;
        return this;
    }

    public void match(HttpServletRequest request) throws IOException {
        if (methods != null) {
            assertThat(
                    "Request " + request.getMethod() + " " + request.getRequestURL()
                            + " is not using one of the expected HTTP methods",
                    methods, hasItem(request.getMethod()));
        }
        if (pathInfo != null) {
            assertThat("Request " + request.getMethod() + " " + request.getRequestURL()
                    + " does not have the expected pathInfo", request.getPathInfo(), is(pathInfo));
        }
        if (requestURL != null) {
            assertThat(
                    "Request " + request.getMethod() + " " + request.getRequestURL()
                            + " does not have the expected requestURL",
                    request.getRequestURL().toString(), is(requestURL));
        }
        if (headers != null) {
            for (String name : headers.keySet()) {
                assertThat(
                        "Request " + request.getMethod() + " " + request.getRequestURL()
                                + " does not have the expected value for header " + name,
                        request.getHeader(name), is(headers.get(name)));
            }
        }
        if (cookies != null) {
            List<Cookie> requestCookies = Arrays.asList(request.getCookies());
            for (Cookie cookie : cookies) {
                assertThat("Request " + request.getMethod() + " " + request.getRequestURL()
                        + " does not have the expected cookie " + cookie, requestCookies, hasItem(cookie));
            }
        }
        if (contentType != null) {
            String[] requestContentType = request.getContentType().split(";", 2);
            assertThat("Request " + request.getMethod() + " " + request.getRequestURL()
                    + " does not have the expected content type", requestContentType[0], is(contentType));
        }
        if (characterEncoding != null) {
            assertThat(
                    "Request " + request.getMethod() + " " + request.getRequestURL()
                            + " does not have the expected character encoding",
                    request.getCharacterEncoding(), equalToIgnoringCase(characterEncoding));
        }
        if (contentLength != null) {
            assertThat(
                    "Request " + request.getMethod() + " " + request.getRequestURL()
                            + " does not have the expected content length",
                    request.getContentLength(), is(contentLength));
        }
        if (attributes != null) {
            for (String name : attributes.keySet()) {
                assertThat("Request " + request.getMethod() + " " + request.getRequestURL()
                        + " is missing attribute '" + name + "'", request.getAttribute(name), notNullValue());
                assertThat(
                        "Request " + request.getMethod() + " " + request.getRequestURL()
                                + " has wrong value for attribute '" + name + "'",
                        request.getAttribute(name), is(request.getAttribute(name)));
            }
        }
        // Note: Cannot use any of the expect.getParameter*() methods because they will read the
        // body and we don't want that to happen.
        if (queryParams != null) {
            String queryString = request.getQueryString();
            Map<String, String[]> requestParams = parseQueryString(queryString == null ? "" : queryString);
            for (String name : queryParams.keySet()) {
                String[] values = requestParams.get(name);
                assertThat("Request " + request.getMethod() + " " + request.getRequestURL() + " query string "
                        + queryString + " is missing parameter '" + name + "'", values, notNullValue());
                assertThat(
                        "Request " + request.getMethod() + " " + request.getRequestURL() + " query string "
                                + queryString + " is missing a value for parameter '" + name + "'",
                        Arrays.asList(values), hasItem(queryParams.get(name)));
            }
        }
        if (formParams != null) {
            String paramString = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            Map<String, String[]> requestParams = parseQueryString(paramString == null ? "" : paramString);
            for (String name : formParams.keySet()) {
                String[] actualValues = requestParams.get(name);
                assertThat(
                        "Request " + request.getMethod() + " " + request.getRequestURL() + " form params "
                                + paramString + " is missing parameter '" + name + "'",
                        actualValues, notNullValue());
                String[] expectedValues = formParams.get(name);
                for (String expectedValue : expectedValues) {
                    assertThat("Request " + request.getMethod() + " " + request.getRequestURL() + " form params "
                            + paramString + " is missing a value " + expectedValue + " for parameter '" + name
                            + "'", Arrays.asList(actualValues), hasItem(expectedValue));
                }
            }
        }
        if (entity != null) {
            if (contentType != null && contentType.endsWith("/xml")) {
                String expectEncoding = characterEncoding;
                String expect = new String(entity, (expectEncoding == null ? UTF8.name() : expectEncoding));
                String actualEncoding = request.getCharacterEncoding();
                String actual = IOUtils.toString(request.getInputStream(),
                        actualEncoding == null ? UTF8.name() : actualEncoding);
                assertThat(the(actual), isEquivalentTo(the(expect)));
            } else if (contentType != null && contentType.endsWith("/json")) {
                String expectEncoding = characterEncoding;
                String expect = new String(entity, (expectEncoding == null ? UTF8.name() : expectEncoding));
                String actualEncoding = request.getCharacterEncoding();
                String actual = IOUtils.toString(request.getInputStream(),
                        actualEncoding == null ? UTF8.name() : actualEncoding);
                //        System.out.println( "EXPECT=" + expect );
                //        System.out.println( "ACTUAL=" + actual );
                assertThat(actual, sameJSONAs(expect));
            } else if (characterEncoding == null || request.getCharacterEncoding() == null) {
                byte[] bytes = IOUtils.toByteArray(request.getInputStream());
                assertThat("Request " + request.getMethod() + " " + request.getRequestURL()
                        + " content does not match the expected content", bytes, is(entity));
            } else {
                String expect = new String(entity, characterEncoding);
                String actual = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
                assertThat("Request " + request.getMethod() + " " + request.getRequestURL()
                        + " content does not match the expected content", actual, is(expect));
            }
        }
    }

    public String toString() {
        return "from=" + from + ", pathInfo=" + pathInfo;
    }

    // Separate method to minimally scope the depreciation suppression.
    @SuppressWarnings("deprecation")
    private static Map<String, String[]> parseQueryString(String queryString) {
        return javax.servlet.http.HttpUtils.parseQueryString(queryString);
    }

}