org.apache.hadoop.gateway.GatewayAdminTopologyFuncTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.gateway.GatewayAdminTopologyFuncTest.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.gateway;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.core.MediaType;

import com.jayway.restassured.http.ContentType;
import com.mycila.xmltool.XMLDoc;
import com.mycila.xmltool.XMLTag;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.security.ldap.SimpleLdapDirectoryServer;
import org.apache.hadoop.gateway.services.DefaultGatewayServices;
import org.apache.hadoop.gateway.services.GatewayServices;
import org.apache.hadoop.gateway.services.ServiceLifecycleException;
import org.apache.hadoop.gateway.services.topology.TopologyService;
import org.apache.hadoop.gateway.topology.Param;
import org.apache.hadoop.gateway.topology.Provider;
import org.apache.hadoop.gateway.topology.Service;
import org.apache.hadoop.gateway.topology.Topology;
import org.apache.hadoop.gateway.util.XmlUtils;
import org.apache.hadoop.test.TestUtils;
import org.apache.http.HttpStatus;
import org.apache.log4j.Appender;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import static com.jayway.restassured.RestAssured.given;
import static org.apache.hadoop.test.TestUtils.LOG_ENTER;
import static org.apache.hadoop.test.TestUtils.LOG_EXIT;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.xml.HasXPath.hasXPath;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

public class GatewayAdminTopologyFuncTest {

    private static Class RESOURCE_BASE_CLASS = GatewayAdminTopologyFuncTest.class;
    private static Logger LOG = LoggerFactory.getLogger(GatewayAdminTopologyFuncTest.class);

    public static Enumeration<Appender> appenders;
    public static GatewayConfig config;
    public static GatewayServer gateway;
    public static String gatewayUrl;
    public static String clusterUrl;
    public static SimpleLdapDirectoryServer ldap;
    public static TcpTransport ldapTransport;

    @BeforeClass
    public static void setupSuite() throws Exception {
        //appenders = NoOpAppender.setUp();
        setupLdap();
        setupGateway(new GatewayTestConfig());
    }

    @AfterClass
    public static void cleanupSuite() throws Exception {
        gateway.stop();
        ldap.stop(true);
        //FileUtils.deleteQuietly( new File( config.getGatewayHomeDir() ) );
        //NoOpAppender.tearDown( appenders );
    }

    public static void setupLdap() throws Exception {
        URL usersUrl = getResourceUrl("users.ldif");
        ldapTransport = new TcpTransport(0);
        ldap = new SimpleLdapDirectoryServer("dc=hadoop,dc=apache,dc=org", new File(usersUrl.toURI()),
                ldapTransport);
        ldap.start();
        LOG.info("LDAP port = " + ldapTransport.getAcceptor().getLocalAddress().getPort());
    }

    public static void setupGateway(GatewayTestConfig testConfig) throws Exception {

        File targetDir = new File(System.getProperty("user.dir"), "target");
        File gatewayDir = new File(targetDir, "gateway-home-" + UUID.randomUUID());
        gatewayDir.mkdirs();

        config = testConfig;
        testConfig.setGatewayHomeDir(gatewayDir.getAbsolutePath());

        File topoDir = new File(testConfig.getGatewayTopologyDir());
        topoDir.mkdirs();

        File deployDir = new File(testConfig.getGatewayDeploymentDir());
        deployDir.mkdirs();

        File descriptor = new File(topoDir, "admin.xml");
        FileOutputStream stream = new FileOutputStream(descriptor);
        createKnoxTopology().toStream(stream);
        stream.close();

        File descriptor2 = new File(topoDir, "test-cluster.xml");
        FileOutputStream stream2 = new FileOutputStream(descriptor2);
        createNormalTopology().toStream(stream2);
        stream.close();

        DefaultGatewayServices srvcs = new DefaultGatewayServices();
        Map<String, String> options = new HashMap<>();
        options.put("persist-master", "false");
        options.put("master", "password");

        try {
            srvcs.init(testConfig, options);
        } catch (ServiceLifecycleException e) {
            e.printStackTrace(); // I18N not required.
        }
        gateway = GatewayServer.startGateway(testConfig, srvcs);
        MatcherAssert.assertThat("Failed to start gateway.", gateway, notNullValue());

        LOG.info("Gateway port = " + gateway.getAddresses()[0].getPort());

        gatewayUrl = "http://localhost:" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath();
        clusterUrl = gatewayUrl + "/admin";
    }

