knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmin...@apache.org
Subject [3/5] knox git commit: [KNOX-670] - Knox should be able to sost simple web apps
Date Thu, 25 Feb 2016 20:54:23 GMT
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryTest.java
index 8669b2e..129f0fb 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryTest.java
@@ -17,55 +17,308 @@
  */
 package org.apache.hadoop.gateway.deploy;
 
+import java.io.IOException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
 import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.hadoop.gateway.config.impl.GatewayConfigImpl;
+import org.apache.hadoop.gateway.topology.Application;
+import org.apache.hadoop.gateway.topology.Service;
 import org.apache.hadoop.gateway.topology.Topology;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.apache.hadoop.test.TestUtils;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
 import org.junit.Test;
 import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.io.InputStream;
-
+import static junit.framework.TestCase.fail;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.hamcrest.xml.HasXPath.hasXPath;
 
 public class DeploymentFactoryTest {
 
-  @Test
-  public void testEmptyTopology() throws IOException, SAXException, ParserConfigurationException {
+  @Test( timeout = TestUtils.MEDIUM_TIMEOUT )
+  public void testEmptyTopology() throws IOException, SAXException, ParserConfigurationException, TransformerException {
     GatewayConfig config = new GatewayConfigImpl();
 
     Topology topology = new Topology();
-    topology.setName( "test-cluster" );
-
-    WebArchive war = DeploymentFactory.createDeployment( config, topology );
-    //File dir = new File( System.getProperty( "user.dir" ) );
-    //File file = war.as( ExplodedExporter.class ).exportExploded( dir, "test-cluster.war" );
-
-    Document wad = parse( war.get( "WEB-INF/web.xml" ).getAsset().openStream() );
-    assertThat( wad, hasXPath( "/web-app/servlet/servlet-name", equalTo( "test-cluster" ) ) );
-    assertThat( wad, hasXPath( "/web-app/servlet/servlet-class", equalTo( "org.apache.hadoop.gateway.GatewayServlet" ) ) );
-    assertThat( wad, hasXPath( "/web-app/servlet/init-param/param-name", equalTo( "gatewayDescriptorLocation" ) ) );
-    assertThat( wad, hasXPath( "/web-app/servlet/init-param/param-value", equalTo( "gateway.xml" ) ) );
-    assertThat( wad, hasXPath( "/web-app/servlet-mapping/servlet-name", equalTo( "test-cluster" ) ) );
-    assertThat( wad, hasXPath( "/web-app/servlet-mapping/url-pattern", equalTo( "/*" ) ) );
-
-    Document gateway = parse( war.get( "WEB-INF/gateway.xml" ).getAsset().openStream() );
-    assertThat( gateway, hasXPath( "/gateway" ) );
+    topology.setName( "test-topology" );
+
+    EnterpriseArchive archive = DeploymentFactory.createDeployment( config, topology );
+
+    Document xml = TestUtils.parseXml( archive.get( "/META-INF/topology.xml" ).getAsset().openStream() );
+    //TestUtils.dumpXml( xml );
+    assertThat( xml, hasXPath( "/topology/gateway" ) );
+    assertThat( xml, hasXPath( "/topology/name", equalTo( "test-topology" ) ) );
   }
 
-  private Document parse( InputStream stream ) throws IOException, SAXException, ParserConfigurationException {
-    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-    DocumentBuilder builder = factory.newDocumentBuilder();
-    InputSource source = new InputSource( stream );
-    return builder.parse( source );
+  @Test( timeout = TestUtils.SHORT_TIMEOUT )
+  public void test_validateNoAppsWithRootUrlsInServicesTopology() {
+    DeploymentFactory.validateNoAppsWithRootUrlsInServicesTopology( null );
+
+    Topology topology = new Topology();
+    topology.setName( "test-topology" );
+    DeploymentFactory.validateNoAppsWithRootUrlsInServicesTopology( topology );
+
+    Service service;
+    Application application;
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    service = new Service();
+    service.setName( "test-service" );
+    service.setRole( "test-service" );
+    topology.addService( service );
+    application = new Application();
+    application.setName( "test-application" );
+    topology.addApplication( application );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    service = new Service();
+    service.setName( "test-service" );
+    service.setRole( "test-service" );
+    topology.addService( service );
+    application = new Application();
+    application.setName( "test-application" );
+    application.addUrl( "" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithRootUrlsInServicesTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    service = new Service();
+    service.setName( "test-service" );
+    service.setRole( "test-service" );
+    topology.addService( service );
+    application = new Application();
+    application.setName( "test-application" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithRootUrlsInServicesTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    service = new Service();
+    service.setName( "test-service" );
+    service.setRole( "test-service" );
+    topology.addService( service );
+    application = new Application();
+    application.setName( "test-application" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithRootUrlsInServicesTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    service = new Service();
+    service.setName( "test-service" );
+    service.setRole( "test-service" );
+    topology.addService( service );
+    application = new Application();
+    application.setName( "test-application" );
+    application.addUrl( "/test-application" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithRootUrlsInServicesTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+  }
+
+  @Test( timeout = TestUtils.SHORT_TIMEOUT )
+  public void test_validateNoAppsWithDuplicateUrlsInTopology() {
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( null );
+
+    Topology topology = new Topology();
+    topology.setName( "test-topology" );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    Application application;
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    topology.addApplication( application );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/test-application-2" );
+    topology.addApplication( application );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    application.addUrl( "/test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/test-application-2" );
+    topology.addApplication( application );
+    DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    application.addUrl( "/test-application-dup" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/test-application-dup" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    application.addUrl( "" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/test-application-1" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-1" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
+    topology = new Topology();
+    topology.setName( "test-topology" );
+    application = new Application();
+    application.setName( "test-application-1" );
+    application.addUrl( "/test-application-1" );
+    application.addUrl( "/test-application-3" );
+    topology.addApplication( application );
+    application = new Application();
+    application.setName( "test-application-2" );
+    application.addUrl( "/test-application-2" );
+    application.addUrl( "/test-application-3" );
+    topology.addApplication( application );
+    try {
+      DeploymentFactory.validateNoAppsWithDuplicateUrlsInTopology( topology );
+      fail( "Expected DeploymentException" );
+    } catch ( DeploymentException e ) {
+      // Expected.
+    }
+
   }
 
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/java/org/apache/hadoop/gateway/jetty/JettyPathMapTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/jetty/JettyPathMapTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/jetty/JettyPathMapTest.java
index 749d2d6..6942234 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/jetty/JettyPathMapTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/jetty/JettyPathMapTest.java
@@ -17,33 +17,51 @@
  */
 package org.apache.hadoop.gateway.jetty;
 
-import org.apache.hadoop.test.category.UnitTests;
-import org.apache.hadoop.test.category.FastTests;
 import org.eclipse.jetty.http.PathMap;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
 
-import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
 
 /**
  *
  */
-@Category( { UnitTests.class, FastTests.class } )
+//@Category( { UnitTests.class, FastTests.class } )
 public class JettyPathMapTest {
 
-  @Ignore( "This doesn't work like I expected." )
-  @Test
+  //@Ignore( "This doesn't work like I expected." )
+  //@Test
   public void testPathMatching() {
-    PathMap map = new PathMap();
-    map.put( "/webhdfs", "/webhdfs" );
-    map.put( "/webhdfs/dfshealth.jsp", "/webhdfs/dfshealth.jsp" );
-    map.put( "/webhdfs/*", "/webhdfs/*" );
-
-    assertThat( (String)map.match( "/webhdfs" ), equalTo( "/webhdfs" ) );
-    assertThat( (String)map.match( "/webhdfs/dfshealth.jsp" ), equalTo( "/webhdfs/dfshealth.jsp" ) );
-    assertThat( (String)map.match( "/webhdfs/v1" ), equalTo( "/webhdfs/*" ) );
+    PathMap map;
+
+    map = new PathMap();
+    map.put( "/path", "/path" );
+    assertThat( (String)map.match("/path"), is("/path") );
+
+    map = new PathMap();
+    map.put( "/path", "/path" );
+    map.put( "/path/", "/path/" );
+    assertThat( (String)map.match("/path"), is("/path") );
+    assertThat( (String)map.match("/path/"), is("/path/") );
+
+    map = new PathMap();
+    map.put( "/path/*", "/path/*" );
+    map.put( "/path", "/path" );
+    map.put( "/path/", "/path/" );
+    assertThat( (String)map.match("/path"), is("/path") );
+    assertThat( (String)map.match("/path/"), is("/path/") );
+    assertThat( (String)map.match("/path/sub"), is("/path/*") );
+
+    map = new PathMap();
+    map.put( "/path", "/path" );
+    map.put( "/path/", "/path/" );
+    map.put( "/path/*", "/path/*" );
+    assertThat( (String)map.match( "/path/sub" ), is("/path/*") );
+
+    // Here the addition of the * path "overwrites" the exact matches.
+    // Above this worked if the /path and /path/ were added after /path/*.
+    assertThat( (String)map.match("/path"), is("/path") );
+    assertThat( (String)map.match("/path/"), is("/path/") );
+
   }
 
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest.java
new file mode 100644
index 0000000..3918b53
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest.java
@@ -0,0 +1,48 @@
+/**
+ * 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.topology.validation;
+
+import java.net.URL;
+
+import org.apache.hadoop.test.TestUtils;
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class TopologyValidatorTest {
+
+  @Test
+  public void testValidateApplications() throws Exception {
+    URL url;
+    TopologyValidator validator;
+
+    url = TestUtils.getResourceUrl( TopologyValidatorTest.class, "topology-valid-complete.xml" );
+    validator = new TopologyValidator( url );
+    assertThat( validator.getErrorString(), validator.validateTopology(), is( true ) );
+
+    url = TestUtils.getResourceUrl( TopologyValidatorTest.class, "topology-valid.xml" );
+    validator = new TopologyValidator( url );
+    assertThat( validator.getErrorString(), validator.validateTopology(), is( true ) );
+
+    url = TestUtils.getResourceUrl( TopologyValidatorTest.class, "topology-valid-with-name.xml" );
+    validator = new TopologyValidator( url );
+    assertThat( validator.getErrorString(), validator.validateTopology(), is( true ) );
+
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest.java
index 5981479..bb2c85e 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest.java
@@ -19,11 +19,13 @@ package org.apache.hadoop.gateway.topology.xml;
 
 import org.apache.commons.digester3.Digester;
 import org.apache.commons.digester3.binder.DigesterLoader;
+import org.apache.hadoop.gateway.topology.Application;
 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.topology.Version;
 import org.apache.hadoop.gateway.topology.builder.TopologyBuilder;
+import org.apache.hadoop.test.TestUtils;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -236,4 +238,25 @@ public class TopologyRulesModuleTest {
     assertThat( service.getParams(), hasEntry( is( "test-service-param-name-1" ), is( "test-service-param-value-1" ) ) );
     assertThat( service.getParams(), hasEntry( is( "test-service-param-name-2" ), is( "test-service-param-value-2" ) ) );
   }
+
+  @Test
+  public void testParseTopologyWithApplication() throws IOException, SAXException {
+    Digester digester = loader.newDigester();
+    String name = "topology-with-application.xml";
+    URL url = TestUtils.getResourceUrl( TopologyRulesModuleTest.class, name );
+    assertThat( "Failed to find URL for resource " + name, url, notNullValue() );
+    File file = new File( url.getFile() );
+    TopologyBuilder topologyBuilder = digester.parse( url );
+    Topology topology = topologyBuilder.build();
+    assertThat( "Failed to parse resource " + name, topology, notNullValue() );
+    topology.setTimestamp( file.lastModified() );
+
+    Application app = topology.getApplications().iterator().next();
+    assertThat( "Failed to find application", app, notNullValue() );
+    assertThat( app.getName(), is("test-app-name") );
+    assertThat( app.getUrl(), is("test-app-path") );
+    assertThat( app.getUrls().get( 0 ), is("test-app-path") );
+    assertThat( app.getParams().get( "test-param-name" ), is( "test-param-value" ) );
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-complete.xml
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-complete.xml b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-complete.xml
new file mode 100644
index 0000000..ec38a81
--- /dev/null
+++ b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-complete.xml
@@ -0,0 +1,40 @@
+<!--
+  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.
+-->
+<topology>
+    <name>topology-name</name>
+    <gateway>
+        <provider>
+            <role>test-provider-role</role>
+            <name>test-provider-name</name>
+            <enabled>true</enabled>
+        </provider>
+    </gateway>
+    <service>
+        <role>test-service-role</role>
+    </service>
+    <service>
+        <role>test-service-role</role>
+        <url>test-service-url</url>
+    </service>
+    <application>
+        <name>test-app-name</name>
+    </application>
+    <application>
+        <name>test-app-name</name>
+        <url>test-app-url</url>
+    </application>
+</topology>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-with-name.xml
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-with-name.xml b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-with-name.xml
new file mode 100644
index 0000000..7d5a697
--- /dev/null
+++ b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid-with-name.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+-->
+<topology>
+    <name>topology-name</name>
+</topology>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid.xml
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid.xml b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid.xml
new file mode 100644
index 0000000..057bcbb
--- /dev/null
+++ b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/validation/TopologyValidatorTest/topology-valid.xml
@@ -0,0 +1,25 @@
+<!--
+  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.
+-->
+<topology>
+    <application>
+        <name>test-application-name</name>
+    </application>
+    <application>
+        <name>test-application-name</name>
+        <url>test-application-path</url>
+    </application>
+</topology>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest/topology-with-application.xml
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest/topology-with-application.xml b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest/topology-with-application.xml
new file mode 100644
index 0000000..e6143d5
--- /dev/null
+++ b/gateway-server/src/test/resources/org/apache/hadoop/gateway/topology/xml/TopologyRulesModuleTest/topology-with-application.xml
@@ -0,0 +1,23 @@
+<!--
+  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.
+-->
+<topology>
+    <application>
+        <name>test-app-name</name>
+        <url>test-app-path</url>
+        <param name="test-param-name" value="test-param-value"/>
+    </application>
+</topology>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-service-admin/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-admin/pom.xml b/gateway-service-admin/pom.xml
index d63ff11..4a043fe 100644
--- a/gateway-service-admin/pom.xml
+++ b/gateway-service-admin/pom.xml
@@ -64,5 +64,10 @@
           <artifactId>easymock</artifactId>
           <scope>test</scope>
       </dependency>
+      <dependency>
+          <groupId>org.xmlmatchers</groupId>
+          <artifactId>xml-matchers</artifactId>
+          <scope>test</scope>
+      </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-service-admin/src/test/java/org/apache/hadoop/gateway/service/admin/TopologyMarshallerTest.java
----------------------------------------------------------------------
diff --git a/gateway-service-admin/src/test/java/org/apache/hadoop/gateway/service/admin/TopologyMarshallerTest.java b/gateway-service-admin/src/test/java/org/apache/hadoop/gateway/service/admin/TopologyMarshallerTest.java
new file mode 100644
index 0000000..ba62cf2
--- /dev/null
+++ b/gateway-service-admin/src/test/java/org/apache/hadoop/gateway/service/admin/TopologyMarshallerTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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.service.admin;
+
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+import org.apache.hadoop.gateway.topology.Application;
+import org.apache.hadoop.gateway.topology.Topology;
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.xmlmatchers.transform.XmlConverters.the;
+import static org.xmlmatchers.xpath.HasXPath.hasXPath;
+import static org.xmlmatchers.xpath.XpathReturnType.returningAString;
+
+public class TopologyMarshallerTest {
+
+  @Test
+  public void testTopologyMarshalling() throws Exception {
+    Topology topology = new Topology();
+    Application app = new Application();
+    app.setName( "test-app-name" );
+    topology.addApplication( app );
+
+    StringWriter writer = new StringWriter();
+    String xml;
+
+    Map<String,Object> properties = new HashMap<String,Object>(2);
+    properties.put( "eclipselink-oxm-xml", "org/apache/hadoop/gateway/topology/topology_binding-xml.xml" );
+    properties.put( "eclipselink.media-type", "application/xml" );
+    JAXBContext jaxbContext = JAXBContext.newInstance( Topology.class.getPackage().getName(), Topology.class.getClassLoader() , properties );
+    Marshaller marshaller = jaxbContext.createMarshaller();
+    marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
+    marshaller.marshal( topology, writer );
+    writer.close();
+    xml = writer.toString();
+    assertThat( the( xml ), hasXPath( "/topology/application/name", returningAString(), is("test-app-name") ) );
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
----------------------------------------------------------------------
diff --git a/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
index 0d26301..5ed4a21 100644
--- a/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
+++ b/gateway-service-test/src/main/java/org/apache/hadoop/gateway/service/test/ServiceTestResource.java
@@ -17,6 +17,26 @@
  */
 package org.apache.hadoop.gateway.service.test;
 
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.SSLContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+
 import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.hadoop.gateway.services.GatewayServices;
 import org.apache.hadoop.gateway.services.topology.TopologyService;
@@ -31,32 +51,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.glassfish.jersey.internal.util.Base64;
 
-import javax.net.ssl.SSLContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static javax.ws.rs.core.MediaType.APPLICATION_XML;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
-import static javax.ws.rs.core.Response.ok;
-import static javax.ws.rs.core.Response.status;
 
 @Path( "/service-test" )
 public class ServiceTestResource {
@@ -297,7 +293,7 @@ public class ServiceTestResource {
       this.serviceName = s.getRole();
     }
 
-    public ServiceTest(Service s, String requestURL) {
+    public ServiceTest( Service s, String requestURL) {
       this.serviceName = s.getRole();
       this.requestURL = requestURL;
     }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-spi/pom.xml b/gateway-spi/pom.xml
index 9454536..6c55072 100644
--- a/gateway-spi/pom.xml
+++ b/gateway-spi/pom.xml
@@ -59,10 +59,16 @@
             <groupId>org.apache.hadoop</groupId>
             <artifactId>hadoop-common</artifactId>
         </dependency>
+        <!--
         <dependency>
             <groupId>org.eclipse.jetty.orbit</groupId>
             <artifactId>javax.servlet</artifactId>
         </dependency>
+        -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.jboss.shrinkwrap</groupId>
             <artifactId>shrinkwrap-api</artifactId>
@@ -138,6 +144,12 @@
             <artifactId>hamcrest-library</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity</artifactId>
+            <scope>test</scope>
+        </dependency>
+
 
     </dependencies>
 

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
index 7e30b72..475649d 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
@@ -59,6 +59,12 @@ public interface GatewayConfig {
    */
   String getGatewayServicesDir();
 
+  /**
+   * The location of the gateway applications's root directory
+   * @return The location of the gateway applications top level directory.
+   */
+  String getGatewayApplicationsDir();
+
   String getHadoopConfDir();
 
   String getGatewayHost();
@@ -119,4 +125,8 @@ public interface GatewayConfig {
 
   int getHttpServerResponseHeaderBuffer();
 
+  int getGatewayDeploymentsBackupVersionLimit();
+
+  long getGatewayDeploymentsBackupAgeLimit();
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/java/org/apache/hadoop/gateway/deploy/ServiceDeploymentContributorBase.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/deploy/ServiceDeploymentContributorBase.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/deploy/ServiceDeploymentContributorBase.java
index 8206b88..4508ad8 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/deploy/ServiceDeploymentContributorBase.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/deploy/ServiceDeploymentContributorBase.java
@@ -74,11 +74,14 @@ public abstract class ServiceDeploymentContributorBase extends DeploymentContrib
     }
   }
 
-  protected void addIdentityAssertionFilter(DeploymentContext context, Service service, ResourceDescriptor resource) {
-    context.contributeFilter( service, resource, "identity-assertion", null, null );
+  protected void addIdentityAssertionFilter( DeploymentContext context, Service service, ResourceDescriptor resource) {
+    if( topologyContainsProviderType( context, "authentication" ) ||
+        topologyContainsProviderType( context, "federation"  ) ) {
+      context.contributeFilter( service, resource, "identity-assertion", null, null );
+    }
   }
 
-  protected void addAuthorizationFilter(DeploymentContext context, Service service, ResourceDescriptor resource) {
+  protected void addAuthorizationFilter( DeploymentContext context, Service service, ResourceDescriptor resource) {
     if (topologyContainsProviderType(context, "authorization")) {
       context.contributeFilter( service, resource, "authorization", null, null );
     }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Application.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Application.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Application.java
new file mode 100644
index 0000000..1ae8962
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Application.java
@@ -0,0 +1,30 @@
+/**
+ * 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.topology;
+
+public class Application extends Service {
+
+  public String getRole() {
+    return getName();
+  }
+
+  public void setRole( String role ) {
+    setName( role );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Routable.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Routable.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Routable.java
new file mode 100644
index 0000000..f1b1c49
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Routable.java
@@ -0,0 +1,22 @@
+/**
+ * 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.topology;
+
+public class Routable {
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
index 955f72f..c698c4c 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
@@ -81,7 +81,7 @@ public class Service {
     return params;
   }
 
-  private Collection<Param> getParamsList(){
+  public Collection<Param> getParamsList(){
 
     ArrayList<Param> paramList = new ArrayList<Param>();
 
@@ -95,6 +95,14 @@ public class Service {
     return paramList;
   }
 
+  public void setParamsList( Collection<Param> params ) {
+    if( params != null ) {
+      for( Param param : params ) {
+        addParam( param );
+      }
+    }
+  }
+
   public void setParams(Map<String, String> params) {
     this.params = params;
   }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
index 7be8301..87f73df 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
@@ -35,8 +35,9 @@ public class Topology {
   public List<Provider> providerList = new ArrayList<Provider>();
   private Map<String,Map<String,Provider>> providerMap = new HashMap<String,Map<String,Provider>>();
   public List<Service> services = new ArrayList<Service>();
-
   private MultiKeyMap serviceMap;
+  private List<Application> applications = new ArrayList<Application>();
+  private Map<String,Application> applicationMap = new HashMap<String,Application>();
 
   public Topology() {
     serviceMap = MultiKeyMap.decorate(new HashedMap());
@@ -70,7 +71,7 @@ public class Topology {
     return services;
   }
 
-  public Service getService(String role, String name, Version version) {
+  public Service getService( String role, String name, Version version) {
     return (Service)serviceMap.get(role, name, version);
   }
 
@@ -79,6 +80,36 @@ public class Topology {
     serviceMap.put(service.getRole(), service.getName(), service.getVersion(), service);
   }
 
+  public Collection<Application> getApplications() {
+    return applications;
+  }
+
+  private static String fixApplicationUrl( String url ) {
+    if( url == null ) {
+      url = "/";
+    }
+    if( !url.startsWith( "/" ) ) {
+      url = "/" + url;
+    }
+    return url;
+  }
+
+  public Application getApplication(String url) {
+    return applicationMap.get( fixApplicationUrl( url ) );
+  }
+
+  public void addApplication( Application application ) {
+    applications.add( application );
+    List<String> urls = application.getUrls();
+    if( urls == null || urls.isEmpty() ) {
+      applicationMap.put( fixApplicationUrl( application.getName() ), application );
+    } else {
+      for( String url : application.getUrls() ) {
+        applicationMap.put( fixApplicationUrl( url ), application );
+      }
+    }
+  }
+
   public Collection<Provider> getProviders() {
     return providerList;
   }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/jaxb.index
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/jaxb.index b/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/jaxb.index
index 78e716f..3baf0c3 100644
--- a/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/jaxb.index
+++ b/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/jaxb.index
@@ -18,4 +18,5 @@
 Topology
 Param
 Service
+Application
 Provider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-json.xml
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-json.xml b/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-json.xml
index fe8613d..7fb301b 100644
--- a/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-json.xml
+++ b/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-json.xml
@@ -24,12 +24,13 @@ or more contributor license agreements.  See the NOTICE file
         element-form-default="QUALIFIED"/>
     <java-types>
         <java-type name="Topology" xml-accessor-type="NONE">
-            <xml-type prop-order="name providers services timestamp"/>
+            <xml-type prop-order="name providers services applications timestamp"/>
             <xml-root-element/>
-            <java-attributes prop-order="providers services">
+            <java-attributes prop-order="providers services applications">
+                <xml-element java-attribute="name" name="name"/>
                 <xml-element java-attribute="providers" name="providers"/>
                 <xml-element java-attribute="services" name="services"/>
-                <xml-element java-attribute="name" name="name"/>
+                <xml-element java-attribute="applications" name="applications"/>
                 <xml-element java-attribute="timestamp" name="timestamp"/>
             </java-attributes>
         </java-type>
@@ -46,6 +47,7 @@ or more contributor license agreements.  See the NOTICE file
         </java-type>
         <java-type name="Service" xml-accessor-type="NONE">
             <java-attributes>
+                <xml-element java-attribute="name" name="name"/>
                 <xml-element java-attribute="role" name="role"/>
                 <xml-element java-attribute="urls" name="urls"/>
                 <xml-variable-node java-attribute="paramsList" java-variable-attribute="name">
@@ -53,6 +55,7 @@ or more contributor license agreements.  See the NOTICE file
                 </xml-variable-node>
             </java-attributes>
         </java-type>
+        <java-type name="Application" xml-accessor-type="NONE"/>
         <java-type name="Param" xml-accessor-type="NONE">
             <java-attributes>
                 <xml-value java-attribute="value"/>

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-xml.xml
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-xml.xml b/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-xml.xml
index 6f397c5..50d8d58 100644
--- a/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-xml.xml
+++ b/gateway-spi/src/main/resources/org/apache/hadoop/gateway/topology/topology_binding-xml.xml
@@ -24,14 +24,16 @@ or more contributor license agreements.  See the NOTICE file
         element-form-default="QUALIFIED"/>
     <java-types>
         <java-type name="Topology" xml-accessor-type="NONE">
-            <xml-type prop-order="providers services"/>
+            <xml-type prop-order="name providers services applications"/>
             <xml-root-element/>
-            <java-attributes prop-order="providers services">
+            <java-attributes>
+                <xml-element java-attribute="name" name="name"/>
                 <xml-elements java-attribute="providers">
                     <xml-element name="provider"/>
                     <xml-element-wrapper name="gateway"/>
                 </xml-elements>
                 <xml-element java-attribute="services" name="service"/>
+                <xml-element java-attribute="applications" name="application"/>
             </java-attributes>
         </java-type>
         <java-type name="Provider" xml-accessor-type="NONE">
@@ -44,11 +46,13 @@ or more contributor license agreements.  See the NOTICE file
         </java-type>
         <java-type name="Service" xml-accessor-type="NONE">
             <java-attributes>
+                <xml-element java-attribute="name" name="name"/>
                 <xml-element java-attribute="role" name="role"/>
                 <xml-element java-attribute="urls" name="url"/>
                 <xml-element java-attribute="paramsList" name="param"/>
             </java-attributes>
         </java-type>
+        <java-type name="Application" xml-accessor-type="NONE"/>
         <java-type name="Param" xml-accessor-type="NONE">
             <java-attributes>
                 <xml-element java-attribute="name"/>

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 779eb2d..950952c 100644
--- a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -248,6 +248,11 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
    }
 
   @Override
+  public String getGatewayApplicationsDir() {
+    return gatewayHomeDir + "/conf/applications";
+  }
+
+  @Override
   public boolean isXForwardedEnabled() {
     return xForwardedEnabled;
   }
@@ -294,4 +299,14 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
     return 8*1024;
   }
 
+  @Override
+  public int getGatewayDeploymentsBackupVersionLimit() {
+    return Integer.MAX_VALUE;
+  }
+
+  @Override
+  public long getGatewayDeploymentsBackupAgeLimit() {
+    return Long.MAX_VALUE;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-test-utils/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test-utils/pom.xml b/gateway-test-utils/pom.xml
index eaf6f8f..4dc2790 100644
--- a/gateway-test-utils/pom.xml
+++ b/gateway-test-utils/pom.xml
@@ -91,11 +91,13 @@
             <artifactId>jetty-servlet</artifactId>
             <scope>provided</scope>
         </dependency>
+        <!--
         <dependency>
             <groupId>org.eclipse.jetty.orbit</groupId>
             <artifactId>javax.servlet</artifactId>
             <scope>provided</scope>
         </dependency>
+        -->
 
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
@@ -121,6 +123,12 @@
             <scope>provided</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
     </dependencies>
 
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-test-utils/src/main/java/org/apache/hadoop/test/TestUtils.java
----------------------------------------------------------------------
diff --git a/gateway-test-utils/src/main/java/org/apache/hadoop/test/TestUtils.java b/gateway-test-utils/src/main/java/org/apache/hadoop/test/TestUtils.java
index 2a78364..b6dfe54 100644
--- a/gateway-test-utils/src/main/java/org/apache/hadoop/test/TestUtils.java
+++ b/gateway-test-utils/src/main/java/org/apache/hadoop/test/TestUtils.java
@@ -17,22 +17,6 @@
  */
 package org.apache.hadoop.test;
 
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -42,12 +26,38 @@ import java.io.Reader;
 import java.io.StringWriter;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
+import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.URL;
+import java.util.Properties;
 import java.util.UUID;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 
 public class TestUtils {
 
+  public static final long SHORT_TIMEOUT = 1000L;
+  public static final long MEDIUM_TIMEOUT = 20 * 1000L;
+  public static final long LONG_TIMEOUT = 60 * 1000L;
+
   public static String getResourceName( Class clazz, String name ) {
     name = clazz.getName().replaceAll( "\\.", "/" ) + "/" + name;
     return name;
@@ -120,12 +130,16 @@ public class TestUtils {
 
   public static void LOG_ENTER() {
     StackTraceElement caller = Thread.currentThread().getStackTrace()[2];
+    System.out.flush();
     System.out.println( String.format( "Running %s#%s", caller.getClassName(), caller.getMethodName() ) );
+    System.out.flush();
   }
 
   public static void LOG_EXIT() {
     StackTraceElement caller = Thread.currentThread().getStackTrace()[2];
+    System.out.flush();
     System.out.println( String.format( "Exiting %s#%s", caller.getClassName(), caller.getMethodName() ) );
+    System.out.flush();
   }
 
   public static void awaitPortOpen( InetSocketAddress address, int timeout, int delay ) throws InterruptedException {
@@ -166,4 +180,46 @@ public class TestUtils {
     throw new IllegalStateException( "Timed out " + timeout + " waiting for URL " + url );
   }
 
+  public static String merge( String resource, Properties properties ) {
+    ClasspathResourceLoader loader = new ClasspathResourceLoader();
+    loader.getResourceStream( resource );
+
+    VelocityEngine engine = new VelocityEngine();
+    Properties config = new Properties();
+    config.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogSystem" );
+    config.setProperty( RuntimeConstants.RESOURCE_LOADER, "classpath" );
+    config.setProperty( "classpath.resource.loader.class", ClasspathResourceLoader.class.getName() );
+    engine.init( config );
+
+    VelocityContext context = new VelocityContext( properties );
+    Template template = engine.getTemplate( resource );
+    StringWriter writer = new StringWriter();
+    template.merge( context, writer );
+    return writer.toString();
+  }
+
+  public static String merge( Class base, String resource, Properties properties ) {
+    String baseResource = base.getName().replaceAll( "\\.", "/" );
+    String fullResource = baseResource + "/" + resource;
+    return merge( fullResource, properties );
+  }
+
+  public static int findFreePort() throws IOException {
+    ServerSocket socket = new ServerSocket(0);
+    int port = socket.getLocalPort();
+    socket.close();
+    return port;
+  }
+
+  public static void waitUntilNextSecond() {
+    long before = System.currentTimeMillis();
+    long wait;
+    while( ( wait = ( 1000 - ( System.currentTimeMillis() - before ) ) ) > 0 ) {
+      try {
+        Thread.sleep( wait );
+      } catch( InterruptedException e ) {
+        // Ignore.
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayAdminTopologyFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayAdminTopologyFuncTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayAdminTopologyFuncTest.java
index 6a7db25..e099141 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayAdminTopologyFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayAdminTopologyFuncTest.java
@@ -17,6 +17,20 @@
  */
 package org.apache.hadoop.gateway;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ServerSocket;
+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;
@@ -37,34 +51,19 @@ import org.hamcrest.MatcherAssert;
 import org.hamcrest.Matchers;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.ws.rs.core.MediaType;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.ServerSocket;
-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 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.CoreMatchers.containsString;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
@@ -134,7 +133,6 @@ public class GatewayAdminTopologyFuncTest {
     createNormalTopology().toStream( stream2 );
     stream.close();
 
-
     DefaultGatewayServices srvcs = new DefaultGatewayServices();
     Map<String,String> options = new HashMap<String,String>();
     options.put( "persist-master", "false" );
@@ -238,7 +236,6 @@ public class GatewayAdminTopologyFuncTest {
         .addTag( "role" ).addText( "identity-assertion" )
         .addTag( "enabled" ).addText( "true" )
         .addTag( "name" ).addText( "Default" ).gotoParent()
-        .addTag( "provider" )
         .gotoRoot()
         .addTag( "service" )
         .addTag( "role" ).addText( "KNOX" )
@@ -506,7 +503,7 @@ public class GatewayAdminTopologyFuncTest {
   }
 
   @Test( timeout = LONG_TIMEOUT )
-  public void testDeployTopology() throws ClassNotFoundException {
+  public void testDeployTopology() throws Exception {
     LOG_ENTER();
 
     Topology testTopology = createTestTopology();
@@ -519,42 +516,42 @@ public class GatewayAdminTopologyFuncTest {
     GatewayServices srvs = GatewayServer.getGatewayServices();
 
     TopologyService ts = srvs.getService(GatewayServices.TOPOLOGY_SERVICE);
-
-    assertThat(testTopology, not(nullValue()));
-    assertThat(testTopology.getName(), is("test-topology"));
-
-    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);
+    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();
   }


Mime
View raw message