org.geowebcache.jetty.RestIntegrationTest.java Source code

Java tutorial

Introduction

Here is the source code for org.geowebcache.jetty.RestIntegrationTest.java

Source

/**
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  This program 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 Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Kevin Smith, Boundless
 * @author David Vick, Boundless, 2017
 * @author Torben Barsballe, Boundless 2018
 */

package org.geowebcache.jetty;

import junit.framework.TestCase;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;
import org.custommonkey.xmlunit.XMLUnit;
import org.geowebcache.util.FileMatchers;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.http.MediaType;
import org.springframework.util.xml.SimpleNamespaceContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Arrays;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

/**
 * Integration test for the REST API in a full GWC instance
 */
public class RestIntegrationTest {

    @ClassRule
    static public JettyRule jetty = new JettyRule();

    @Rule
    public HttpClientRule anonymous = HttpClientRule.anonymous();
    @Rule
    public HttpClientRule admin = new HttpClientRule("geowebcache", "secured", "admin");
    @Rule
    public HttpClientRule badPassword = new HttpClientRule("geowebcache", "notTheRightPassword", "badPassword");
    @Rule
    public HttpClientRule notAUser = new HttpClientRule("notARealUser", "somePassword", "notAUser");

    @ClassRule
    static public TemporaryFolder temp = new TemporaryFolder();

    private SimpleNamespaceContext nsContext;

    @Before
    public void setUp() throws Exception {
        nsContext = new SimpleNamespaceContext();
        nsContext.bindNamespaceUri("atom", "http://www.w3.org/2005/Atom");
        nsContext.bindNamespaceUri("wmts", "http://www.opengis.net/wmts/1.0");
        nsContext.bindNamespaceUri("ows", "http://www.opengis.net/ows/1.1");

        //Reset Server configuration
        final String globalUpdate = "<global>\n" + "  <serviceInformation>\n" + "    <title>GeoWebCache</title>\n"
                + "    <description>GeoWebCache is an advanced tile cache for WMS servers. It supports a large variety of protocols and\n"
                + "      formats, including WMS-C, WMTS, KML, Google Maps and Virtual Earth.</description>\n"
                + "    <keywords>\n" + "      <string>WMS</string>\n" + "      <string>WFS</string>\n"
                + "      <string>WMTS</string>\n" + "      <string>GEOWEBCACHE</string>\n" + "    </keywords>\n"
                + "    <serviceProvider>\n" + "      <providerName>John Smith inc.</providerName>\n"
                + "      <providerSite>http://www.example.com/</providerSite>\n" + "      <serviceContact>\n"
                + "        <individualName>John Smith</individualName>\n"
                + "        <positionName>Geospatial Expert</positionName>\n"
                + "        <addressType>Work</addressType>\n"
                + "        <addressStreet>1 Bumpy St.</addressStreet>\n"
                + "        <addressCity>Hobart</addressCity>\n"
                + "        <addressAdministrativeArea>TAS</addressAdministrativeArea>\n"
                + "        <addressPostalCode>7005</addressPostalCode>\n"
                + "        <addressCountry>Australia</addressCountry>\n"
                + "        <phoneNumber>+61 3 0000 0000</phoneNumber>\n"
                + "        <faxNumber>+61 3 0000 0001</faxNumber>\n"
                + "        <addressEmail>john.smith@example.com</addressEmail>\n" + "      </serviceContact>\n"
                + "    </serviceProvider>\n" + "    <fees>NONE</fees>\n"
                + "    <accessConstraints>NONE</accessConstraints>\n" + "  </serviceInformation>\n"
                + "  <runtimeStatsEnabled>true</runtimeStatsEnabled>\n"
                + "  <wmtsCiteCompliant>false</wmtsCiteCompliant>\n" + "  <backendTimeout>120</backendTimeout>\n"
                + "</global>";

        CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/global"), admin.getClient(),
                globalUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();
    }

    Matcher<Node> hasXPath(final String xpathExpr, final Matcher<String> matcher) {
        return Matchers.hasXPath(xpathExpr, nsContext, matcher);

    }

    Matcher<Node> hasXPath(final String xpathExpr) {
        return Matchers.hasXPath(xpathExpr, nsContext);
    }

    /* General REST API Tests ********************************************************************/