    private static XMLTag createNormalTopology() {
        XMLTag xml = XMLDoc.newDocument(true).addRoot("topology").addTag("gateway").addTag("provider")
                .addTag("role").addText("webappsec").addTag("name").addText("WebAppSec").addTag("enabled")
                .addText("true").addTag("param").addTag("name").addText("csrf.enabled").addTag("value")
                .addText("true").gotoParent().gotoParent().addTag("provider").addTag("role")
                .addText("authentication").addTag("name").addText("ShiroProvider").addTag("enabled").addText("true")
                .addTag("param").addTag("name").addText("main.ldapRealm").addTag("value")
                .addText("org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm").gotoParent().addTag("param")
                .addTag("name").addText("main.ldapRealm.userDnTemplate").addTag("value")
                .addText("uid={0},ou=people,dc=hadoop,dc=apache,dc=org").gotoParent().addTag("param").addTag("name")
                .addText("main.ldapRealm.contextFactory.url").addTag("value")
                .addText("ldap://localhost:" + ldapTransport.getAcceptor().getLocalAddress().getPort()).gotoParent()
                .addTag("param").addTag("name").addText("main.ldapRealm.contextFactory.authenticationMechanism")
                .addTag("value").addText("simple").gotoParent().addTag("param").addTag("name").addText("urls./**")
                .addTag("value").addText("authcBasic").gotoParent().gotoParent().addTag("provider").addTag("role")
                .addText("identity-assertion").addTag("enabled").addText("true").addTag("name").addText("Default")
                .gotoParent().addTag("provider").addTag("role").addText("authorization").addTag("enabled")
                .addText("true").addTag("name").addText("AclsAuthz").gotoParent().addTag("param").addTag("name")
                .addText("webhdfs-acl").addTag("value").addText("hdfs;*;*").gotoParent().gotoRoot()
                .addTag("service").addTag("role").addText("WEBHDFS").addTag("url")
                .addText("http://localhost:50070/webhdfs/v1").gotoParent().gotoRoot();
        //     System.out.println( "GATEWAY=" + xml.toString() );
        return xml;
    }

    private static XMLTag createKnoxTopology() {
        XMLTag xml = XMLDoc.newDocument(true).addRoot("topology").addTag("gateway").addTag("provider")
                .addTag("role").addText("authentication").addTag("name").addText("ShiroProvider").addTag("enabled")
                .addText("true").addTag("param").addTag("name").addText("main.ldapRealm").addTag("value")
                .addText("org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm").gotoParent().addTag("param")
                .addTag("name").addText("main.ldapRealm.userDnTemplate").addTag("value")
                .addText("uid={0},ou=people,dc=hadoop,dc=apache,dc=org").gotoParent().addTag("param").addTag("name")
                .addText("main.ldapRealm.contextFactory.url").addTag("value")
                .addText("ldap://localhost:" + ldapTransport.getAcceptor().getLocalAddress().getPort()).gotoParent()
                .addTag("param").addTag("name").addText("main.ldapRealm.contextFactory.authenticationMechanism")
                .addTag("value").addText("simple").gotoParent().addTag("param").addTag("name").addText("urls./**")
                .addTag("value").addText("authcBasic").gotoParent().gotoParent().addTag("provider").addTag("role")
                .addText("authorization").addTag("name").addText("AclsAuthz").addTag("enabled").addText("true")
                .addTag("param").addTag("name").addText("knox.acl").addTag("value").addText("admin;*;*")
                .gotoParent().gotoParent().addTag("provider").addTag("role").addText("identity-assertion")
                .addTag("enabled").addText("true").addTag("name").addText("Default").gotoParent().gotoRoot()
                .addTag("service").addTag("role").addText("KNOX").gotoRoot();
        // System.out.println( "GATEWAY=" + xml.toString() );
        return xml;
    }

