You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by km...@apache.org on 2016/02/25 21:54:25 UTC
[5/5] knox git commit: [KNOX-670] - Knox should be able to sost
simple web apps
[KNOX-670] - Knox should be able to sost simple web apps
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/a70a3b56
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/a70a3b56
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/a70a3b56
Branch: refs/heads/master
Commit: a70a3b56cf54e1c1088d57bf7f4c1dbe06b291c4
Parents: 82539e4
Author: Kevin Minder <km...@apache.org>
Authored: Thu Feb 25 15:54:13 2016 -0500
Committer: Kevin Minder <km...@apache.org>
Committed: Thu Feb 25 15:54:13 2016 -0500
----------------------------------------------------------------------
CHANGES | 8 +
.../pom.xml | 5 +
.../pom.xml | 5 +
.../pom.xml | 5 +
gateway-provider-rewrite/pom.xml | 7 +
.../impl/xml/XmlUrlRewriteRulesExporter.java | 12 +-
gateway-provider-security-authc-anon/pom.xml | 6 -
gateway-provider-security-authz-acls/pom.xml | 2 +
gateway-provider-security-hadoopauth/pom.xml | 2 +
gateway-provider-security-jwt/pom.xml | 2 +
gateway-provider-security-picketlink/pom.xml | 2 +
gateway-provider-security-preauth/pom.xml | 2 +
gateway-provider-security-shiro/pom.xml | 2 +
gateway-provider-security-webappsec/pom.xml | 2 +
gateway-release/home/data/applications/README | 1 +
gateway-release/pom.xml | 4 +
gateway-server/pom.xml | 11 +
.../apache/hadoop/gateway/GatewayFilter.java | 46 +-
.../apache/hadoop/gateway/GatewayMessages.java | 37 +-
.../apache/hadoop/gateway/GatewayServer.java | 374 +++++++---
.../apache/hadoop/gateway/GatewayServlet.java | 130 +++-
.../gateway/config/impl/GatewayConfigImpl.java | 48 +-
.../gateway/deploy/DeploymentContextImpl.java | 8 +-
.../gateway/deploy/DeploymentFactory.java | 458 +++++++++----
.../impl/ApplicationDeploymentContributor.java | 214 ++++++
.../xml/XmlGatewayDescriptorExporter.java | 34 +-
.../gateway/filter/DefaultTopologyHandler.java | 104 +++
.../gateway/filter/GatewayHelloFilter.java | 45 ++
.../builder/BeanPropertyTopologyBuilder.java | 16 +
.../topology/validation/TopologyValidator.java | 27 +-
.../xml/KnoxFormatXmlTopologyRules.java | 11 +
.../org/apache/hadoop/gateway/util/KnoxCLI.java | 46 +-
.../gateway/util/ServiceDefinitionsLoader.java | 2 +-
.../src/main/resources/conf/topology-v1.xsd | 43 +-
.../hadoop/gateway/GatewayGlobalConfigTest.java | 16 +-
.../config/impl/GatewayConfigImplTest.groovy | 61 --
.../config/impl/GatewayConfigImplTest.java | 96 +++
.../gateway/deploy/DeploymentFactoryTest.java | 315 ++++++++-
.../hadoop/gateway/jetty/JettyPathMapTest.java | 52 +-
.../validation/TopologyValidatorTest.java | 48 ++
.../topology/xml/TopologyRulesModuleTest.java | 23 +
.../topology-valid-complete.xml | 40 ++
.../topology-valid-with-name.xml | 19 +
.../TopologyValidatorTest/topology-valid.xml | 25 +
.../topology-with-application.xml | 23 +
gateway-service-admin/pom.xml | 5 +
.../service/admin/TopologyMarshallerTest.java | 60 ++
.../service/test/ServiceTestResource.java | 46 +-
gateway-spi/pom.xml | 12 +
.../hadoop/gateway/config/GatewayConfig.java | 10 +
.../ServiceDeploymentContributorBase.java | 9 +-
.../hadoop/gateway/topology/Application.java | 30 +
.../hadoop/gateway/topology/Routable.java | 22 +
.../apache/hadoop/gateway/topology/Service.java | 10 +-
.../hadoop/gateway/topology/Topology.java | 35 +-
.../apache/hadoop/gateway/topology/jaxb.index | 1 +
.../gateway/topology/topology_binding-json.xml | 9 +-
.../gateway/topology/topology_binding-xml.xml | 8 +-
.../hadoop/gateway/GatewayTestConfig.java | 15 +
gateway-test-utils/pom.xml | 8 +
.../java/org/apache/hadoop/test/TestUtils.java | 88 ++-
.../gateway/GatewayAdminTopologyFuncTest.java | 107 ++-
.../hadoop/gateway/GatewayAppFuncTest.java | 685 +++++++++++++++++++
.../hadoop/gateway/GatewayDeployFuncTest.java | 28 +-
.../hadoop/gateway/GatewayTestConfig.java | 66 +-
.../org/apache/hadoop/gateway/TestServlet.java | 32 +
.../deploy/DeploymentFactoryFuncTest.java | 257 +++++--
.../test-apps/dynamic-app/WEB-INF/web.xml | 15 +
.../GatewayAppFuncTest/test-apps/readme.txt | 18 +
.../test-apps/static-hello-app/index.html | 24 +
.../test-apps/static-json-app/one.json | 3 +
.../test-apps/static-json-app/rewrite.xml | 17 +
.../test-apps/static-json-app/service.xml | 21 +
.../test-apps/static-xml-app/test.xml | 17 +
.../test-default-app-name-topology.xml | 53 ++
.../test-dynamic-app-topology.xml | 54 ++
.../test-multi-apps-topology.xml | 65 ++
.../test-naked-app-topology.xml | 33 +
.../test-static-hello-topology.xml | 54 ++
.../test-svcs-and-apps-topology.xml | 62 ++
.../GatewayAppFuncTest/test-svcs/readme.txt | 18 +
.../test-svcs/webhdfs/2.4.0/rewrite.xml | 70 ++
.../test-svcs/webhdfs/2.4.0/service.xml | 43 ++
.../gateway/GatewayAppFuncTest/users.ldif | 42 ++
.../test-apps/minimal-test-app/rewrite.xml | 17 +
.../test-apps/minimal-test-app/service.xml | 21 +
gateway-util-common/pom.xml | 16 +-
.../org/apache/hadoop/gateway/util/Urls.java | 56 ++
.../apache/hadoop/gateway/util/XmlUtils.java | 72 ++
.../apache/hadoop/gateway/util/UrlsTest.java | 28 +
gateway-util-urltemplate/pom.xml | 4 +-
pom.xml | 29 +-
92 files changed, 4164 insertions(+), 670 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index e5c7b63..8f364c3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,12 @@
------------------------------------------------------------------------------
+Release Notes - Apache Knox - Version 0.9.0
+------------------------------------------------------------------------------
+** New Feature
+ * [KNOX-670] - Knox should be able to sost simple web apps
+** Improvement
+** Bug
+
+------------------------------------------------------------------------------
Release Notes - Apache Knox - Version 0.8.0
------------------------------------------------------------------------------
** New Feature
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-rewrite-func-hostmap-static/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-func-hostmap-static/pom.xml b/gateway-provider-rewrite-func-hostmap-static/pom.xml
index f9e3583..545b500 100644
--- a/gateway-provider-rewrite-func-hostmap-static/pom.xml
+++ b/gateway-provider-rewrite-func-hostmap-static/pom.xml
@@ -103,6 +103,11 @@
<artifactId>easymock</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-provider-rewrite-func-service-registry/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-func-service-registry/pom.xml b/gateway-provider-rewrite-func-service-registry/pom.xml
index 7caddf2..52bbed5 100644
--- a/gateway-provider-rewrite-func-service-registry/pom.xml
+++ b/gateway-provider-rewrite-func-service-registry/pom.xml
@@ -70,6 +70,11 @@
<artifactId>gateway-test-utils</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-rewrite-step-encrypt-uri/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/pom.xml b/gateway-provider-rewrite-step-encrypt-uri/pom.xml
index 3e14f5a..101bb15 100644
--- a/gateway-provider-rewrite-step-encrypt-uri/pom.xml
+++ b/gateway-provider-rewrite-step-encrypt-uri/pom.xml
@@ -76,6 +76,11 @@
<artifactId>gateway-test-utils</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>${gateway-group}</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-rewrite/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/pom.xml b/gateway-provider-rewrite/pom.xml
index a25d2f3..243969e 100644
--- a/gateway-provider-rewrite/pom.xml
+++ b/gateway-provider-rewrite/pom.xml
@@ -60,10 +60,12 @@
<artifactId>gateway-spi</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>org.apache.commons</groupId>
@@ -151,6 +153,11 @@
<artifactId>easymock</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-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
index 707a75c..6fa92d5 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
@@ -22,6 +22,7 @@ import org.apache.hadoop.gateway.filter.rewrite.api.*;
import org.apache.hadoop.gateway.filter.rewrite.i18n.UrlRewriteMessages;
import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteRulesExporter;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
+import org.apache.hadoop.gateway.util.XmlUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -86,16 +87,7 @@ public class XmlUrlRewriteRulesExporter implements UrlRewriteRulesExporter, XmlR
}
}
- TransformerFactory transformerFactory = TransformerFactory.newInstance();
- transformerFactory.setAttribute( "indent-number", 2 );
- Transformer transformer = transformerFactory.newTransformer();
- //transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" );
- transformer.setOutputProperty( OutputKeys.STANDALONE, "yes" );
- transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
-
- StreamResult result = new StreamResult( writer );
- DOMSource source = new DOMSource(document);
- transformer.transform( source, result );
+ XmlUtils.writeXml( document, writer );
} catch( ParserConfigurationException e ) {
throw new IOException( e );
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-authc-anon/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-authc-anon/pom.xml b/gateway-provider-security-authc-anon/pom.xml
index cde18f1..c6203b3 100755
--- a/gateway-provider-security-authc-anon/pom.xml
+++ b/gateway-provider-security-authc-anon/pom.xml
@@ -46,11 +46,6 @@
</dependency>
<dependency>
- <groupId>org.eclipse.jetty.orbit</groupId>
- <artifactId>javax.servlet</artifactId>
- </dependency>
-
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
@@ -60,7 +55,6 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
-
<dependency>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-test-utils</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-authz-acls/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-authz-acls/pom.xml b/gateway-provider-security-authz-acls/pom.xml
index 210d925..1564144 100644
--- a/gateway-provider-security-authz-acls/pom.xml
+++ b/gateway-provider-security-authz-acls/pom.xml
@@ -35,10 +35,12 @@
<groupId>${gateway-group}</groupId>
<artifactId>gateway-util-common</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-hadoopauth/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-hadoopauth/pom.xml b/gateway-provider-security-hadoopauth/pom.xml
index ff04cef..8240dde 100755
--- a/gateway-provider-security-hadoopauth/pom.xml
+++ b/gateway-provider-security-hadoopauth/pom.xml
@@ -45,10 +45,12 @@
<artifactId>gateway-util-common</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>org.apache.hadoop</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/pom.xml b/gateway-provider-security-jwt/pom.xml
index e720ba2..ef0727e 100644
--- a/gateway-provider-security-jwt/pom.xml
+++ b/gateway-provider-security-jwt/pom.xml
@@ -46,10 +46,12 @@
<artifactId>gateway-util-common</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>commons-io</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-picketlink/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-picketlink/pom.xml b/gateway-provider-security-picketlink/pom.xml
index 1cf4eab..b20e93c 100644
--- a/gateway-provider-security-picketlink/pom.xml
+++ b/gateway-provider-security-picketlink/pom.xml
@@ -45,10 +45,12 @@
<artifactId>gateway-util-common</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>org.picketlink</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-preauth/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-preauth/pom.xml b/gateway-provider-security-preauth/pom.xml
index 6c238c9..cabe506 100644
--- a/gateway-provider-security-preauth/pom.xml
+++ b/gateway-provider-security-preauth/pom.xml
@@ -45,10 +45,12 @@
<artifactId>gateway-util-common</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>junit</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-shiro/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/pom.xml b/gateway-provider-security-shiro/pom.xml
index 7ec2da1..763e9ce 100644
--- a/gateway-provider-security-shiro/pom.xml
+++ b/gateway-provider-security-shiro/pom.xml
@@ -55,10 +55,12 @@
<artifactId>shrinkwrap-descriptors-api-javaee</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>org.apache.shiro</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-provider-security-webappsec/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/pom.xml b/gateway-provider-security-webappsec/pom.xml
index 01669e8..67c4b2d 100644
--- a/gateway-provider-security-webappsec/pom.xml
+++ b/gateway-provider-security-webappsec/pom.xml
@@ -50,10 +50,12 @@
<artifactId>cors-filter</artifactId>
</dependency>
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>junit</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-release/home/data/applications/README
----------------------------------------------------------------------
diff --git a/gateway-release/home/data/applications/README b/gateway-release/home/data/applications/README
new file mode 100644
index 0000000..149839b
--- /dev/null
+++ b/gateway-release/home/data/applications/README
@@ -0,0 +1 @@
+THIS DIRECTORY CAN CONTAIN APPLICATIONS THAT CAN BE REFERENCED FROM TOPOLOGIES.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index c3cb2af..f02d169 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -232,6 +232,10 @@
</dependency>
<dependency>
<groupId>${gateway-group}</groupId>
+ <artifactId>gateway-provider-security-authc-anon</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
<artifactId>gateway-provider-security-authz-acls</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml
index 516ef23..b3df024 100644
--- a/gateway-server/pom.xml
+++ b/gateway-server/pom.xml
@@ -64,10 +64,12 @@
<artifactId>javax.servlet-api</artifactId>
</dependency>
-->
+ <!--
<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
</dependency>
+ -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
@@ -190,6 +192,15 @@
<groupId>org.apache.knox</groupId>
<artifactId>gateway-server-xforwarded-filter</artifactId>
</dependency>
+ <dependency>
+ <groupId>net.lingala.zip4j</groupId>
+ <artifactId>zip4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ </dependency>
+
<!-- ********** ********** ********** ********** ********** ********** -->
<!-- ********** Test Dependencies ********** -->
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
index 98ad94e..da6ba61 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
@@ -89,30 +89,38 @@ public class GatewayFilter implements Filter {
@Override
public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain ) throws IOException, ServletException {
doFilter( servletRequest, servletResponse );
+ if( filterChain != null ) {
+ filterChain.doFilter( servletRequest, servletResponse );
+ }
}
- @SuppressWarnings("unckecked")
+ @SuppressWarnings("unchecked")
public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse ) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse)servletResponse;
//TODO: The resulting pathInfo + query needs to be added to the servlet context somehow so that filters don't need to rebuild it. This is done in HttpClientDispatch right now for example.
+ String servlet = httpRequest.getServletPath();
+ String path = httpRequest.getPathInfo();
String query = httpRequest.getQueryString();
- String path = httpRequest.getPathInfo() + ( query == null ? "" : "?" + query );
+ String requestPath = ( servlet == null ? "" : servlet ) + ( path == null ? "" : path );
+ String requestPathWithQuery = requestPath + ( query == null ? "" : "?" + query );
- Template pathTemplate;
+ Template pathWithQueryTemplate;
try {
- pathTemplate = Parser.parseLiteral( path );
+ pathWithQueryTemplate = Parser.parseLiteral( requestPathWithQuery );
} catch( URISyntaxException e ) {
throw new ServletException( e );
}
- String pathWithContext = httpRequest.getContextPath() + path;
- LOG.receivedRequest( httpRequest.getMethod(), pathTemplate );
+ String contextWithPathAndQuery = httpRequest.getContextPath() + requestPathWithQuery;
+ LOG.receivedRequest( httpRequest.getMethod(), requestPath );
- servletRequest.setAttribute( AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME, pathTemplate );
- servletRequest.setAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME, pathWithContext );
+ servletRequest.setAttribute(
+ AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME, pathWithQueryTemplate );
+ servletRequest.setAttribute(
+ AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME, contextWithPathAndQuery );
- Matcher<Chain>.Match match = chains.match( pathTemplate );
+ Matcher<Chain>.Match match = chains.match( pathWithQueryTemplate );
assignCorrelationRequestId();
// Populate Audit/correlation parameters
@@ -120,7 +128,9 @@ public class GatewayFilter implements Filter {
auditContext.setTargetServiceName( match == null ? null : match.getValue().getResourceRole() );
auditContext.setRemoteIp( servletRequest.getRemoteAddr() );
auditContext.setRemoteHostname( servletRequest.getRemoteHost() );
- auditor.audit( Action.ACCESS, pathWithContext, ResourceType.URI, ActionOutcome.UNAVAILABLE, RES.requestMethod(((HttpServletRequest)servletRequest).getMethod()));
+ auditor.audit(
+ Action.ACCESS, contextWithPathAndQuery, ResourceType.URI,
+ ActionOutcome.UNAVAILABLE, RES.requestMethod(((HttpServletRequest)servletRequest).getMethod()));
if( match != null ) {
Chain chain = match.getValue();
@@ -129,27 +139,27 @@ public class GatewayFilter implements Filter {
chain.doFilter( servletRequest, servletResponse );
} catch( IOException e ) {
LOG.failedToExecuteFilter( e );
- auditor.audit( Action.ACCESS, pathWithContext, ResourceType.URI, ActionOutcome.FAILURE );
+ auditor.audit( Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE );
throw e;
} catch( ServletException e ) {
LOG.failedToExecuteFilter( e );
- auditor.audit( Action.ACCESS, pathWithContext, ResourceType.URI, ActionOutcome.FAILURE );
+ auditor.audit( Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE );
throw e;
} catch( RuntimeException e ) {
LOG.failedToExecuteFilter( e );
- auditor.audit( Action.ACCESS, pathWithContext, ResourceType.URI, ActionOutcome.FAILURE );
+ auditor.audit( Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE );
throw e;
} catch( ThreadDeath e ) {
LOG.failedToExecuteFilter( e );
- auditor.audit( Action.ACCESS, pathWithContext, ResourceType.URI, ActionOutcome.FAILURE );
+ auditor.audit( Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE );
throw e;
} catch( Throwable e ) {
LOG.failedToExecuteFilter( e );
- auditor.audit( Action.ACCESS, pathWithContext, ResourceType.URI, ActionOutcome.FAILURE );
+ auditor.audit( Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE );
throw new ServletException( e );
}
} else {
- LOG.failedToMatchPath( path );
+ LOG.failedToMatchPath( requestPath );
httpResponse.setStatus( HttpServletResponse.SC_NOT_FOUND );
}
//KAM[ Don't do this or the Jetty default servlet will overwrite any response setup by the filter.
@@ -180,7 +190,7 @@ public class GatewayFilter implements Filter {
addHolder( holder );
}
-// public void addFilter( String path, String name, Class<WarDirFilter> clazz, Map<String,String> params ) throws URISyntaxException {
+// public void addFilter( String path, String name, Class<RegexDirFilter> clazz, Map<String,String> params ) throws URISyntaxException {
// Holder holder = new Holder( path, name, clazz, params );
// addHolder( holder );
// }
@@ -262,7 +272,7 @@ public class GatewayFilter implements Filter {
this.resourceRole = resourceRole;
}
-// private Holder( String path, String name, Class<WarDirFilter> clazz, Map<String,String> params ) throws URISyntaxException {
+// private Holder( String path, String name, Class<RegexDirFilter> clazz, Map<String,String> params ) throws URISyntaxException {
// this.path = path;
// this.template = Parser.parse( path );
// this.name = name;
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
index 7f68601..8ac83b2 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
@@ -89,6 +89,15 @@ public interface GatewayMessages {
@Message( level = MessageLevel.DEBUG, text = "Redeployed topology {0}." )
void redeployedTopology( String clusterName );
+ @Message( level = MessageLevel.INFO, text = "Activating topology {0}" )
+ void activatingTopology( String name );
+
+ @Message( level = MessageLevel.INFO, text = "Activating topology {0} archive {1}" )
+ void activatingTopologyArchive( String topology, String archive );
+
+ @Message( level = MessageLevel.INFO, text = "Deactivating topology {0}" )
+ void deactivatingTopology( String name );
+
@Message( level = MessageLevel.ERROR, text = "Failed to deploy topology {0}: {1}" )
void failedToDeployTopology( String name, @StackTrace(level=MessageLevel.DEBUG) Throwable e );
@@ -107,9 +116,18 @@ public interface GatewayMessages {
@Message( level = MessageLevel.ERROR, text = "Failed to undeploy topology {0}: {1}" )
void failedToUndeployTopology( String name, @StackTrace(level=MessageLevel.DEBUG) Exception e );
+ @Message( level = MessageLevel.INFO, text = "Deleting topology {0}" )
+ void deletingTopology( String topologyName );
+
@Message( level = MessageLevel.INFO, text = "Deleting deployed topology {0}" )
void deletingDeployment( String warDirName );
+ @Message( level = MessageLevel.DEBUG, text = "Purge backups of deployed topology {0}" )
+ void cleanupDeployments( String topologyName );
+
+ @Message( level = MessageLevel.INFO, text = "Deleting backup deployed topology {0}" )
+ void cleanupDeployment( String absolutePath );
+
@Message( level = MessageLevel.INFO, text = "Creating gateway home directory: {0}" )
void creatingGatewayHomeDir( File homeDir );
@@ -162,7 +180,7 @@ public interface GatewayMessages {
void credentialStoreForClusterFoundNotCreating(String clusterName);
@Message( level = MessageLevel.DEBUG, text = "Received request: {0} {1}" )
- void receivedRequest( String method, Template uri );
+ void receivedRequest( String method, String uri );
@Message( level = MessageLevel.DEBUG, text = "Dispatch request: {0} {1}" )
void dispatchRequest( String method, URI uri );
@@ -350,7 +368,7 @@ public interface GatewayMessages {
@Message( level = MessageLevel.DEBUG, text = "Finalize service: {1}/{0}" )
void finalizeService( String name, String role );
- @Message( level = MessageLevel.INFO, text = "Configured services directory is {0}" )
+ @Message( level = MessageLevel.DEBUG, text = "Configured services directory is {0}" )
void usingServicesDirectory(String path);
@Message( level = MessageLevel.ERROR, text = "Failed to unmarshall service definition file {0} file : {1}" )
@@ -376,4 +394,19 @@ public interface GatewayMessages {
@Message( level = MessageLevel.ERROR, text = "Unable to get password: {0}" )
void unableToGetPassword(@StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+ @Message( level = MessageLevel.DEBUG, text = "Initialize application: {0}" )
+ void initializeApplication( String name );
+
+ @Message( level = MessageLevel.DEBUG, text = "Contribute application: {0}" )
+ void contributeApplication( String name );
+
+ @Message( level = MessageLevel.DEBUG, text = "Finalize application: {0}" )
+ void finalizeApplication( String name );
+
+ @Message( level = MessageLevel.INFO, text = "Default topology {0} at {1}" )
+ void defaultTopologySetup( String defaultTopologyName, String redirectContext );
+
+ @Message( level = MessageLevel.DEBUG, text = "Default topology forward from {0} to {1}" )
+ void defaultTopologyForward( String oldTarget, String newTarget );
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
index 21fb9ea..a6943b6 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
@@ -17,10 +17,34 @@
*/
package org.apache.hadoop.gateway;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import net.lingala.zip4j.core.ZipFile;
+import net.lingala.zip4j.exception.ZipException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
import org.apache.hadoop.gateway.audit.api.Action;
import org.apache.hadoop.gateway.audit.api.ActionOutcome;
import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
@@ -29,20 +53,25 @@ import org.apache.hadoop.gateway.audit.api.ResourceType;
import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.config.impl.GatewayConfigImpl;
+import org.apache.hadoop.gateway.deploy.DeploymentException;
import org.apache.hadoop.gateway.deploy.DeploymentFactory;
import org.apache.hadoop.gateway.filter.CorrelationHandler;
+import org.apache.hadoop.gateway.filter.DefaultTopologyHandler;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
import org.apache.hadoop.gateway.i18n.resources.ResourcesFactory;
import org.apache.hadoop.gateway.services.GatewayServices;
import org.apache.hadoop.gateway.services.registry.ServiceRegistry;
import org.apache.hadoop.gateway.services.security.SSLService;
import org.apache.hadoop.gateway.services.topology.TopologyService;
+import org.apache.hadoop.gateway.topology.Application;
import org.apache.hadoop.gateway.topology.Topology;
import org.apache.hadoop.gateway.topology.TopologyEvent;
import org.apache.hadoop.gateway.topology.TopologyListener;
import org.apache.hadoop.gateway.trace.AccessHandler;
import org.apache.hadoop.gateway.trace.ErrorHandler;
import org.apache.hadoop.gateway.trace.TraceHandler;
+import org.apache.hadoop.gateway.util.Urls;
+import org.apache.hadoop.gateway.util.XmlUtils;
import org.apache.log4j.PropertyConfigurator;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
@@ -54,27 +83,12 @@ import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.ProviderException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.ServiceLoader;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
public class GatewayServer {
private static GatewayResources res = ResourcesFactory.get(GatewayResources.class);
@@ -220,21 +234,39 @@ public class GatewayServer {
return properties;
}
- private static void extractToFile( String resource, File file ) throws IOException {
- InputStream input = ClassLoader.getSystemResourceAsStream( resource );
- OutputStream output = new FileOutputStream( file );
- IOUtils.copy( input, output );
- output.close();
- input.close();
- }
-
-
public static void redeployTopologies( String topologyName ) {
TopologyService ts = getGatewayServices().getService(GatewayServices.TOPOLOGY_SERVICE);
ts.reloadTopologies();
ts.redeployTopologies(topologyName);
}
+ private void cleanupTopologyDeployments() {
+ File deployDir = new File( config.getGatewayDeploymentDir() );
+ TopologyService ts = getGatewayServices().getService(GatewayServices.TOPOLOGY_SERVICE);
+ for( Topology topology : ts.getTopologies() ) {
+ cleanupTopologyDeployments( deployDir, topology );
+ }
+ }
+
+ private void cleanupTopologyDeployments( File deployDir, Topology topology ) {
+ log.cleanupDeployments( topology.getName() );
+ File[] files = deployDir.listFiles( new RegexDirFilter( topology.getName() + "\\.(war|topo)\\.[0-9A-Fa-f]+" ) );
+ if( files != null ) {
+ Arrays.sort( files, new FileModificationTimeDescendingComparator() );
+ int verLimit = config.getGatewayDeploymentsBackupVersionLimit();
+ long ageLimit = config.getGatewayDeploymentsBackupAgeLimit();
+ long keepTime = System.currentTimeMillis() - ageLimit;
+ for( int i=1; i<files.length; i++ ) {
+ File file = files[i];
+ if( ( ( verLimit >= 0 ) && ( i > verLimit ) ) ||
+ ( ( ageLimit >= 0 ) && ( file.lastModified() < keepTime ) ) ) {
+ log.cleanupDeployment( file.getAbsolutePath() );
+ FileUtils.deleteQuietly( file );
+ }
+ }
+ }
+ }
+
public static GatewayServer startGateway( GatewayConfig config, GatewayServices svcs ) throws Exception {
log.startingGateway();
server = new GatewayServer( config );
@@ -287,7 +319,10 @@ public class GatewayServer {
return connector;
}
- private static HandlerCollection createHandlers( final GatewayConfig config, final ContextHandlerCollection contexts ) {
+ private static HandlerCollection createHandlers(
+ final GatewayConfig config,
+ final GatewayServices services,
+ final ContextHandlerCollection contexts ) {
HandlerCollection handlers = new HandlerCollection();
RequestLogHandler logHandler = new RequestLogHandler();
logHandler.setRequestLog( new AccessHandler() );
@@ -299,11 +334,16 @@ public class GatewayServer {
CorrelationHandler correlationHandler = new CorrelationHandler();
correlationHandler.setHandler( traceHandler );
- handlers.setHandlers( new Handler[]{ correlationHandler, logHandler } );
+ DefaultTopologyHandler defaultTopoHandler = new DefaultTopologyHandler( config, services, contexts );
+
+ handlers.setHandlers( new Handler[]{ correlationHandler, defaultTopoHandler, logHandler } );
return handlers;
}
private synchronized void start() throws Exception {
+ errorHandler = new ErrorHandler();
+ errorHandler.setShowStacks( false );
+ errorHandler.setTracedBodyFilter( System.getProperty( "org.apache.knox.gateway.trace.body.status.filter" ) );
// Create the global context handler.
contexts = new ContextHandlerCollection();
@@ -313,9 +353,16 @@ public class GatewayServer {
// Start Jetty.
jetty = new Server();
jetty.addConnector( createConnector( config ) );
- jetty.setHandler( createHandlers( config, contexts ) );
+ jetty.setHandler( createHandlers( config, services, contexts ) );
jetty.setThreadPool( new QueuedThreadPool( config.getThreadPoolMax() ) );
+ // Load the current topologies.
+ File topologiesDir = calculateAbsoluteTopologiesDir();
+ log.loadingTopologiesFromDirectory(topologiesDir.getAbsolutePath());
+ monitor = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ monitor.addTopologyChangeListener(listener);
+ monitor.reloadTopologies();
+
try {
jetty.start();
}
@@ -324,14 +371,7 @@ public class GatewayServer {
throw e;
}
- // Create a dir/file based cluster topology provider.
- File topologiesDir = calculateAbsoluteTopologiesDir();
- monitor = services.getService(GatewayServices.TOPOLOGY_SERVICE);
- monitor.addTopologyChangeListener(listener);
-
- // Load the current topologies.
- log.loadingTopologiesFromDirectory(topologiesDir.getAbsolutePath());
- monitor.reloadTopologies();
+ cleanupTopologyDeployments();
// Start the topology monitor.
log.monitoringTopologyChangesInDirectory(topologiesDir.getAbsolutePath());
@@ -361,53 +401,158 @@ public class GatewayServer {
return addresses;
}
- private synchronized void internalDeploy( Topology topology, File warFile ) {
- String name = topology.getName();
- String warPath = warFile.getAbsolutePath();
- errorHandler = new ErrorHandler();
- errorHandler.setShowStacks(false);
- errorHandler.setTracedBodyFilter( System.getProperty( "org.apache.knox.gateway.trace.body.status.filter" ) );
+ private WebAppContext createWebAppContext( Topology topology, File warFile, String warPath ) throws IOException, ZipException, TransformerException, SAXException, ParserConfigurationException {
+ String topoName = topology.getName();
WebAppContext context = new WebAppContext();
- context.setDefaultsDescriptor( null );
- if (!name.equals("_default")) {
- context.setContextPath( "/" + config.getGatewayPath() + "/" + name );
- }
- else {
- context.setContextPath( "/" );
- }
- context.setWar( warPath );
- context.setErrorHandler(errorHandler);
- // internalUndeploy( topology ); KNOX-152
- context.setAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE, name );
+ String contextPath;
+ contextPath = "/" + Urls.trimLeadingAndTrailingSlashJoin( config.getGatewayPath(), topoName, warPath );
+ context.setContextPath( contextPath );
+ context.setWar( warFile.getAbsolutePath() );
+ context.setAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE, topoName );
context.setAttribute( "org.apache.knox.gateway.frontend.uri", getFrontendUri( context, config ) );
context.setAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE, config );
- deployments.put( name, context );
- contexts.addHandler( context );
- try {
- context.start();
- } catch( Exception e ) {
- auditor
- .audit(Action.DEPLOY, topology.getName(), ResourceType.TOPOLOGY, ActionOutcome.FAILURE);
- log.failedToDeployTopology( name, e );
+ context.setTempDirectory( warFile );
+ context.setErrorHandler( errorHandler );
+ return context;
+ }
+
+ private static void explodeWar( File source, File target ) throws IOException, ZipException {
+ if( source.isDirectory() ) {
+ FileUtils.copyDirectory( source, target );
+ } else {
+ ZipFile zip = new ZipFile( source );
+ zip.extractAll( target.getAbsolutePath() );
+ }
+ }
+
+ private void mergeWebXmlOverrides( File webInfDir ) throws IOException, SAXException, ParserConfigurationException, TransformerException {
+ File webXmlFile = new File( webInfDir, "web.xml" );
+ Document webXmlDoc;
+ if( webXmlFile.exists() ) {
+ // Backup original web.xml file.
+ File originalWebXmlFile = new File( webInfDir, "original-web.xml" );
+ FileUtils.copyFile( webXmlFile, originalWebXmlFile );
+ webXmlDoc = XmlUtils.readXml( webXmlFile );
+ } else {
+ webXmlDoc = XmlUtils.createDocument();
+ webXmlDoc.appendChild( webXmlDoc.createElement( "web-app" ) );
+ }
+ File overrideWebXmlFile = new File( webInfDir, "override-web.xml" );
+ if( overrideWebXmlFile.exists() ) {
+ Document overrideWebXmlDoc = XmlUtils.readXml( overrideWebXmlFile );
+ Element originalRoot = webXmlDoc.getDocumentElement();
+ Element overrideRoot = overrideWebXmlDoc.getDocumentElement();
+ NodeList overrideNodes = overrideRoot.getChildNodes();
+ for( int i = 0, n = overrideNodes.getLength(); i < n; i++ ) {
+ Node overrideNode = overrideNodes.item( i );
+ if( overrideNode.getNodeType() == Node.ELEMENT_NODE ) {
+ Node importedNode = webXmlDoc.importNode( overrideNode, true );
+ originalRoot.appendChild( importedNode );
+ }
+ }
+ XmlUtils.writeXml( webXmlDoc, webXmlFile );
+ }
+ }
+
+ private synchronized void internalDeployApplications( Topology topology, File topoDir ) throws IOException, ZipException, ParserConfigurationException, TransformerException, SAXException {
+ if( topology != null ) {
+ Collection<Application> applications = topology.getApplications();
+ if( applications != null ) {
+ for( Application application : applications ) {
+ List<String> urls = application.getUrls();
+ if( urls == null || urls.isEmpty() ) {
+ internalDeployApplication( topology, topoDir, application, application.getName() );
+ } else {
+ for( String url : urls ) {
+ internalDeployApplication( topology, topoDir, application, url );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private synchronized void internalDeployApplication( Topology topology, File topoDir, Application application, String url ) throws IOException, ZipException, TransformerException, SAXException, ParserConfigurationException {
+ File appsDir = new File( config.getGatewayApplicationsDir() );
+ File appDir = new File( appsDir, application.getName() );
+ if( !appDir.exists() ) {
+ appDir = new File( appsDir, application.getName() + ".war" );
+ }
+ if( !appDir.exists() ) {
+ throw new DeploymentException( "Application archive does not exist: " + appDir.getAbsolutePath() );
+ }
+ File warFile = new File( topoDir, Urls.encode( "/" + Urls.trimLeadingAndTrailingSlash( url ) ) );
+ File webInfDir = new File( warFile, "WEB-INF" );
+ explodeWar( appDir, warFile );
+ mergeWebXmlOverrides( webInfDir );
+ }
+
+ private synchronized void internalActivateTopology( Topology topology, File topoDir ) throws IOException, ZipException, ParserConfigurationException, TransformerException, SAXException {
+ log.activatingTopology( topology.getName() );
+ File[] files = topoDir.listFiles( new RegexDirFilter( "%.*" ) );
+ if( files != null ) {
+ for( File file : files ) {
+ internalActivateArchive( topology, file );
+ }
}
}
- private synchronized void internalUndeploy( Topology topology ) {
- WebAppContext context = deployments.remove( topology.getName() );
- if( context != null ) {
- ServiceRegistry sr = getGatewayServices().getService(GatewayServices.SERVICE_REGISTRY_SERVICE);
- if (sr != null) {
- sr.removeClusterServices(topology.getName());
+ private synchronized void internalActivateArchive( Topology topology, File warDir ) throws IOException, ZipException, ParserConfigurationException, TransformerException, SAXException {
+ log.activatingTopologyArchive( topology.getName(), warDir.getName() );
+ WebAppContext newContext = createWebAppContext( topology, warDir, Urls.decode( warDir.getName() ) );
+ WebAppContext oldContext = deployments.get( newContext.getContextPath() );
+ deployments.put( newContext.getContextPath(), newContext );
+ if( oldContext != null ) {
+ contexts.removeHandler( oldContext );
+ }
+ contexts.addHandler( newContext );
+ if( contexts.isRunning() ) {
+ try {
+ newContext.start();
+ } catch( Exception e ) {
+ auditor.audit( Action.DEPLOY, topology.getName(), ResourceType.TOPOLOGY, ActionOutcome.FAILURE );
+ log.failedToDeployTopology( topology.getName(), e );
+ }
+ }
+ }
+
+ private synchronized void internalDeactivateTopology( Topology topology ) {
+
+ log.deactivatingTopology( topology.getName() );
+
+ String topoName = topology.getName();
+ String topoPath = "/" + Urls.trimLeadingAndTrailingSlashJoin( config.getGatewayPath(), topoName );
+ String topoPathSlash = topoPath + "/";
+
+ ServiceRegistry sr = getGatewayServices().getService(GatewayServices.SERVICE_REGISTRY_SERVICE);
+ if (sr != null) {
+ sr.removeClusterServices( topoName );
+ }
+
+ // Find all the deployed contexts we need to deactivate.
+ List<WebAppContext> deactivate = new ArrayList<WebAppContext>();
+ if( deployments != null ) {
+ for( WebAppContext app : deployments.values() ) {
+ String appPath = app.getContextPath();
+ if( appPath.equals( topoPath ) || appPath.startsWith( topoPathSlash ) ) {
+ deactivate.add( app );
+ }
}
- contexts.removeHandler( context ) ;
+ }
+ // Deactivate the required deployed contexts.
+ for( WebAppContext context : deactivate ) {
+ String contextPath = context.getContextPath();
+ deployments.remove( contextPath );
+ contexts.removeHandler( context );
try {
context.stop();
} catch( Exception e ) {
- auditor.audit(Action.UNDEPLOY, topology.getName(), ResourceType.TOPOLOGY,
- ActionOutcome.FAILURE);
+ auditor.audit(Action.UNDEPLOY, topology.getName(), ResourceType.TOPOLOGY, ActionOutcome.FAILURE);
log.failedToUndeployTopology( topology.getName(), e );
}
}
+ deactivate.clear();
+
}
// Using an inner class to hide the handleTopologyEvent method from consumers of GatewayServer.
@@ -429,13 +574,14 @@ public class GatewayServer {
}
private void handleDeleteDeployment(Topology topology, File deployDir) {
- File[] files = deployDir.listFiles( new WarDirFilter( topology.getName() + "\\.war\\.[0-9A-Fa-f]+" ) );
+ log.deletingTopology( topology.getName() );
+ File[] files = deployDir.listFiles( new RegexDirFilter( topology.getName() + "\\.(war|topo)\\.[0-9A-Fa-f]+" ) );
if( files != null ) {
auditor.audit(Action.UNDEPLOY, topology.getName(), ResourceType.TOPOLOGY,
ActionOutcome.UNAVAILABLE);
+ internalDeactivateTopology( topology );
for( File file : files ) {
log.deletingDeployment( file.getAbsolutePath() );
- internalUndeploy( topology );
FileUtils.deleteQuietly( file );
}
}
@@ -443,48 +589,47 @@ public class GatewayServer {
private void handleCreateDeployment(Topology topology, File deployDir) {
try {
- File warDir = calculateDeploymentDir( topology );
- if( !warDir.exists() ) {
+ File topoDir = calculateDeploymentDir( topology );
+ if( !topoDir.exists() ) {
auditor.audit( Action.DEPLOY, topology.getName(), ResourceType.TOPOLOGY, ActionOutcome.UNAVAILABLE );
// KNOX-564 - Topology should fail to deploy with no providers configured.
+//TODO:APPS:This should only fail if there are services in the topology.
if(topology.getProviders().isEmpty()) {
- throw new ProviderException("No providers found inside topology.");
+ throw new DeploymentException("No providers found inside topology.");
}
- log.deployingTopology( topology.getName(), warDir.getAbsolutePath() );
- internalUndeploy( topology ); // KNOX-152
- WebArchive war = null;
- war = DeploymentFactory.createDeployment( config, topology );
+ log.deployingTopology( topology.getName(), topoDir.getAbsolutePath() );
+ internalDeactivateTopology( topology ); // KNOX-152
+
+ EnterpriseArchive ear = DeploymentFactory.createDeployment( config, topology );
if( !deployDir.exists() ) {
deployDir.mkdirs();
+ if( !deployDir.exists() ) {
+ throw new DeploymentException( "Failed to create topology deployment temporary directory: " + deployDir.getAbsolutePath() );
+ }
+ }
+ File tmp = ear.as( ExplodedExporter.class ).exportExploded( deployDir, topoDir.getName() + ".tmp" );
+ if( !tmp.renameTo( topoDir ) ) {
+ FileUtils.deleteQuietly( tmp );
+ throw new DeploymentException( "Failed to create topology deployment directory: " + topoDir.getAbsolutePath() );
}
- File tmp = war.as( ExplodedExporter.class ).exportExploded( deployDir, warDir.getName() + ".tmp" );
- tmp.renameTo( warDir );
- internalDeploy( topology, warDir );
- handleDefaultTopology(topology, deployDir);
+ internalDeployApplications( topology, topoDir );
+ internalActivateTopology( topology, topoDir );
log.deployedTopology( topology.getName());
} else {
auditor.audit( Action.REDEPLOY, topology.getName(), ResourceType.TOPOLOGY, ActionOutcome.UNAVAILABLE );
- log.redeployingTopology( topology.getName(), warDir.getAbsolutePath() );
- internalDeploy( topology, warDir );
- handleDefaultTopology(topology, deployDir);
+ log.redeployingTopology( topology.getName(), topoDir.getAbsolutePath() );
+ internalActivateTopology( topology, topoDir );
log.redeployedTopology( topology.getName() );
}
+ cleanupTopologyDeployments( deployDir, topology );
} catch( Throwable e ) {
auditor.audit( Action.DEPLOY, topology.getName(), ResourceType.TOPOLOGY, ActionOutcome.FAILURE );
log.failedToDeployTopology( topology.getName(), e );
}
}
- public void handleDefaultTopology(Topology topology, File deployDir) {
- if (topology.getName().equals(config.getDefaultTopologyName())) {
- topology.setName("_default");
- handleCreateDeployment(topology, deployDir);
- topology.setName(config.getDefaultTopologyName());
- }
- }
-
}
private static File calculateAbsoluteTopologiesDir( GatewayConfig config ) {
@@ -508,12 +653,16 @@ public class GatewayServer {
}
private File calculateDeploymentDir( Topology topology ) {
- File warDir = new File( calculateAbsoluteDeploymentsDir(), calculateDeploymentName( topology ) );
- return warDir;
+ File dir = new File( calculateAbsoluteDeploymentsDir(), calculateDeploymentName( topology ) );
+ return dir;
+ }
+
+ private String calculateDeploymentExtension( Topology topology ) {
+ return ".topo.";
}
private String calculateDeploymentName( Topology topology ) {
- String name = topology.getName() + ".war." + Long.toHexString( topology.getTimestamp() );
+ String name = topology.getName() + calculateDeploymentExtension( topology ) + Long.toHexString( topology.getTimestamp() );
return name;
}
@@ -523,11 +672,11 @@ public class GatewayServer {
socket.close();
}
- private class WarDirFilter implements FilenameFilter {
+ private class RegexDirFilter implements FilenameFilter {
Pattern pattern;
- WarDirFilter( String regex ) {
+ RegexDirFilter( String regex ) {
pattern = Pattern.compile( regex );
}
@@ -556,4 +705,19 @@ public class GatewayServer {
return frontendUri;
}
+ private static class FileModificationTimeDescendingComparator implements Comparator<File> {
+ @Override
+ public int compare( File left, File right ) {
+ long leftTime = ( left == null ? Long.MIN_VALUE : left.lastModified() );
+ long rightTime = ( right == null ? Long.MIN_VALUE : right.lastModified() );
+ if( leftTime > rightTime ) {
+ return -1;
+ } else if ( leftTime < rightTime ) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
index 6eea100..cb9f7a5 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServlet.java
@@ -17,6 +17,22 @@
*/
package org.apache.hadoop.gateway;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URISyntaxException;
+import java.util.Enumeration;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.hadoop.gateway.audit.api.Action;
import org.apache.hadoop.gateway.audit.api.ActionOutcome;
import org.apache.hadoop.gateway.audit.api.AuditService;
@@ -29,25 +45,8 @@ import org.apache.hadoop.gateway.descriptor.GatewayDescriptorFactory;
import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
import org.apache.hadoop.gateway.i18n.resources.ResourcesFactory;
-import org.apache.hadoop.gateway.services.GatewayServices;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterConfig;
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URISyntaxException;
-import java.util.Enumeration;
-
-public class GatewayServlet implements Servlet {
+public class GatewayServlet implements Servlet, Filter {
public static final String GATEWAY_DESCRIPTOR_LOCATION_DEFAULT = "gateway.xml";
public static final String GATEWAY_DESCRIPTOR_LOCATION_PARAM = "gatewayDescriptorLocation";
@@ -107,6 +106,24 @@ public class GatewayServlet implements Servlet {
}
@Override
+ public void init( FilterConfig filterConfig ) throws ServletException {
+ try {
+ if( filter == null ) {
+ filter = createFilter( filterConfig );
+ }
+ if( filter != null ) {
+ filter.init( filterConfig );
+ }
+ } catch( ServletException e ) {
+ LOG.failedToInitializeServletInstace( e );
+ throw e;
+ } catch( RuntimeException e ) {
+ LOG.failedToInitializeServletInstace( e );
+ throw e;
+ }
+ }
+
+ @Override
public ServletConfig getServletConfig() {
return filterConfig.getServletConfig();
}
@@ -118,7 +135,38 @@ public class GatewayServlet implements Servlet {
GatewayFilter f = filter;
if( f != null ) {
try {
+ f.doFilter( servletRequest, servletResponse, null );
+ } catch( IOException e ) {
+ LOG.failedToExecuteFilter( e );
+ throw e;
+ } catch( ServletException e ) {
+ LOG.failedToExecuteFilter( e );
+ throw e;
+ } catch( RuntimeException e ) {
+ LOG.failedToExecuteFilter( e );
+ throw e;
+ }
+ } else {
+ ((HttpServletResponse)servletResponse).setStatus( HttpServletResponse.SC_SERVICE_UNAVAILABLE );
+ }
+ String requestUri = (String)servletRequest.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
+ int status = ((HttpServletResponse)servletResponse).getStatus();
+ auditor.audit( Action.ACCESS, requestUri, ResourceType.URI, ActionOutcome.SUCCESS, res.responseStatus( status ) );
+ } finally {
+ auditService.detachContext();
+ }
+ }
+
+ @Override
+ public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain ) throws IOException, ServletException {
+ try {
+ auditService.createContext();
+ GatewayFilter f = filter;
+ if( f != null ) {
+ try {
f.doFilter( servletRequest, servletResponse );
+ //TODO: This should really happen naturally somehow as part of being a filter. This way will cause problems eventually.
+ chain.doFilter( servletRequest, servletResponse );
} catch( IOException e ) {
LOG.failedToExecuteFilter( e );
throw e;
@@ -153,19 +201,9 @@ public class GatewayServlet implements Servlet {
filter = null;
}
- private static GatewayFilter createFilter( ServletConfig servletConfig ) throws ServletException {
- GatewayFilter filter = null;
+ private static GatewayFilter createFilter( InputStream stream ) throws ServletException {
try {
- InputStream stream = null;
- String location = servletConfig.getInitParameter( GATEWAY_DESCRIPTOR_LOCATION_PARAM );
- if( location != null ) {
- stream = servletConfig.getServletContext().getResourceAsStream( location );
- if( stream == null ) {
- stream = servletConfig.getServletContext().getResourceAsStream( "/WEB-INF/" + location );
- }
- } else {
- stream = servletConfig.getServletContext().getResourceAsStream( GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
- }
+ GatewayFilter filter = null;
if( stream != null ) {
try {
GatewayDescriptor descriptor = GatewayDescriptorFactory.load( "xml", new InputStreamReader( stream ) );
@@ -174,11 +212,43 @@ public class GatewayServlet implements Servlet {
stream.close();
}
}
+ return filter;
} catch( IOException e ) {
throw new ServletException( e );
} catch( URISyntaxException e ) {
throw new ServletException( e );
}
+ }
+
+ private static GatewayFilter createFilter( FilterConfig filterConfig ) throws ServletException {
+ GatewayFilter filter;
+ InputStream stream;
+ String location = filterConfig.getInitParameter( GATEWAY_DESCRIPTOR_LOCATION_PARAM );
+ if( location != null ) {
+ stream = filterConfig.getServletContext().getResourceAsStream( location );
+ if( stream == null ) {
+ stream = filterConfig.getServletContext().getResourceAsStream( "/WEB-INF/" + location );
+ }
+ } else {
+ stream = filterConfig.getServletContext().getResourceAsStream( GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
+ }
+ filter = createFilter( stream );
+ return filter;
+ }
+
+ private static GatewayFilter createFilter( ServletConfig servletConfig ) throws ServletException {
+ GatewayFilter filter;
+ InputStream stream;
+ String location = servletConfig.getInitParameter( GATEWAY_DESCRIPTOR_LOCATION_PARAM );
+ if( location != null ) {
+ stream = servletConfig.getServletContext().getResourceAsStream( location );
+ if( stream == null ) {
+ stream = servletConfig.getServletContext().getResourceAsStream( "/WEB-INF/" + location );
+ }
+ } else {
+ stream = servletConfig.getServletContext().getResourceAsStream( GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
+ }
+ filter = createFilter( stream );
return filter;
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
index 6aa5418..cdaa96d 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
@@ -22,6 +22,9 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.gateway.GatewayMessages;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
+import org.joda.time.Period;
+import org.joda.time.format.PeriodFormatter;
+import org.joda.time.format.PeriodFormatterBuilder;
import java.io.File;
import java.net.InetSocketAddress;
@@ -67,7 +70,7 @@ import java.util.Map;
public class GatewayConfigImpl extends Configuration implements GatewayConfig {
private static final String GATEWAY_DEFAULT_TOPOLOGY_NAME_PARAM = "default.app.topology.name";
- private static final String GATEWAY_DEFAULT_TOPOLOGY_NAME = "sandbox";
+ private static final String GATEWAY_DEFAULT_TOPOLOGY_NAME = null;
private static GatewayMessages log = MessagesFactory.get( GatewayMessages.class );
@@ -77,6 +80,8 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
private static final String DEFAULT_STACKS_SERVICES_DIR = "services";
+ private static final String DEFAULT_APPLICATIONS_DIR = "applications";
+
public static final String[] GATEWAY_CONFIG_FILENAMES = {
GATEWAY_CONFIG_DIR_PREFIX + "/" + GATEWAY_CONFIG_FILE_PREFIX + "-default.xml",
GATEWAY_CONFIG_DIR_PREFIX + "/" + GATEWAY_CONFIG_FILE_PREFIX + "-site.xml"
@@ -103,6 +108,7 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
public static final String SECURITY_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".security.dir";
public static final String DATA_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".data.dir";
public static final String STACKS_SERVICES_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".services.dir";
+ public static final String APPLICATIONS_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".applications.dir";
public static final String HADOOP_CONF_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".hadoop.conf.dir";
public static final String FRONTEND_URL = GATEWAY_CONFIG_FILE_PREFIX + ".frontend.url";
private static final String TRUST_ALL_CERTS = GATEWAY_CONFIG_FILE_PREFIX + ".trust.all.certs";
@@ -118,6 +124,8 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
public static final String HTTP_SERVER_REQUEST_HEADER_BUFFER = GATEWAY_CONFIG_FILE_PREFIX + ".httpserver.requestHeaderBuffer";
public static final String HTTP_SERVER_RESPONSE_BUFFER = GATEWAY_CONFIG_FILE_PREFIX + ".httpserver.responseBuffer";
public static final String HTTP_SERVER_RESPONSE_HEADER_BUFFER = GATEWAY_CONFIG_FILE_PREFIX + ".httpserver.responseHeaderBuffer";
+ public static final String DEPLOYMENTS_BACKUP_VERSION_LIMIT = GATEWAY_CONFIG_FILE_PREFIX + ".deployment.backup.versionLimit";
+ public static final String DEPLOYMENTS_BACKUP_AGE_LIMIT = GATEWAY_CONFIG_FILE_PREFIX + ".deployment.backup.ageLimit";
// These config property names are not inline with the convention of using the
// GATEWAY_CONFIG_FILE_PREFIX as is done by those above. These are left for
@@ -190,6 +198,11 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
}
@Override
+ public String getGatewayApplicationsDir() {
+ return get(APPLICATIONS_DIR, getGatewayDataDir() + File.separator + DEFAULT_APPLICATIONS_DIR);
+ }
+
+ @Override
public String getHadoopConfDir() {
return get( HADOOP_CONF_DIR );
}
@@ -371,7 +384,12 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
*/
@Override
public String getDefaultAppRedirectPath() {
- return "/" + getGatewayPath() + "/" + getDefaultTopologyName();
+ String defTopo = getDefaultTopologyName();
+ if( defTopo == null ) {
+ return null;
+ } else {
+ return "/" + getGatewayPath() + "/" + defTopo;
+ }
}
/* (non-Javadoc)
@@ -497,4 +515,30 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
return i;
}
+ @Override
+ public int getGatewayDeploymentsBackupVersionLimit() {
+ int i = getInt( DEPLOYMENTS_BACKUP_VERSION_LIMIT, 5 );
+ if( i < 0 ) {
+ i = -1;
+ }
+ return i;
+ }
+
+ @Override
+ public long getGatewayDeploymentsBackupAgeLimit() {
+ PeriodFormatter f = new PeriodFormatterBuilder().appendDays().toFormatter();
+ String s = get( DEPLOYMENTS_BACKUP_AGE_LIMIT, "-1" );
+ long d;
+ try {
+ Period p = Period.parse( s, f );
+ d = p.toStandardDuration().getMillis();
+ if( d < 0 ) {
+ d = -1;
+ }
+ } catch( Exception e ) {
+ d = -1;
+ }
+ return d;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a70a3b56/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentContextImpl.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentContextImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentContextImpl.java
index 59480ce..918cdbb 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentContextImpl.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentContextImpl.java
@@ -39,7 +39,6 @@ public class DeploymentContextImpl implements DeploymentContext {
private WebArchive webArchive;
private WebAppDescriptor webAppDescriptor;
Map<String,List<ProviderDeploymentContributor>> providers;
- Map<String,List<ServiceDeploymentContributor>> services;
private Map<String,Object> descriptors;
public DeploymentContextImpl(
@@ -48,15 +47,13 @@ public class DeploymentContextImpl implements DeploymentContext {
GatewayDescriptor gatewayDescriptor,
WebArchive webArchive,
WebAppDescriptor webAppDescriptor,
- Map<String,List<ProviderDeploymentContributor>> providers,
- Map<String,List<ServiceDeploymentContributor>> services ) {
+ Map<String,List<ProviderDeploymentContributor>> providers ) {
this.gatewayConfig = gatewayConfig;
this.topology = topology;
this.gatewayDescriptor = gatewayDescriptor;
this.webArchive = webArchive;
this.webAppDescriptor = webAppDescriptor;
this.providers = providers;
- this.services = services;
this.descriptors = new HashMap<String,Object>();
}
@@ -118,9 +115,6 @@ public class DeploymentContextImpl implements DeploymentContext {
List<FilterParamDescriptor> params ) {
ProviderDeploymentContributor contributor = DeploymentFactory.getProviderContributor( providers, role, name );
Provider provider = getTopology().getProvider( role, name );
-// if( provider != null ) {
-// System.out.println("=================== provider found by name: " + name + " with actual name of: " + provider.getName());
-// }
if( provider == null ) {
provider = new Provider();
provider.setRole( role );