    @Test
    public void testGetLogo() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/web/geowebcache_logo.png"),
                anonymous.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testGetCss() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/web/gwc.css"),
                anonymous.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testGetBadWebResource() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/web/thisDoesNotExist"),
                anonymous.getClient());
        TestCase.assertEquals(404, response.getStatusLine().getStatusCode());
    }

    /* ServerController Integration Tests ********************************************************/

    @Test
    public void testGetGlobal() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/global.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("/global/serviceInformation/title", equalTo("GeoWebCache")));
        assertThat(doc, hasXPath("normalize-space(/global/serviceInformation/description)",
                equalTo("GeoWebCache is an advanced tile cache for WMS servers. It supports a large variety of "
                        + "protocols and formats, including WMS-C, WMTS, KML, Google Maps and Virtual Earth.")));
        assertThat(doc, hasXPath("count(/global/serviceInformation/keywords/string)", equalTo("4")));
        assertThat(doc,
                hasXPath("/global/serviceInformation/serviceProvider/providerName", equalTo("John Smith inc.")));
        assertThat(doc, hasXPath("/global/serviceInformation/serviceProvider/serviceContact/individualName",
                equalTo("John Smith")));
        assertThat(doc, hasXPath("/global/runtimeStatsEnabled", equalTo("true")));
        assertThat(doc, hasXPath("/global/wmtsCiteCompliant", equalTo("false")));
        assertThat(doc, hasXPath("/global/backendTimeout", equalTo("120")));
    }

    @Test
    public void testPutGlobal() throws Exception {
        final String globalUpdate = "<global>\n" + "  <serviceInformation>\n" + "    <title>GeoWebCache</title>\n"
                + "    <description>GeoWebCache is an advanced tile cache for WMS servers. It supports a large variety of protocols and\n"
                + "      formats, including WMS-C, WMTS, KML, Google Maps and Virtual Earth.</description>\n"
                + "    <keywords>\n" + "      <string>WMS</string>\n" + "      <string>WMTS</string>\n"
                + "      <string>GEOWEBCACHE</string>\n" + "    </keywords>\n" + "    <serviceProvider>\n"
                + "      <providerName>Jane Doe inc.</providerName>\n"
                + "      <providerSite>http://www.example.com/</providerSite>\n" + "      <serviceContact>\n"
                + "        <individualName>Jane Doe</individualName>\n"
                + "        <positionName>Geospatial Expert</positionName>\n"
                + "        <addressType>Work</addressType>\n"
                + "        <addressStreet>1 Bumpy St.</addressStreet>\n"
                + "        <addressCity>Hobart</addressCity>\n"
                + "        <addressAdministrativeArea>TAS</addressAdministrativeArea>\n"
                + "        <addressPostalCode>7005</addressPostalCode>\n"
                + "        <addressCountry>Australia</addressCountry>\n"
                + "        <phoneNumber>+61 3 0000 0000</phoneNumber>\n"
                + "        <faxNumber>+61 3 0000 0001</faxNumber>\n"
                + "        <addressEmail>jane.doe@example.com</addressEmail>\n" + "      </serviceContact>\n"
                + "    </serviceProvider>\n" + "    <fees>NONE</fees>\n"
                + "    <accessConstraints>NONE</accessConstraints>\n" + "  </serviceInformation>\n"
                + "  <runtimeStatsEnabled>false</runtimeStatsEnabled>\n"
                + "  <wmtsCiteCompliant>false</wmtsCiteCompliant>\n" + "  <backendTimeout>120</backendTimeout>\n"
                + "</global>";

        testGetGlobal();

        CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/global"), admin.getClient(),
                globalUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/global.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("/global/serviceInformation/title", equalTo("GeoWebCache")));
        assertThat(doc, hasXPath("normalize-space(/global/serviceInformation/description)",
                equalTo("GeoWebCache is an advanced tile cache for WMS servers. It supports a large variety of "
                        + "protocols and formats, including WMS-C, WMTS, KML, Google Maps and Virtual Earth.")));
        assertThat(doc, hasXPath("count(/global/serviceInformation/keywords/string)", equalTo("3")));
        assertThat(doc,
                hasXPath("/global/serviceInformation/serviceProvider/providerName", equalTo("Jane Doe inc.")));
        assertThat(doc, hasXPath("/global/serviceInformation/serviceProvider/serviceContact/individualName",
                equalTo("Jane Doe")));
        assertThat(doc, hasXPath("/global/runtimeStatsEnabled", equalTo("false")));
        assertThat(doc, hasXPath("/global/wmtsCiteCompliant", equalTo("false")));
        assertThat(doc, hasXPath("/global/backendTimeout", equalTo("120")));
    }

    @Test
    public void testPutGlobalRoundTrip() throws Exception {
        testGetGlobal();

        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/global.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        final String globalUpdate = getResponseEntity(response);

        response = handlePut(URI.create("/geowebcache/rest/global"), admin.getClient(), globalUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        //Round-tripping the XML should not cause changes
        testGetGlobal();

    }

    @Test
    public void testPutGlobalPartial() throws Exception {

        //Only PUT a partial object
        final String globalUpdate = "<global><backendTimeout>150</backendTimeout></global>";

        testGetGlobal();

        CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/global"), admin.getClient(),
                globalUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/global.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        //Verify only the PUT value has changed
        assertThat(doc, hasXPath("/global/serviceInformation/title", equalTo("GeoWebCache")));
        assertThat(doc, hasXPath("normalize-space(/global/serviceInformation/description)",
                equalTo("GeoWebCache is an advanced tile cache for WMS servers. It supports a large variety of "
                        + "protocols and formats, including WMS-C, WMTS, KML, Google Maps and Virtual Earth.")));
        assertThat(doc, hasXPath("count(/global/serviceInformation/keywords/string)", equalTo("4")));
        assertThat(doc,
                hasXPath("/global/serviceInformation/serviceProvider/providerName", equalTo("John Smith inc.")));
        assertThat(doc, hasXPath("/global/serviceInformation/serviceProvider/serviceContact/individualName",
                equalTo("John Smith")));
        assertThat(doc, hasXPath("/global/runtimeStatsEnabled", equalTo("true")));
        assertThat(doc, hasXPath("/global/wmtsCiteCompliant", equalTo("false")));
        assertThat(doc, hasXPath("/global/backendTimeout", equalTo("150")));
    }

    @Test
    public void testPutGlobalLock() throws Exception {

        final String globalUpdate = "<global><lockProvider>nioLock</lockProvider></global>";

        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/global.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        //Lock provider is null by default. If this is the case, it won't show up in the configuration
        assertThat(doc, hasXPath("count(/global/lockProvider)", equalTo("0")));

        response = handlePut(URI.create("/geowebcache/rest/global"), admin.getClient(), globalUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/global.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("/global/lockProvider", equalTo("nioLock")));
    }

    @Test
    public void testPutGlobalReadOnly() throws Exception {
        //PUT a value that is read-only
        final String globalUpdate = "<global><location>foobar</location></global>";

        CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/global"), admin.getClient(),
                globalUpdate);
        assertEquals(400, response.getStatusLine().getStatusCode());
        response.close();
    }

    /* TileLayerController Integration Tests *****************************************************/

    @Test
    public void testGetLayers() throws Exception {
        doGetXML("rest/layers.xml", admin.getClient(), equalTo(200), doc -> {

            assertThat(doc, hasXPath("/layers/layer[name/text()='img states']/atom:link/@href",
                    equalTo(jetty.getUri().resolve("/geowebcache/rest/layers/img%20states.xml").toString())));
            assertThat(doc, hasXPath("/layers/layer[name/text()='topp:states']/atom:link/@href",
                    equalTo(jetty.getUri().resolve("/geowebcache/rest/layers/topp:states.xml").toString())));
            assertThat(doc, hasXPath("/layers/layer[name/text()='raster test layer']/atom:link/@href", equalTo(
                    jetty.getUri().resolve("/geowebcache/rest/layers/raster%20test%20layer.xml").toString())));

            assertThat(doc, hasXPath("count(/layers/layer)", equalTo("3")));
        });

    }

    @Test
    public void testCreateUpdateDelete() throws Exception {
        final String layerName = "testLayer";
        final String url1 = "http://example.com/wms1?";
        final String url2 = "http://example.com/wms2?";
        final String layers = "remoteLayer";

        // Create
        {
            final HttpPut request = new HttpPut(jetty.getUri().resolve("rest/layers/").resolve(layerName + ".xml"));
            request.setEntity(new StringEntity(
                    "<wmsLayer><name>" + layerName + "</name><wmsUrl><string>" + url1
                            + "</string></wmsUrl><wmsLayers>" + layers + "</wmsLayers></wmsLayer>",
                    ContentType.APPLICATION_XML));
            try (CloseableHttpResponse response = admin.getClient().execute(request)) {
                assertThat(response.getStatusLine(), hasProperty("statusCode", equalTo(200)));
            }

            doGetXML("rest/layers.xml", admin.getClient(), equalTo(200), doc -> {
                assertThat(doc, hasXPath("/layers/layer[name/text()='" + layerName + "']/atom:link/@href", equalTo(
                        jetty.getUri().resolve("/geowebcache/rest/layers/" + layerName + ".xml").toString())));
            });
            doGetXML("rest/layers/" + layerName + ".xml", admin.getClient(), equalTo(200), doc -> {
                assertThat(doc, hasXPath("/wmsLayer/name", equalTo(layerName)));
                assertThat(doc, hasXPath("/wmsLayer/wmsUrl/string", equalTo(url1)));
                assertThat(doc, hasXPath("/wmsLayer/wmsLayers", equalTo(layers)));
            });
        }
        // Update
        {
            final HttpPost request = new HttpPost(
                    jetty.getUri().resolve("rest/layers/").resolve(layerName + ".xml"));
            request.setEntity(new StringEntity(
                    "<wmsLayer><name>" + layerName + "</name><wmsUrl><string>" + url2
                            + "</string></wmsUrl><wmsLayers>" + layers + "</wmsLayers></wmsLayer>",
                    ContentType.APPLICATION_XML));
            try (CloseableHttpResponse response = admin.getClient().execute(request)) {
                assertThat(response.getStatusLine(), hasProperty("statusCode", equalTo(200)));
            }
            doGetXML("rest/layers/" + layerName + ".xml", admin.getClient(), equalTo(200), doc -> {
                assertThat(doc, hasXPath("/wmsLayer/name", equalTo(layerName)));
                assertThat(doc, hasXPath("/wmsLayer/wmsUrl/string", equalTo(url2)));
                assertThat(doc, hasXPath("/wmsLayer/wmsLayers", equalTo(layers)));
            });
        }
        // GetCap
        {
            doGetXML("service/wmts?REQUEST=getcapabilities", anonymous.getClient(), equalTo(200), doc -> {
                assertThat(doc, hasXPath(
                        "/wmts:Capabilities/wmts:Contents/wmts:Layer/ows:Title[text()='" + layerName + "']"));
            });
        }
        // Delete
        {
            final HttpDelete request = new HttpDelete(
                    jetty.getUri().resolve("rest/layers/").resolve(layerName + ".xml"));
            try (CloseableHttpResponse response = admin.getClient().execute(request)) {
                assertThat(response.getStatusLine(), hasProperty("statusCode", equalTo(200)));
            }

            doGetXML("rest/layers.xml", admin.getClient(), equalTo(200), doc -> {
                assertThat(doc, not(hasXPath("/layers/layer[name/text()='" + layerName + "']")));
            });

            final HttpGet request2 = new HttpGet(
                    jetty.getUri().resolve("rest/layers/").resolve(layerName + ".xml"));
            try (CloseableHttpResponse response = admin.getClient().execute(request2)) {
                assertThat(response.getStatusLine(), hasProperty("statusCode", equalTo(404)));
            }
        }
        // GetCap
        {
            doGetXML("service/wmts?REQUEST=getcapabilities", anonymous.getClient(), equalTo(200), doc -> {
                assertThat(doc, not(hasXPath(
                        "/wmts:Capabilities/wmts:Contents/wmts:Layer/ows:Title[text()='" + layerName + "']")));
            });
        }

    }

    @Test
    public void testInvalidMethods() throws Exception {
        // Check that all permutations of method and user produce the expected status code. 
        for (HttpUriRequest request : Arrays.asList(new HttpDelete(jetty.getUri().resolve("rest/layers.xml")),
                new HttpPost(jetty.getUri().resolve("rest/layers.xml")),
                new HttpPut(jetty.getUri().resolve("rest/layers.xml")),

                new HttpPut(jetty.getUri().resolve("rest/seed/img%20states.xml")),
                new HttpDelete(jetty.getUri().resolve("rest/seed/img%20states.xml")),
                new HttpDelete(jetty.getUri().resolve("rest/seed/ui_form")),
                new HttpPut(jetty.getUri().resolve("rest/seed/ui_form")),

                new HttpDelete(jetty.getUri().resolve("rest/diskquota.xml")),
                new HttpDelete(jetty.getUri().resolve("rest/diskquota.json")),
                new HttpDelete(jetty.getUri().resolve("rest/diskquota")),

                new HttpPut(jetty.getUri().resolve("rest/masstruncate")),
                new HttpDelete(jetty.getUri().resolve("rest/masstruncate")),

                new HttpPut(jetty.getUri().resolve("rest/statistics")),
                new HttpPost(jetty.getUri().resolve("rest/statistics")),
                new HttpDelete(jetty.getUri().resolve("rest/statistics")),

                new HttpPut(jetty.getUri().resolve("rest/reload")),
                new HttpGet(jetty.getUri().resolve("rest/reload")),
                new HttpDelete(jetty.getUri().resolve("rest/reload")))) {
            testSecured(request, equalTo(405));
        }
    }

    @Test
    public void testSecure() throws Exception {
        for (HttpUriRequest request : Arrays.asList(new HttpGet(jetty.getUri().resolve("rest/layers.xml")),
                new HttpGet(jetty.getUri().resolve("rest/seed/img%20states")),
                new HttpPost(jetty.getUri().resolve("rest/reload")),
                new HttpPost(jetty.getUri().resolve("rest/seed/img%20states.xml")),
                new HttpGet(jetty.getUri().resolve("rest/seed/img%20states.xml")),
                new HttpGet(jetty.getUri().resolve("rest/seed/ui_form")),
                new HttpPost(jetty.getUri().resolve("rest/seed/ui_form")),
                new HttpGet(jetty.getUri().resolve("rest/masstruncate")),
                new HttpPost(jetty.getUri().resolve("rest/masstruncate")))) {
            testSecured(request, not(either(equalTo(401)).or(equalTo(405))));
        }
    }

    @Test
    public void testGetLayer() throws Exception {
        doGetXML("rest/layers/img%20states.xml", admin.getClient(), equalTo(200), doc -> {
            assertThat(doc, hasXPath("/wmsLayer/name", equalTo("img states")));
            assertThat(doc,
                    hasXPath("/wmsLayer/wmsUrl/string", equalTo("https://demo.boundlessgeo.com/geoserver/wms?")));
            assertThat(doc, hasXPath("/wmsLayer/wmsLayers", equalTo("nurc:Img_Sample,topp:states")));
        });
    }

    @Test
    public void testLayerNoAuth() throws Exception {
        for (CloseableHttpClient client : Arrays.asList(anonymous.getClient(), notAUser.getClient())) {
            doGetXML("rest/layers/img%20states.xml", client, equalTo(401), doc -> {
                assertThat(doc, not(hasXPath("//wmsUrl", containsString("demo.opengeo.org"))));
                assertThat(doc, not(hasXPath("//wmsLayer", containsString("nurc"))));
                assertThat(doc, not(hasXPath("//wmsLayer", containsString("Img_Sample"))));
                assertThat(doc, not(hasXPath("//wmsLayer", containsString("topp"))));
                assertThat(doc, not(hasXPath("//wmsLayer", containsString("states"))));
            });
        }
    }

    /**
     * Check that the given request gives a 401 Forbidden when not authenticated, and otherwise 
     * has a response matching the given matcher
     * @param request
     * @param authenticatedStatus
     * @throws Exception
     */
    protected void testSecured(HttpUriRequest request, Matcher<Integer> authenticatedStatus) throws Exception {
        {
            CloseableHttpClient client = admin.getClient();
            try (CloseableHttpResponse response = client.execute(request);
                    InputStream in = response.getEntity().getContent()) {
                assertThat(response.getStatusLine(), hasProperty("statusCode", authenticatedStatus));
            }
        }
        for (CloseableHttpClient client : Arrays.asList(anonymous.getClient(), notAUser.getClient(),
                badPassword.getClient())) {
            try (CloseableHttpResponse response = client.execute(request);
                    InputStream in = response.getEntity().getContent()) {
                final int code = 401;
                assertThat(response.getStatusLine(),
                        describedAs("Request %0 with without authentication produces status code %1",
                                hasProperty("statusCode", equalTo(code)), request, code));
            }
        }
    }

    @Test
    public void testAddLayer() throws Exception {
        doGetXML("rest/layers/img%20states.xml", notAUser.getClient(), equalTo(401), doc -> {
            assertThat(doc, not(hasXPath("//wmsUrl", containsString("demo.opengeo.org"))));
            assertThat(doc, not(hasXPath("//wmsLayer", containsString("nurc"))));
            assertThat(doc, not(hasXPath("//wmsLayer", containsString("Img_Sample"))));
            assertThat(doc, not(hasXPath("//wmsLayer", containsString("topp"))));
            assertThat(doc, not(hasXPath("//wmsLayer", containsString("states"))));
        });
    }

    /* BlobStoreController Integration Tests *****************************************************/

    @Test
    public void testGetBlobStoresXML() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/blobstores.xml"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("count(/blobStores/blobStore)", equalTo("1")));
        assertThat(doc, hasXPath("/blobStores/blobStore[1]/name", equalTo("defaultCache")));
        assertThat(doc, hasXPath("/blobStores/blobStore[1]/atom:link/@href",
                equalTo(jetty.getUri() + "rest/blobstores/defaultCache.xml")));
        assertThat(doc, hasXPath("/blobStores/blobStore[1]/atom:link/@type", equalTo(MediaType.TEXT_XML_VALUE)));
    }

    @Test
    public void testGetBlobStoresJSON() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/blobstores.json"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        JSONArray jsonArray = getResponseEntityAsJSONArray(response);
        assertEquals(1, jsonArray.length());
        assertEquals("defaultCache", jsonArray.get(0));
    }

    @Test
    public void testGetBlobStoreXML() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/blobstores/defaultCache.xml"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("//id", equalTo("defaultCache")));
        assertThat(doc, hasXPath("//enabled", equalTo("false")));
        assertThat(doc, hasXPath("//baseDirectory", equalTo("/tmp/defaultCache")));
        assertThat(doc, hasXPath("//fileSystemBlockSize", equalTo("4096")));
    }

    @Test
    public void testGetBlobStoreJSON() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/blobstores/defaultCache.json"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        JSONObject jsonObject = getResponseEntityAsJSONObject(response);
        jsonObject = jsonObject.getJSONObject("FileBlobStore");
        assertEquals("defaultCache", jsonObject.get("id"));
        assertEquals(false, jsonObject.get("enabled"));
        assertEquals("/tmp/defaultCache", jsonObject.get("baseDirectory"));
        assertEquals(4096, jsonObject.get("fileSystemBlockSize"));
    }

    @Test
    public void testPutBlobStoreCreateModifyDelete() throws Exception {
        String blobStore = "<FileBlobStore>\n" + "    <id>newCache</id>\n" + "    <enabled>false</enabled>\n"
                + "    <baseDirectory>/tmp/newCache</baseDirectory>\n"
                + "    <fileSystemBlockSize>4096</fileSystemBlockSize>\n" + "</FileBlobStore>";

        //Make it sure doesn't exist
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/blobstores/newCache.xml"),
                admin.getClient());
        assertEquals(404, response.getStatusLine().getStatusCode());
        response.close();

        response = handlePut(URI.create("/geowebcache/rest/blobstores/newCache"), admin.getClient(), blobStore);
        assertEquals(201, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/blobstores/newCache.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("//id", equalTo("newCache")));
        assertThat(doc, hasXPath("//enabled", equalTo("false")));
        assertThat(doc, hasXPath("//baseDirectory", equalTo("/tmp/newCache")));
        assertThat(doc, hasXPath("//fileSystemBlockSize", equalTo("4096")));

        String blobStoreUpdate = "<FileBlobStore>\n" + "    <id>newCache</id>\n" + "    <enabled>false</enabled>\n"
                + "    <baseDirectory>/tmp/newCache</baseDirectory>\n"
                + "    <fileSystemBlockSize>2048</fileSystemBlockSize>\n" + "</FileBlobStore>";

        response = handlePut(URI.create("/geowebcache/rest/blobstores/newCache"), admin.getClient(),
                blobStoreUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/blobstores/newCache.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("//id", equalTo("newCache")));
        assertThat(doc, hasXPath("//enabled", equalTo("false")));
        assertThat(doc, hasXPath("//baseDirectory", equalTo("/tmp/newCache")));
        assertThat(doc, hasXPath("//fileSystemBlockSize", equalTo("2048")));

        response = handleDelete(URI.create("/geowebcache/rest/blobstores/newCache.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/blobstores/newCache.xml"), admin.getClient());
        assertEquals(404, response.getStatusLine().getStatusCode());
        response.close();
    }

    /* GridSetController Integration Tests *****************************************************/

    @Test
    public void testGetGridSetsXML() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/gridsets.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("count(/gridSets/gridSet)", equalTo("7")));
        assertThat(doc, hasXPath("/gridSets/gridSet[1]/name", equalTo("EPSG:2163")));
        assertThat(doc, hasXPath("/gridSets/gridSet[1]/atom:link/@href",
                equalTo(jetty.getUri() + "rest/gridsets/EPSG:2163.xml")));
        assertThat(doc, hasXPath("/gridSets/gridSet[1]/atom:link/@type", equalTo(MediaType.TEXT_XML_VALUE)));
    }

    @Test
    public void testGetGridSetsJSON() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/gridsets.json"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        JSONArray jsonArray = getResponseEntityAsJSONArray(response);
        assertEquals(7, jsonArray.length());
        assertEquals("EPSG:2163", jsonArray.get(0));
    }

    @Test
    public void testGetGridSetXML() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/gridsets/EPSG:2163.xml"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("//name", equalTo("EPSG:2163")));
        assertThat(doc, hasXPath("//srs/number", equalTo("2163")));
        assertThat(doc, hasXPath("//extent/coords/double[1]", equalTo("-2495667.977678598")));
        assertThat(doc, hasXPath("//extent/coords/double[2]", equalTo("-2223677.196231552")));
        assertThat(doc, hasXPath("//extent/coords/double[3]", equalTo("3291070.6104286816")));
        assertThat(doc, hasXPath("//extent/coords/double[4]", equalTo("959189.3312465074")));
        assertThat(doc, hasXPath("//scaleDenominators/double[1]", equalTo("2.5E7")));
        assertThat(doc, hasXPath("//metersPerUnit", equalTo("1.0")));
        assertThat(doc, hasXPath("//pixelSize", equalTo("2.8E-4")));
        assertThat(doc, hasXPath("//yCoordinateFirst", equalTo("false")));
        assertThat(doc, hasXPath("//tileWidth", equalTo("200")));
        assertThat(doc, hasXPath("//tileHeight", equalTo("200")));

    }

    @Test
    public void testGetGridSetJSON() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/gridsets/EPSG:2163.json"),
                admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        JSONObject jsonObject = getResponseEntityAsJSONObject(response);
        jsonObject = jsonObject.getJSONObject("gridSet");
        assertEquals("EPSG:2163", jsonObject.get("name"));
        assertEquals("2163", jsonObject.getJSONObject("srs").getString("number"));
        assertEquals("[-2495667.977678598,-2223677.196231552,3291070.6104286816,959189.3312465074]",
                jsonObject.getJSONObject("extent").get("coords").toString());
        assertEquals("false", jsonObject.get("yCoordinateFirst").toString());
    }

    @Test
    public void testPutGridSetCreateModifyDelete() throws Exception {
        String gridSet = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gridSet>\n"
                + "  <name>testGridset</name>\n" + "  <srs>\n" + "    <number>4326</number>\n" + "  </srs>\n"
                + "  <extent>\n" + "    <coords>\n" + "      <double>-2495667.977678598</double>\n"
                + "      <double>-2223677.196231552</double>\n" + "      <double>3291070.6104286816</double>\n"
                + "      <double>959189.3312465074</double>\n" + "    </coords>\n" + "  </extent>\n"
                + "  <alignTopLeft>false</alignTopLeft>\n" + "  <scaleDenominators>\n"
                + "    <double>2.5E7</double>\n" + "    <double>1000000.0</double>\n"
                + "    <double>100000.0</double>\n" + "    <double>25000.0</double>\n" + "  </scaleDenominators>\n"
                + "  <metersPerUnit>1.0</metersPerUnit>\n" + "  <pixelSize>2.8E-4</pixelSize>\n"
                + "  <scaleNames>\n" + "    <string>EPSG:4326:0</string>\n" + "    <string>EPSG:4326:1</string>\n"
                + "    <string>EPSG:4326:2</string>\n" + "    <string>EPSG:4326:3</string>\n" + "  </scaleNames>\n"
                + "  <tileHeight>211</tileHeight>\n" + "  <tileWidth>211</tileWidth>\n"
                + "  <yCoordinateFirst>false</yCoordinateFirst>\n" + "</gridSet>";

        //Make it sure doesn't exist
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/gridsets/testGridset.xml"),
                admin.getClient());
        assertEquals(404, response.getStatusLine().getStatusCode());
        response.close();

        response = handlePut(URI.create("/geowebcache/rest/gridsets/testGridset.xml"), admin.getClient(), gridSet);
        assertEquals(201, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/gridsets/testGridset.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        Document doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("//name", equalTo("testGridset")));
        assertThat(doc, hasXPath("//srs/number", equalTo("4326")));
        assertThat(doc, hasXPath("//scaleDenominators/double[1]", equalTo("2.5E7")));
        assertThat(doc, hasXPath("//metersPerUnit", equalTo("1.0")));
        assertThat(doc, hasXPath("//pixelSize", equalTo("2.8E-4")));
        assertThat(doc, hasXPath("//yCoordinateFirst", equalTo("false")));
        assertThat(doc, hasXPath("//tileWidth", equalTo("211")));
        assertThat(doc, hasXPath("//tileHeight", equalTo("211")));

        String gridSetUpdate = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gridSet>\n"
                + "  <name>testGridset</name>\n" + "  <srs>\n" + "    <number>2163</number>\n" + "  </srs>\n"
                + "  <extent>\n" + "    <coords>\n" + "      <double>-2495667.977678598</double>\n"
                + "      <double>-2223677.196231552</double>\n" + "      <double>3291070.6104286816</double>\n"
                + "      <double>959189.3312465074</double>\n" + "    </coords>\n" + "  </extent>\n"
                + "  <alignTopLeft>false</alignTopLeft>\n" + "  <scaleDenominators>\n"
                + "    <double>2.5E7</double>\n" + "    <double>1000000.0</double>\n"
                + "    <double>100000.0</double>\n" + "    <double>25000.0</double>\n" + "  </scaleDenominators>\n"
                + "  <metersPerUnit>1.0</metersPerUnit>\n" + "  <pixelSize>2.8E-4</pixelSize>\n"
                + "  <scaleNames>\n" + "    <string>EPSG:2163:0</string>\n" + "    <string>EPSG:2163:1</string>\n"
                + "    <string>EPSG:2163:2</string>\n" + "    <string>EPSG:2163:3</string>\n" + "  </scaleNames>\n"
                + "  <tileHeight>200</tileHeight>\n" + "  <tileWidth>200</tileWidth>\n"
                + "  <yCoordinateFirst>false</yCoordinateFirst>\n" + "</gridSet>";

        response = handlePut(URI.create("/geowebcache/rest/gridsets/testGridset"), admin.getClient(),
                gridSetUpdate);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/gridsets/testGridset.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());

        doc = getResponseEntityAsXML(response);

        assertThat(doc, hasXPath("//name", equalTo("testGridset")));
        assertThat(doc, hasXPath("//srs/number", equalTo("2163")));
        assertThat(doc, hasXPath("//scaleDenominators/double[1]", equalTo("2.5E7")));
        assertThat(doc, hasXPath("//metersPerUnit", equalTo("1.0")));
        assertThat(doc, hasXPath("//pixelSize", equalTo("2.8E-4")));
        assertThat(doc, hasXPath("//yCoordinateFirst", equalTo("false")));
        assertThat(doc, hasXPath("//tileWidth", equalTo("200")));
        assertThat(doc, hasXPath("//tileHeight", equalTo("200")));

        response = handleDelete(URI.create("/geowebcache/rest/gridsets/testGridset.xml"), admin.getClient());
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.close();

        response = handleGet(URI.create("/geowebcache/rest/gridsets/testGridset.xml"), admin.getClient());
        assertEquals(404, response.getStatusLine().getStatusCode());
        response.close();
    }

    /* DiskQuotaController Integration Tests *****************************************************/

    @Test
    public void testDiskQuotaXML() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/diskquota.xml"),
                admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
        if (response.getStatusLine().getStatusCode() == 200) {
            Document doc = getResponseEntityAsXML(response);
            assertThat(doc, hasXPath("//enabled", equalTo("false")));
            assertThat(doc, hasXPath("//cacheCleanUpFrequency", equalTo("10")));
            assertThat(doc, hasXPath("//cacheCleanUpUnits", equalTo("SECONDS")));
            assertThat(doc, hasXPath("//maxConcurrentCleanUps", equalTo("2")));
            assertThat(doc, hasXPath("//globalExpirationPolicyName", equalTo("LFU")));
            assertThat(doc, hasXPath("//globalQuota/id", equalTo("0")));
            assertThat(doc, hasXPath("//globalQuota/bytes", equalTo("524288000")));
        }
    }

    @Test
    public void testDiskQuotaJson() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/diskquota.json"),
                admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
        if (response.getStatusLine().getStatusCode() == 200) {
            JSONObject jsonObject = getResponseEntityAsJSONObject(response);
            Object obj = jsonObject.get("org.geowebcache.diskquota.DiskQuotaConfig");
            if (obj instanceof JSONObject) {
                TestCase.assertEquals(false, ((JSONObject) obj).get("enabled"));
                TestCase.assertEquals(10, ((JSONObject) obj).get("cacheCleanUpFrequency"));
                TestCase.assertEquals("SECONDS", ((JSONObject) obj).get("cacheCleanUpUnits"));
                TestCase.assertEquals(2, ((JSONObject) obj).get("maxConcurrentCleanUps"));
                TestCase.assertEquals("LFU", ((JSONObject) obj).get("globalExpirationPolicyName"));
                Object globalQuota = ((JSONObject) obj).get("globalQuota");
                if (globalQuota instanceof JSONObject) {
                    TestCase.assertEquals(0, ((JSONObject) globalQuota).get("id"));
                    TestCase.assertEquals(524288000, ((JSONObject) globalQuota).get("bytes"));
                }
            }

        }
    }

    /* SeedController Integration Tests ***********************************************************/

    @Test
    public void testSeedPost() throws Exception {
        String seedLayer = "<seedRequest>" + //
                "  <name>topp:states</name>" + //
                "  <srs>" + //
                "    <number>4326</number>" + //
                "  </srs>" + //
                "  <zoomStart>1</zoomStart>" + //
                "  <zoomStop>12</zoomStop>" + //
                "  <format>image/png</format>" + //
                "  <type>truncate</type>" + //
                "  <threadCount>4</threadCount>" + //
                "</seedRequest>";

        CloseableHttpResponse response = handlePost(URI.create("/geowebcache/rest/seed/topp:states.xml"),
                admin.getClient(), seedLayer);
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testSeedGet() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/seed/topp:states"),
                admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testSeedGetNoLayer() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/seed"), admin.getClient());
        TestCase.assertEquals(405, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testSeedGetSeedForm() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/seed/topp:states"),
                admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testSeedGetJson() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/seed.json"), admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testSeedGetLayerJson() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/seed/topp:states.json"),
                admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testSeedGetLayerXml() throws Exception {
        CloseableHttpResponse response = handleGet(URI.create("/geowebcache/rest/seed/topp:states.xml"),
                admin.getClient());
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testKillAll() throws Exception {
        String killCommand = "kill_all=all";
        CloseableHttpResponse response = handlePost(URI.create("/geowebcache/rest/seed"), admin.getClient(),
                killCommand);
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testLayerKillAll() throws Exception {
        String killCommand = "kill_all=all";
        CloseableHttpResponse response = handlePost(URI.create("/geowebcache/rest/seed/topp:states"),
                admin.getClient(), killCommand);
        TestCase.assertEquals(200, response.getStatusLine().getStatusCode());
    }

    @Test
    public void testNewFileBlobstoreDontDeleteExistingContent() throws Exception {
        // The directory already has stuff in it
        File bsDir = temp.newFolder();
        File existingFile1 = new File(bsDir, "existingFile1");
        existingFile1.createNewFile();
        File existingDirectory = new File(bsDir, "existingDirectory");
        existingDirectory.mkdir();
        File existingFile2 = new File(existingDirectory, "existingFile2");
        existingFile2.createNewFile();

        String blobStore = "<FileBlobStore>\n" + "    <id>maliciousCache</id>\n" + "    <enabled>true</enabled>\n"
                + "    <baseDirectory>" + bsDir + "</baseDirectory>\n"
                + "    <fileSystemBlockSize>4096</fileSystemBlockSize>\n" + "</FileBlobStore>";
        String layer1name = existingFile1.getName();
        String layer1 = "<wmsLayer>\n" + "    <name>" + layer1name + "</name>\n"
                + "    <blobStoreId>maliciousCache</blobStoreId>\n"
                + "    <wmsUrl><string>http://example.com/geoserver/wms</string></wmsUrl>\n" + "</wmsLayer>";
        String layer1truncate = "<truncateLayer><layerName>" + layer1name + "</layerName></truncateLayer>";
        String layer2name = existingDirectory.getName();
        String layer2 = "<wmsLayer>\n" + "    <name>" + layer2name + "</name>\n"
                + "    <blobStoreId>maliciousCache</blobStoreId>\n"
                + "    <wmsUrl><string>http://example.com/geoserver/wms</string></wmsUrl>\n" + "</wmsLayer>";
        String layer2truncate = "<truncateLayer><layerName>" + layer2name + "</layerName></truncateLayer>";

        // Make it sure the blobstore doesn't exist already as that would invalidate the test
        try (CloseableHttpResponse response = handleGet(
                URI.create("/geowebcache/rest/blobstores/maliciousCache.xml"), admin.getClient())) {
            assertThat(response, hasProperty("statusLine", hasProperty("statusCode", equalTo(404))));
        }

        // Create a store
        try (CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/blobstores/maliciousCache"),
                admin.getClient(), blobStore)) {
        } catch (Exception e) {
            // Ignore and keep going
        }

        // Create layers with the names of entries in that directory
        try (CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/layers/" + layer1name),
                admin.getClient(), layer1)) {
        } catch (Exception e) {
            // Ignore and keep going
        }
        try (CloseableHttpResponse response = handlePut(URI.create("/geowebcache/rest/layers/" + layer2name),
                admin.getClient(), layer2)) {
        } catch (Exception e) {
            // Ignore and keep going
        }

        // Mass Truncate those layers
        try (CloseableHttpResponse response = handlePost(URI.create("/geowebcache/rest/masstruncate"),
                admin.getClient(), layer1truncate)) {
        }
        try (CloseableHttpResponse response = handlePost(URI.create("/geowebcache/rest/masstruncate"),
                admin.getClient(), layer2truncate)) {
        } catch (Exception e) {
            // Ignore and keep going
        }

        // Delete the layers
        try (CloseableHttpResponse response = handleDelete(URI.create("/geowebcache/rest/layers/" + layer1name),
                admin.getClient())) {
        } catch (Exception e) {
            // Ignore and keep going
        }
        try (CloseableHttpResponse response = handleDelete(URI.create("/geowebcache/rest/layers/" + layer2name),
                admin.getClient())) {
        } catch (Exception e) {
            // Ignore and keep going
        }

        // Delete the store
        try (CloseableHttpResponse response = handleDelete(
                URI.create("/geowebcache/rest/blobstores/maliciousCache"), admin.getClient())) {
        } catch (Exception e) {
            // Ignore and keep going
        }

        // The existing data should still be present
        assertThat(existingFile1, FileMatchers.exists());
        assertThat(existingDirectory, FileMatchers.exists());
        assertThat(existingFile2, FileMatchers.exists());

    }

    /* Utility methods ***************************************************************************/

    private Document getResponseEntityAsXML(CloseableHttpResponse response) throws Exception {
        Document doc;

        doc = XMLUnit.buildTestDocument(new InputSource(response.getEntity().getContent()));
        doc.normalizeDocument();

        return doc;
    }

    private JSONObject getResponseEntityAsJSONObject(CloseableHttpResponse response) throws Exception {
        JSONObject jsonObject = new JSONObject(getResponseEntity(response));
        return jsonObject;
    }

    private JSONArray getResponseEntityAsJSONArray(CloseableHttpResponse response) throws Exception {
        JSONArray jsonObject = new JSONArray(getResponseEntity(response));
        return jsonObject;
    }

    private String getResponseEntity(CloseableHttpResponse response) {
        String doc;
        try {
            StringWriter writer = new StringWriter();
            IOUtils.copy(response.getEntity().getContent(), writer, Charset.defaultCharset());
            doc = writer.toString();
        } catch (IOException e) {

            doc = e.getMessage().toString();
        }
        return doc;
    }

    private CloseableHttpResponse handleGet(URI uri, CloseableHttpClient client) throws Exception {
        HttpGet request = new HttpGet(jetty.getUri().resolve(uri));
        CloseableHttpResponse response = client.execute(request);
        return response;
    }

    interface Assertions<T> {
        void accept(T result) throws Exception;
    }

    void doGetXML(String uri, CloseableHttpClient client, Matcher<Integer> statusMatcher, Assertions<Document> body)
            throws Exception {
        doGetXML(URI.create(uri), client, statusMatcher, body);
    }

    void doGetXML(URI uri, CloseableHttpClient client, Matcher<Integer> statusMatcher, Assertions<Document> body)
            throws Exception {
        final HttpGet request = new HttpGet(jetty.getUri().resolve(uri));
        final Document doc;
        try (CloseableHttpResponse response = client.execute(request);
                InputStream in = response.getEntity().getContent()) {
            if (response.getStatusLine().getStatusCode() != 401) {
                doc = XMLUnit.buildTestDocument(new InputSource(in));
                body.accept(doc);
            }
            assertThat(response.getStatusLine(), hasProperty("statusCode", statusMatcher));
        }

    }

    private CloseableHttpResponse handleDelete(URI uri, CloseableHttpClient client) throws Exception {
        HttpDelete request = new HttpDelete(jetty.getUri().resolve(uri));
        CloseableHttpResponse response = client.execute(request);
        return response;
    }

    private CloseableHttpResponse handlePut(URI uri, CloseableHttpClient client, String data) throws Exception {
        HttpPut request = new HttpPut(jetty.getUri().resolve(uri));
        StringEntity entity = new StringEntity(data);
        entity.setContentType(new BasicHeader("Content-type", "text/xml"));
        request.setEntity(entity);
        CloseableHttpResponse response = client.execute(request);
        return response;
    }

    private CloseableHttpResponse handlePost(URI uri, CloseableHttpClient client, String data) throws Exception {
        HttpPost request = new HttpPost(jetty.getUri().resolve(uri));
        StringEntity entity = new StringEntity(data);
        entity.setContentType(new BasicHeader("Content-type", "text/xml"));
        request.setEntity(entity);
        CloseableHttpResponse response = client.execute(request);
        return response;
    }
}