    public static InputStream getResourceStream(String resource) throws IOException {
        return getResourceUrl(resource).openStream();
    }

    public static URL getResourceUrl(String resource) {
        URL url = ClassLoader.getSystemResource(getResourceName(resource));
        assertThat("Failed to find test resource " + resource, url, Matchers.notNullValue());
        return url;
    }

    public static String getResourceName(String resource) {
        return getResourceBaseName() + resource;
    }

    public static String getResourceBaseName() {
        return RESOURCE_BASE_CLASS.getName().replaceAll("\\.", "/") + "/";
    }

    //@Test
    public void waitForManualTesting() throws IOException {
        System.in.read();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testTopologyCollection() throws ClassNotFoundException {
        LOG_ENTER();

        String username = "admin";
        String password = "admin-password";
        String serviceUrl = clusterUrl + "/api/v1/topologies";
        String href1 = given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).body("topologies.topology[0].name", not(nullValue()))
                .body("topologies.topology[1].name", not(nullValue()))
                .body("topologies.topology[0].uri", not(nullValue()))
                .body("topologies.topology[1].uri", not(nullValue()))
                .body("topologies.topology[0].href", not(nullValue()))
                .body("topologies.topology[1].href", not(nullValue()))
                .body("topologies.topology[0].timestamp", not(nullValue()))
                .body("topologies.topology[1].timestamp", not(nullValue())).when().get(serviceUrl).thenReturn()
                .getBody().path("topologies.topology.href[1]");

        given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML).expect()
                //.log().all()
                .body("topologies.topology.href[1]", equalTo(href1)).statusCode(HttpStatus.SC_OK).when()
                .get(serviceUrl);

