se.inera.certificate.proxy.mappings.remote.RemoteDispatcherTest.java Source code

Java tutorial

Introduction

Here is the source code for se.inera.certificate.proxy.mappings.remote.RemoteDispatcherTest.java

Source

/**
 * Copyright (C) 2013 Inera AB (http://www.inera.se)
 *
 * This file is part of Inera Certificate Proxy (http://code.google.com/p/inera-certificate-proxy).
 *
 * Inera Certificate Proxy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Inera Certificate Proxy is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package se.inera.certificate.proxy.mappings.remote;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletTester;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import se.inera.certificate.proxy.filter.HeaderProvider;
import se.inera.certificate.proxy.filter.ProxyFilter;
import se.inera.certificate.proxy.mappings.Mapper;
import se.inera.certificate.proxy.mappings.TestServer;

import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;
import java.io.StringReader;
import java.net.ServerSocket;
import java.util.EnumSet;
import java.util.Map;

import static com.google.common.collect.Maps.newHashMap;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

/**
 *
 */
@RunWith(MockitoJUnitRunner.class)
public class RemoteDispatcherTest {

    @Mock
    HeaderProvider headerProvider;

    private String moduleHostUri;

    @Before
    public void before() throws Exception {
        ServerSocket ss = new ServerSocket(0);
        int serverPort = ss.getLocalPort();
        ss.close();

        TestServer server = new TestServer();
        server.start(serverPort);

        moduleHostUri = "http://localhost:" + serverPort;
    }

    @Test
    public void testGetRoot() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/");

        tester.addFilter(filterWithMapper("/app1/path", "/app1", "/module.webapp"), "/*",
                EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setMethod("GET");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));
        assertEquals("Status code not 200!", 200, resp.getStatus());

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("http://proxy.host/app1/path", rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("/", rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals(moduleHostUri + "/module.webapp/path", rh.requestUrl);
    }

    @Test
    public void testGet() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/webapp1");

        tester.addFilter(filterWithMapper("/app1/path", "/app1", "/module.webapp"), "/*",
                EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setMethod("GET");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/webapp1/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));
        assertEquals("Status code not 200!", 200, resp.getStatus());

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("http://proxy.host/webapp1/app1/path", rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("/webapp1", rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals(moduleHostUri + "/module.webapp/path", rh.requestUrl);
    }

    @Test
    public void testGetAditionalHeaders() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/webapp1");

        FilterHolder filterHolder = filterWithMapper("/app1/path", "/app1", "/module.webapp");
        ((ProxyFilter) filterHolder.getFilter()).setHeaderProvider(headerProvider);
        ImmutableMap<String, String> headers = ImmutableMap.of("X-Header1", "headerValue1");
        when(headerProvider.getHeaders(any(HttpServletRequest.class))).thenReturn(headers);

        tester.addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setMethod("GET");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/webapp1/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));
        assertEquals("Status code not 200!", 200, resp.getStatus());

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("http://proxy.host/webapp1/app1/path", rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("/webapp1", rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals("headerValue1", rh.requestHeaders.get("X-Header1"));
        assertEquals(moduleHostUri + "/module.webapp/path", rh.requestUrl);
    }

    @Test
    public void testPost() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/webapp1");

        tester.addFilter(filterWithMapper("/app1/path", "/app1", "/module.webapp"), "/*",
                EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setMethod("POST");
        req.setContent("This is some content!!");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/webapp1/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("Unexpected X-Proxy-Original-Url", "http://proxy.host/webapp1/app1/path",
                rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("Unexpected X-Proxy-Original-Servlet-ContextPath", "/webapp1",
                rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals("Unexpected Request URL", moduleHostUri + "/module.webapp/path", rh.requestUrl);
        assertEquals("This is some content!!", rh.requestContent);
    }

    @Test
    public void testPut() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/webapp1");

        tester.addFilter(filterWithMapper("/app1/path", "/app1", "/module.webapp"), "/*",
                EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setMethod("PUT");
        req.setContent("This is some content!!");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/webapp1/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("Unexpected X-Proxy-Original-Url", "http://proxy.host/webapp1/app1/path",
                rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("Unexpected X-Proxy-Original-Servlet-ContextPath", "/webapp1",
                rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals("Unexpected Request URL", moduleHostUri + "/module.webapp/path", rh.requestUrl);
        assertEquals("This is some content!!", rh.requestContent);
    }

    @Test
    public void testOptions() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/webapp1");

        tester.addFilter(filterWithMapper("/app1/path", "/app1", "/module.webapp"), "/*",
                EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setMethod("OPTIONS");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/webapp1/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("Unexpected X-Proxy-Original-Url", "http://proxy.host/webapp1/app1/path",
                rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("Unexpected X-Proxy-Original-Servlet-ContextPath", "/webapp1",
                rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals("Unexpected Request URL", moduleHostUri + "/module.webapp/path", rh.requestUrl);
    }

    @Test
    public void testHeaderOverride() throws Exception {
        ServletTester tester = new ServletTester();
        tester.setContextPath("/webapp1");

        tester.addFilter(filterWithMapper("/app1/path", "/app1", "/module.webapp"), "/*",
                EnumSet.of(DispatcherType.REQUEST));
        tester.addServlet(DefaultServlet.class, "/*");
        tester.start();

        HttpTester.Request req = HttpTester.newRequest();
        req.setHeader("X-Proxy-Original-Url", "BlaBla");
        req.setHeader("X-Proxy-Original-Servlet-ContextPath", "BlaBla");
        req.setMethod("GET");
        req.setHeader("HOST", "proxy.host");
        req.setURI("/webapp1/app1/path");

        HttpTester.Response resp = HttpTester.parseResponse(tester.getResponses(req.generate()));
        assertEquals("Status code not 200!", 200, resp.getStatus());

        ResponseHelper rh = new ResponseHelper(resp.getContent());

        assertEquals("http://proxy.host/webapp1/app1/path", rh.requestHeaders.get("X-Proxy-Original-Url"));
        assertEquals("/webapp1", rh.requestHeaders.get("X-Proxy-Original-Servlet-ContextPath"));
        assertEquals(moduleHostUri + "/module.webapp/path", rh.requestUrl);
    }

    private FilterHolder filterWithMapper(String expected, String context, String hostPath) {
        FilterHolder filterHolder = new FilterHolder();

        ProxyFilter filter = new ProxyFilter();
        filter.setProxyKey("ABCDEFGHIJKLMN12345");
        Mapper mapper = Mockito.mock(Mapper.class);
        when(mapper.getMapping(expected)).thenReturn(new RemoteMapping(context, moduleHostUri + hostPath));
        filter.setMapper(mapper);
        filterHolder.setFilter(filter);
        return filterHolder;
    }

    private static class ResponseHelper {
        final String requestUrl;
        final Map<String, String> requestHeaders;
        final String requestContent;

        private ResponseHelper(String responseContent) {
            LineIterator li = IOUtils.lineIterator(new StringReader(responseContent));
            requestUrl = li.nextLine();
            requestHeaders = newHashMap();
            for (String header : StringUtils.split(li.nextLine(), ',')) {
                String[] keyValue = StringUtils.split(header, "||");

                requestHeaders.put(keyValue[0], keyValue[1]);
            }
            String tmpStr = "";
            for (String line : ImmutableList.copyOf(li)) {
                if (!StringUtils.startsWithIgnoreCase(line, "---")) {
                    tmpStr += line;
                }
            }
            requestContent = tmpStr;
        }
    }
}