        given()
                //.log().all()
                .auth().preemptive().basic(username, password).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).contentType(MediaType.APPLICATION_XML).get(serviceUrl);

        given().auth().preemptive().basic(username, password).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).contentType("application/json")
                .body("topology.name", equalTo("test-cluster")).when().get(href1);

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testTopologyObject() throws ClassNotFoundException {
        LOG_ENTER();

        String username = "admin";
        String password = "admin-password";
        String serviceUrl = clusterUrl + "/api/v1/topologies";
        String hrefJson = given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_JSON).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).when().get(serviceUrl).thenReturn().getBody()
                .path("topologies.topology[1].href");

        String timestampJson = given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_JSON).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).contentType("application/json").when().get(serviceUrl).andReturn()
                .getBody().path("topologies.topology[1].timestamp");

        given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_JSON).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).body("topology.name", equalTo("test-cluster"))
                .body("topology.timestamp", equalTo(Long.parseLong(timestampJson))).when().get(hrefJson);

        String hrefXml = given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).when().get(serviceUrl).thenReturn().getBody()
                .path("topologies.topology[1].href");

        given()
                //.log().all()
                .auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).when().get(hrefXml);

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testPositiveAuthorization() throws ClassNotFoundException {
        LOG_ENTER();

        String adminUser = "admin";
        String adminPass = "admin-password";
        String url = clusterUrl + "/api/v1/topologies";

        given()
                //.log().all()
                .auth().preemptive().basic(adminUser, adminPass).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).contentType(ContentType.JSON)
                .body("topologies.topology[0].name", not(nullValue()))
                .body("topologies.topology[1].name", not(nullValue()))
                .body("topologies.topology[0].uri", not(nullValue()))
                .body("topologies.topology[1].uri", not(nullValue()))
                .body("topologies.topology[0].href", not(nullValue()))
                .body("topologies.topology[1].href", not(nullValue()))
                .body("topologies.topology[0].timestamp", not(nullValue()))
                .body("topologies.topology[1].timestamp", not(nullValue())).get(url);

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testNegativeAuthorization() throws ClassNotFoundException {
        LOG_ENTER();

        String guestUser = "guest";
        String guestPass = "guest-password";
        String url = clusterUrl + "/api/v1/topologies";

        given()
                //.log().all()
                .auth().basic(guestUser, guestPass).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_FORBIDDEN).get(url);

        LOG_EXIT();
    }

    private Topology createTestTopology() {
        Topology topology = new Topology();
        topology.setName("test-topology");

        try {
            topology.setUri(new URI(gatewayUrl + "/" + topology.getName()));
        } catch (URISyntaxException ex) {
            assertThat(topology.getUri(), not(nullValue()));
        }

        Provider identityProvider = new Provider();
        identityProvider.setName("Default");
        identityProvider.setRole("identity-assertion");
        identityProvider.setEnabled(true);

        Provider AuthenicationProvider = new Provider();
        AuthenicationProvider.setName("ShiroProvider");
        AuthenicationProvider.setRole("authentication");
        AuthenicationProvider.setEnabled(true);

        Param ldapMain = new Param();
        ldapMain.setName("main.ldapRealm");
        ldapMain.setValue("org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm");

        Param ldapGroupContextFactory = new Param();
        ldapGroupContextFactory.setName("main.ldapGroupContextFactory");
        ldapGroupContextFactory.setValue("org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory");

        Param ldapRealmContext = new Param();
        ldapRealmContext.setName("main.ldapRealm.contextFactory");
        ldapRealmContext.setValue("$ldapGroupContextFactory");

        Param ldapURL = new Param();
        ldapURL.setName("main.ldapRealm.contextFactory.url");
        ldapURL.setValue("ldap://localhost:" + ldapTransport.getAcceptor().getLocalAddress().getPort());

        Param ldapUserTemplate = new Param();
        ldapUserTemplate.setName("main.ldapRealm.userDnTemplate");
        ldapUserTemplate.setValue("uid={0},ou=people,dc=hadoop,dc=apache,dc=org");

        Param authcBasic = new Param();
        authcBasic.setName("urls./**");
        authcBasic.setValue("authcBasic");

        AuthenicationProvider.addParam(ldapGroupContextFactory);
        AuthenicationProvider.addParam(ldapMain);
        AuthenicationProvider.addParam(ldapRealmContext);
        AuthenicationProvider.addParam(ldapURL);
        AuthenicationProvider.addParam(ldapUserTemplate);
        AuthenicationProvider.addParam(authcBasic);

        Service testService = new Service();
        testService.setRole("test-service-role");

        topology.addProvider(AuthenicationProvider);
        topology.addProvider(identityProvider);
        topology.addService(testService);
        topology.setTimestamp(System.nanoTime());

        return topology;
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testDeployTopology() throws Exception {
        LOG_ENTER();

        Topology testTopology = createTestTopology();

        String user = "guest";
        String password = "guest-password";

        String url = gatewayUrl + "/" + testTopology.getName() + "/test-service-path/test-service-resource";

        GatewayServices srvs = GatewayServer.getGatewayServices();

        TopologyService ts = srvs.getService(GatewayServices.TOPOLOGY_SERVICE);
        try {
            ts.stopMonitor();

            assertThat(testTopology, not(nullValue()));
            assertThat(testTopology.getName(), is("test-topology"));

            given()
                    //.log().all()
                    .auth().preemptive().basic("admin", "admin-password")
                    .header("Accept", MediaType.APPLICATION_JSON).expect()
                    //.log().all()
                    .statusCode(HttpStatus.SC_OK).body(containsString("ServerVersion")).when()
                    .get(gatewayUrl + "/admin/api/v1/version");

            given()
                    //.log().all()
                    .auth().preemptive().basic(user, password).expect()
                    //.log().all()
                    .statusCode(HttpStatus.SC_NOT_FOUND).when().get(url);

            ts.deployTopology(testTopology);

            given()
                    //.log().all()
                    .auth().preemptive().basic(user, password).expect()
                    //.log().all()
                    .statusCode(HttpStatus.SC_OK).contentType("text/plain").body(is("test-service-response")).when()
                    .get(url).getBody();

            ts.deleteTopology(testTopology);

            given()
                    //.log().all()
                    .auth().preemptive().basic(user, password).expect()
                    //.log().all()
                    .statusCode(HttpStatus.SC_NOT_FOUND).when().get(url);
        } finally {
            ts.startMonitor();
        }

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testDeleteTopology() throws ClassNotFoundException {
        LOG_ENTER();

        Topology test = createTestTopology();

        String username = "admin";
        String password = "admin-password";
        String url = clusterUrl + "/api/v1/topologies/" + test.getName();

        GatewayServices gs = GatewayServer.getGatewayServices();

        TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);

        ts.deployTopology(test);

        given().auth().preemptive().basic(username, password).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).contentType(MediaType.APPLICATION_JSON).get(url);

        given().auth().preemptive().basic(username, password).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_OK).contentType(MediaType.APPLICATION_JSON).delete(url);

        given()
                //.log().all()
                .auth().preemptive().basic(username, password).expect()
                //.log().all()
                .statusCode(HttpStatus.SC_NO_CONTENT).get(url);

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testPutTopology() throws Exception {
        LOG_ENTER();

        String username = "admin";
        String password = "admin-password";
        String url = clusterUrl + "/api/v1/topologies/test-put";

        String JsonPut = given().auth().preemptive().basic(username, password)
                .header("Accept", MediaType.APPLICATION_JSON).get(clusterUrl + "/api/v1/topologies/test-cluster")
                .getBody().asString();

        String XML = given()
                //.log().all()
                .auth().preemptive().basic(username, password).contentType(MediaType.APPLICATION_JSON)
                .header("Accept", MediaType.APPLICATION_XML).body(JsonPut).expect().statusCode(HttpStatus.SC_OK)
                //.log().all()
                .put(url).getBody().asString();

        InputSource source = new InputSource(new StringReader(XML));
        Document doc = XmlUtils.readXml(source);

        assertThat(doc, hasXPath("/topology/gateway/provider[1]/name", containsString("WebAppSec")));
        assertThat(doc, hasXPath("/topology/gateway/provider[1]/param/name", containsString("csrf.enabled")));

        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML).expect()
                .statusCode(HttpStatus.SC_OK).body(equalTo(XML)).get(url).getBody().asString();

        String XmlPut = given().auth().preemptive().basic(username, password)
                .header("Accept", MediaType.APPLICATION_XML).get(clusterUrl + "/api/v1/topologies/test-cluster")
                .getBody().asString();

        String JSON = given()
                //.log().all()
                .auth().preemptive().basic(username, password).contentType(MediaType.APPLICATION_XML)
                .header("Accept", MediaType.APPLICATION_JSON).body(XmlPut).expect().statusCode(HttpStatus.SC_OK)
                //.log().all()
                .put(url).getBody().asString();

        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_JSON).expect()
                .statusCode(HttpStatus.SC_OK).body(equalTo(JSON)).get(url).getBody().asString();

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testXForwardedHeaders() {
        LOG_ENTER();

        String username = "admin";
        String password = "admin-password";
        String url = clusterUrl + "/api/v1/topologies";

        //    X-Forward header values
        String port = String.valueOf(777);
        String server = "myserver";
        String host = server + ":" + port;
        String proto = "protocol";
        String context = "/mycontext";
        String newUrl = proto + "://" + host + context;
        //    String port = String.valueOf(gateway.getAddresses()[0].getPort());

        //     Case 1: Add in all x-forward headers (host, port, server, context, proto)
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML)
                .header("X-Forwarded-Host", host).header("X-Forwarded-Port", port)
                .header("X-Forwarded-Server", server).header("X-Forwarded-Context", context)
                .header("X-Forwarded-Proto", proto).expect().statusCode(HttpStatus.SC_OK)
                .body(containsString(newUrl)).body(containsString("test-cluster")).body(containsString("admin"))
                .get(url);

        //     Case 2: add in x-forward headers (host, server, proto, context)
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML)
                .header("X-Forwarded-Host", host).header("X-Forwarded-Server", server)
                .header("X-Forwarded-Context", context).header("X-Forwarded-Proto", proto).expect()
                .statusCode(HttpStatus.SC_OK).body(containsString(server)).body(containsString(context))
                .body(containsString(proto)).body(containsString(host)).body(containsString("test-cluster"))
                .body(containsString("admin")).get(url);

        //     Case 3: add in x-forward headers (host, proto, port, context)
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML)
                .header("X-Forwarded-Host", host).header("X-Forwarded-Port", port)
                .header("X-Forwarded-Context", context).header("X-Forwarded-Proto", proto).expect()
                .statusCode(HttpStatus.SC_OK).body(containsString(host)).body(containsString(port))
                .body(containsString(context)).body(containsString(proto)).body(containsString("test-cluster"))
                .body(containsString("admin")).get(url);

        //     Case 4: add in x-forward headers (host, proto, port, context) no port in host.
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML)
                .header("X-Forwarded-Host", server).header("X-Forwarded-Port", port)
                .header("X-Forwarded-Context", context).header("X-Forwarded-Proto", proto).expect()
                .statusCode(HttpStatus.SC_OK).body(containsString(server)).body(containsString(port))
                .body(containsString(context)).body(containsString(proto)).body(containsString("test-cluster"))
                .body(containsString("admin")).get(url);

        //     Case 5: add in x-forward headers (host, port)
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML)
                .header("X-Forwarded-Host", host).header("X-Forwarded-Port", port).expect()
                .statusCode(HttpStatus.SC_OK).body(containsString(host)).body(containsString(port))
                .body(containsString("test-cluster")).body(containsString("admin")).get(url);

        //     Case 6: Normal Request
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML).expect()
                .statusCode(HttpStatus.SC_OK).body(containsString(url)).body(containsString("test-cluster"))
                .body(containsString("admin")).get(url);

        LOG_EXIT();
    }

    @Test(timeout = TestUtils.LONG_TIMEOUT)
    public void testGatewayPathChange() throws Exception {
        LOG_ENTER();
        String username = "admin";
        String password = "admin-password";
        String url = clusterUrl + "/api/v1/topologies";

        //     Case 1: Normal Request (No Change in gateway.path). Ensure HTTP OK resp + valid URL.
        given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML).expect()
                .statusCode(HttpStatus.SC_OK).body(containsString(url + "/test-cluster")).get(url);

        //     Case 2: Change gateway.path to another String. Ensure HTTP OK resp + valid URL.
        try {
            gateway.stop();

            GatewayTestConfig conf = new GatewayTestConfig();
            conf.setGatewayPath("new-gateway-path");
            setupGateway(conf);

            String newUrl = clusterUrl + "/api/v1/topologies";

            given().auth().preemptive().basic(username, password).header("Accept", MediaType.APPLICATION_XML)
                    .expect().statusCode(HttpStatus.SC_OK).body(containsString(newUrl + "/test-cluster"))
                    .get(newUrl);
        } catch (Exception e) {
            fail(e.getMessage());
        } finally {
            //        Restart the gateway with old settings.
            gateway.stop();
            setupGateway(new GatewayTestConfig());
        }

        LOG_EXIT();
    }

    private static final String CLASS = GatewayAdminTopologyFuncTest.class.getCanonicalName();

}