You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/11/13 15:47:51 UTC
[01/16] knox git commit: KNOX-842 Add support for Livy (Spark REST
Service).
Repository: knox
Updated Branches:
refs/heads/KNOX-998-Package_Restructuring 1451428f7 -> e70904b3d
KNOX-842 Add support for Livy (Spark REST Service).
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/4d60e414
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/4d60e414
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/4d60e414
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 4d60e4149a9fd484f8b54faeb082bf40fa3611d4
Parents: 11ec78a
Author: Jeffrey E Rodriguez <je...@gmail.com>
Authored: Thu Nov 2 04:20:46 2017 -0700
Committer: Jeffrey E Rodriguez <je...@gmail.com>
Committed: Thu Nov 2 04:20:46 2017 -0700
----------------------------------------------------------------------
.../resources/services/livy/0.4.0/rewrite.xml | 33 ++++++++++++++++++++
.../resources/services/livy/0.4.0/service.xml | 28 +++++++++++++++++
2 files changed, 61 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/4d60e414/gateway-service-definitions/src/main/resources/services/livy/0.4.0/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/livy/0.4.0/rewrite.xml b/gateway-service-definitions/src/main/resources/services/livy/0.4.0/rewrite.xml
new file mode 100644
index 0000000..013fa99
--- /dev/null
+++ b/gateway-service-definitions/src/main/resources/services/livy/0.4.0/rewrite.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ 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.
+-->
+<rules>
+ <rule name="LIVYSERVER/livy/user-name">
+ <rewrite template="{$username}"/>
+ </rule>
+ <rule dir="IN" name="LIVYSERVER/livy/root/inbound" pattern="*://*:*/**/livy/v1">
+ <rewrite template="{$serviceUrl[LIVYSERVER]}"/>
+ </rule>
+ <rule dir="IN" name="LIVYSERVER/livy/path/inbound" pattern="*://*:*/**/livy/v1/{path=**}?{**}">
+ <rewrite template="{$serviceUrl[LIVYSERVER]}/{path=**}?{**}"/>
+ </rule>
+ <filter name="LIVYSERVER/livy/addusername/inbound">
+ <content type="*/json">
+ <apply path="$.proxyUser" rule="LIVYSERVER/livy/user-name"/>
+ </content>
+ </filter>
+</rules>
http://git-wip-us.apache.org/repos/asf/knox/blob/4d60e414/gateway-service-definitions/src/main/resources/services/livy/0.4.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/livy/0.4.0/service.xml b/gateway-service-definitions/src/main/resources/services/livy/0.4.0/service.xml
new file mode 100644
index 0000000..ef71d1e
--- /dev/null
+++ b/gateway-service-definitions/src/main/resources/services/livy/0.4.0/service.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ 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.
+-->
+
+<service role="LIVYSERVER" name="livy" version="0.4.0">
+ <routes>
+ <route path="/livy/v1/sessions">
+ <rewrite apply="LIVYSERVER/livy/addusername/inbound" to="request.body"/>
+ </route>
+ <route path="/livy/v1/**?**"/>
+ <route path="/livy/v1"/>
+ <route path="/livy/v1/"/>
+ </routes>
+</service>
[05/16] knox git commit: KNOX-921 - Httpclient max connections are
always set to default values
Posted by mo...@apache.org.
KNOX-921 - Httpclient max connections are always set to default values
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/951a725d
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/951a725d
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/951a725d
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 951a725d03764a4ff570194592dea804e392e22a
Parents: 12217b1
Author: Sandeep More <mo...@apache.org>
Authored: Mon Nov 6 13:44:49 2017 -0500
Committer: Sandeep More <mo...@apache.org>
Committed: Mon Nov 6 13:44:49 2017 -0500
----------------------------------------------------------------------
.../metrics/impl/instr/InstrHttpClientBuilderProvider.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/951a725d/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
index e96c05e..e930228 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
@@ -38,8 +38,7 @@ public class InstrHttpClientBuilderProvider implements InstrumentationProvider<H
@Override
public HttpClientBuilder getInstrumented(MetricsContext metricsContext) {
MetricRegistry registry = (MetricRegistry) metricsContext.getProperty(DefaultMetricsService.METRICS_REGISTRY);
- return HttpClientBuilder.create().setRequestExecutor(new InstrumentedHttpRequestExecutor(registry, TOPOLOGY_URL_AND_METHOD)).
- setConnectionManager(new PoolingHttpClientConnectionManager());
+ return HttpClientBuilder.create().setRequestExecutor(new InstrumentedHttpRequestExecutor(registry, TOPOLOGY_URL_AND_METHOD));
}
@Override
[10/16] knox git commit: Updated CHANGES for 0.14.0 release
Posted by mo...@apache.org.
Updated CHANGES for 0.14.0 release
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/898827c1
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/898827c1
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/898827c1
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 898827c1f01e11b510fde07bf80dfd7bd3d80882
Parents: f52dc20
Author: Larry McCay <lm...@hortonworks.com>
Authored: Wed Nov 8 21:23:14 2017 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Wed Nov 8 21:24:04 2017 -0500
----------------------------------------------------------------------
CHANGES | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/898827c1/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 53a551f..2d266d6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,89 @@
------------------------------------------------------------------------------
+Release Notes - Apache Knox - Version 0.14.0
+------------------------------------------------------------------------------
+** New Feature
+ * [KNOX-1014] - Service Discovery and Topology Generation Framework (Phil Zampino via lmccay)
+ * [KNOX-1062] - Service-Level Parameter Support in Service Discovery and Topology Generation (Phil Zampino via lmccay)
+ * [KNOX-1077] - Knox should notice simple descriptors on startup (Phil Zampino via lmccay)
+ * [KNOX-1063] - Simple Descriptor discovery should notice YAML file with .yaml extension (Phil Zampino via lmccay)
+ * [KNOX-1105] - Provide indication that topologies were generated from simple descriptors (Phil Zampino via lmccay)
+ * [KNOX-1110] - Simple Descriptors Must Accommodate Application elements (Phil Zampino via lmccay)
+ * [KNOX-1039] - Added admin APIs for managing shared provider configurations and descriptors (Phil Zampino via Sandeep More)
+ * [KNOX-970] - Add NiFi HA dispatch to service def (Jeff Storck via lmccay)
+ * [KNOX-970] - Add support for proxying NiFi (Jeff Storck via lmccay)
+ * [KNOX-842] - Add support for Livy (Spark REST Service).
+ * [KNOX-1017] - Add support for enabling "Strict-Transport-Security" header in Knox responses (Latha Appanna via lmccay)
+ * [KNOX-1049] - Default Service or App Context for Topologies
+ * [KNOX-1049] - change BeanConverter for path element
+ * [KNOX-1049] - marshaling changes
+ * [KNOX-1049] - change defaultServicePath to path
+ * [KNOX-1041] - High Availability Support For Apache SOLR, HBase & Kafka (Rick Kellogg via Sandeep More)
+ * [KNOX-1046] - Add Client Cert Wanted Capability with Configurable Validation that Checks for It
+ * [KNOX-1072] - Add Client Cert Required Capability to KnoxToken
+
+** Improvement
+ * [KNOX-921] - Httpclient max connections are always set to default values
+ * [KNOX-1106] - Tighten the rewrite rule on oozieui to reduce false positives (Wei Han via Sandeep More)
+ * [KNOX-1104] - Test to verify behavior of HaProvider service with only a single URL ( Phil Zampino via Sandeep More)
+ * [KNOX-1034] - Make Default identity-assertion provider actually be the default
+ * [KNOX-1078] - Add option to preserve original string when lookup fails in regex based identity assertion provider (Wei Han via Sandeep More)
+ * [KNOX-1049] - add unit test to gatewayfiltertest
+ * [KNOX-1076] - Update nimbus-jose-jwt to 4.41.2
+ * [KNOX-1049] - check for null topology to avoid NPE in tests
+ * [KNOX-1088] - Remove LDAP BaseDirectoryService*
+ * [KNOX-1073] - Upgrade PAC4J to a more recent version
+ * [KNOX-1001] - Knox Shell Sqoop.Request class is Package Private (Andrei Viaryshka via lmccay)
+ * [KNOX-1021] - Should handle empty string for endpoint token service audience list
+ * [KNOX-1082] - Add support to validate the "nbf" claim for JWTs
+ * [KNOX-1067] - Support different signature algorithms for JWTs
+ * [KNOX-1045] - Knox Token Service has a trailing whitespace for the token_type attribute
+ * [KNOX-1081] - Remove Picketlink Provider Module
+ * [KNOX-895] - Pass Headers and Cookies to websocket backend
+ * [KNOX-1064] - Externalize Hadoop Service Configuration Details and Service URL Creation (Phil Zampino via Sandeep More)
+ * [KNOX-1070] - Drop support for Java 7 (Rick Kellogg via Sandeep More)
+ * [KNOX-1075 and KNOX-1070] - Enforce minimum maven and Java version (Rick Kellogg via Sandeep More)
+ * [KNOX-1048] - Knoxshell samples missing hadoop-examples.jar
+ * [KNOX-1069] - KnoxSSO token audience config should trim values
+ * [KNOX-1055] - Spark page characters & should be treated as a delimiter (Mars via Sandeep More)
+ * [KNOX-1074] - Workflow Manager view fails to load when using ambari through KNOX (Venkatasairam Lanka via lmccay)
+ * [KNOX-1071] - Replace java.util.Random with SecureRandom
+ * [KNOX-1014] - remove extraneous directory
+ * [KNOX-1065] - Add some unit tests for the DefaultTokenAuthorityService
+ * [KNOX-1060] - JWT.getExpires() returns null
+ * [KNOX-1058] - Fix JWTToken.parseToken
+ * [KNOX-1036] - Fix a number of issues relating to JWTokenAuthority
+ * [KNOX-1054] - Make DefaultURLManager thread-safe (Phil Zampino via Sandeep More)
+ * [KNOX-1052] - Add some tests for the Knox SSO Service
+ * [KNOX-1049] - Default Service or App Context for Topologies
+ * [KNOX-1042] - Fix test timeout (Phil Zampino via Sandeep More)
+ * [KNOX-1047] - Add some tests for the Knox Token Service
+ * [KNOX-1044] - Change Rest Assured "expect" to "then"
+ * [KNOX-1038] - Replace deprecated rest-assured "content" call with "body"
+ * [KNOX-1037] - Upgrade rest-assured dependency
+ * [KNOX-1035] - Move JWTTokenTest to gateway-spi module + add more tests
+ * [KNOX-1027] - Add support to configure the issuer for the JWT filters
+ * [KNOX-1028] - X-Frame-Options and other security headers are ineffective
+ * [KNOX-962] - Add signature validation tests for the JWT filters
+ * [KNOX-1024] - Add Kafka test to GatewayBasicFuncTest
+ * [KNOX-1020] - Minor code improvements
+ * [KNOX-1019] - Remove test-driver "hack" to copy services
+ * [KNOX-1018] - Remove junit.framework calls
+ * [KNOX-738] - Remove references to deprecated httpclient class DefaultHttpClient
+ * [KNOX-963] - Use GatewayTestDriver to configure LDAP in gateway-tests
+ * [KNOX-978] - Add a test for the SOLR REST API
+ * [KNOX-989] - Report metrics at service level (/webhdfs/v1) instead of url with args (/webhdfs/v1/?op=LISTSTATUS) (Mohammad Kamrul Islam via Sandeep More)
+ * [KNOX-993] - The samples README for knoxshell references the 0.5.0 userguide
+ * [KNOX-992] - Add README for the knoxshell distribution (Colm O hEigeartaigh and lmccay via lmccay)
+** Bug
+ * [KNOX-1003] - Fix the rewrite rules for Zeppelin 0.7.2 UI
+ * [KNOX-1004] - Failing (flaky) Knox unit tests
+ * [KNOX-1005] - WebHbase get rid of extra decoding
+ * [KNOX-1061] - KnoxSSO Redirects with Query Params in the OriginalUrl Broken
+ * [KNOX-1068] - Add support for HTTP Head request
+ * [KNOX-1079] - Regression: proxy for Atlas fails with j_spring_security_check during login (Madhan Neethiraj via lmccay)
+ * [KNOX-1022] - Configuring knox token ttl to higher value generates an access token which is not valid
+
+------------------------------------------------------------------------------
Release Notes - Apache Knox - Version 0.13.0
------------------------------------------------------------------------------
** New Feature
[07/16] knox git commit: KNOX-970 - Add support for proxying NiFi
(Jeff Storck via lmccay)
Posted by mo...@apache.org.
KNOX-970 - Add support for proxying NiFi (Jeff Storck via lmccay)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/89dd7788
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/89dd7788
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/89dd7788
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 89dd77886e7f9990e2b5ac2a78012c0d8dfc7cbd
Parents: 951a725
Author: Larry McCay <lm...@hortonworks.com>
Authored: Mon Nov 6 17:45:48 2017 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Mon Nov 6 17:59:49 2017 -0500
----------------------------------------------------------------------
gateway-release/pom.xml | 4 +
.../ServiceDefinitionDeploymentContributor.java | 14 ++-
.../service/definition/CustomDispatch.java | 11 ++
.../resources/services/nifi/1.4.0/rewrite.xml | 27 +++++
.../resources/services/nifi/1.4.0/service.xml | 30 +++++
gateway-service-nifi/pom.xml | 38 +++++++
.../hadoop/gateway/dispatch/NiFiDispatch.java | 106 ++++++++++++++++++
.../hadoop/gateway/dispatch/NiFiHaDispatch.java | 111 +++++++++++++++++++
.../hadoop/gateway/dispatch/NiFiHeaders.java | 26 +++++
.../gateway/dispatch/NiFiRequestUtil.java | 89 +++++++++++++++
.../gateway/dispatch/NiFiResponseUtil.java | 89 +++++++++++++++
gateway-spi/pom.xml | 4 +
.../dispatch/DefaultHttpClientFactory.java | 55 +++++++--
pom.xml | 6 +
14 files changed, 598 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index ad07225..cf85f8b 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -216,6 +216,10 @@
</dependency>
<dependency>
<groupId>${gateway-group}</groupId>
+ <artifactId>gateway-service-nifi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
<artifactId>gateway-provider-rewrite</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
index 53a7e23..8c0e7eb 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
@@ -187,11 +187,12 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
String haContributorName = customDispatch.getHaContributorName();
String haClassName = customDispatch.getHaClassName();
String httpClientFactory = customDispatch.getHttpClientFactory();
+ boolean useTwoWaySsl = customDispatch.getUseTwoWaySsl();
if ( isHaEnabled) {
if (haContributorName != null) {
addDispatchFilter(context, service, resource, DISPATCH_ROLE, haContributorName);
} else if (haClassName != null) {
- addDispatchFilterForClass(context, service, resource, haClassName, httpClientFactory);
+ addDispatchFilterForClass(context, service, resource, haClassName, httpClientFactory, useTwoWaySsl);
} else {
addDefaultHaDispatchFilter(context, service, resource);
}
@@ -202,7 +203,7 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
} else {
String className = customDispatch.getClassName();
if ( className != null ) {
- addDispatchFilterForClass(context, service, resource, className, httpClientFactory);
+ addDispatchFilterForClass(context, service, resource, className, httpClientFactory, useTwoWaySsl);
} else {
//final fallback to the default dispatch
addDispatchFilter(context, service, resource, DISPATCH_ROLE, "http-client");
@@ -221,12 +222,15 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
filter.param().name(SERVICE_ROLE_PARAM).value(service.getRole());
}
- private FilterDescriptor addDispatchFilterForClass(DeploymentContext context, Service service, ResourceDescriptor resource, String dispatchClass, String httpClientFactory) {
+ private FilterDescriptor addDispatchFilterForClass(DeploymentContext context, Service service, ResourceDescriptor resource, String dispatchClass, String httpClientFactory, boolean useTwoWaySsl) {
FilterDescriptor filter = resource.addFilter().name(getName()).role(DISPATCH_ROLE).impl(GatewayDispatchFilter.class);
filter.param().name(DISPATCH_IMPL_PARAM).value(dispatchClass);
if (httpClientFactory != null) {
filter.param().name(HTTP_CLIENT_FACTORY_PARAM).value(httpClientFactory);
}
+ // let's take the value of useTwoWaySsl which is derived from the service definition
+ // then allow it to be overridden by service params from the topology
+ filter.param().name("useTwoWaySsl").value(Boolean.toString(useTwoWaySsl));
for ( Map.Entry<String, String> serviceParam : service.getParams().entrySet() ) {
filter.param().name(serviceParam.getKey()).value(serviceParam.getValue());
}
@@ -240,6 +244,10 @@ public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentCon
return filter;
}
+ private FilterDescriptor addDispatchFilterForClass(DeploymentContext context, Service service, ResourceDescriptor resource, String dispatchClass, String httpClientFactory) {
+ return addDispatchFilterForClass(context, service, resource, dispatchClass, httpClientFactory, false);
+ }
+
private boolean isHaEnabled(DeploymentContext context) {
Provider provider = getProviderByRole(context, "ha");
if ( provider != null && provider.isEnabled() ) {
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/CustomDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/CustomDispatch.java b/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/CustomDispatch.java
index abde82d..7e5c2a0 100644
--- a/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/CustomDispatch.java
+++ b/gateway-service-definitions/src/main/java/org/apache/hadoop/gateway/service/definition/CustomDispatch.java
@@ -33,6 +33,8 @@ public class CustomDispatch {
private String httpClientFactory;
+ private boolean useTwoWaySsl = false;
+
@XmlAttribute(name = "contributor-name")
public String getContributorName() {
return contributorName;
@@ -77,4 +79,13 @@ public class CustomDispatch {
public void setHttpClientFactory(String httpClientFactory) {
this.httpClientFactory = httpClientFactory;
}
+
+ @XmlAttribute(name = "use-two-way-ssl")
+ public boolean getUseTwoWaySsl() {
+ return useTwoWaySsl;
+ }
+
+ public void setUseTwoWaySsl(boolean useTwoWaySsl) {
+ this.useTwoWaySsl = useTwoWaySsl;
+ }
}
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/rewrite.xml b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/rewrite.xml
new file mode 100644
index 0000000..7c44efc
--- /dev/null
+++ b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/rewrite.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<rules>
+ <rule dir="IN" name="NIFI/nifi/inbound/path" pattern="*://*:*/**/nifi-app/{path=**}">
+ <rewrite template="{$serviceUrl[NIFI]}/{path=**}"/>
+ </rule>
+ <rule dir="IN" name="NIFI/nifi/inbound/path/query" pattern="*://*:*/**/nifi-app/{path=**}?{**}">
+ <rewrite template="{$serviceUrl[NIFI]}/{path=**}?{**}"/>
+ </rule>
+ <rule dir="IN" name="NIFI/nifi/inbound/path/query-other" pattern="*://*:*/**/nifi-app/{path=**}/?{**}">
+ <rewrite template="{$serviceUrl[NIFI]}/{path=**}/?{**}"/>
+ </rule>
+</rules>
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
new file mode 100644
index 0000000..fb24598
--- /dev/null
+++ b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
@@ -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.
+-->
+<service role="NIFI" name="nifi" version="1.4.0">
+ <routes>
+ <route path="/nifi-app/**">
+ <rewrite apply="NIFI/nifi/inbound/path" to="request.url"/>
+ </route>
+ <route path="/nifi-app/**?**">
+ <rewrite apply="NIFI/nifi/inbound/path/query" to="request.url"/>
+ </route>
+ <route path="/nifi-app/**/?**">
+ <rewrite apply="NIFI/nifi/inbound/path/query-other" to="request.url"/>
+ </route>
+ </routes>
+ <dispatch classname="org.apache.hadoop.gateway.dispatch.NiFiDispatch" use-two-way-ssl="false"/>
+</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-nifi/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/pom.xml b/gateway-service-nifi/pom.xml
new file mode 100644
index 0000000..41d50fb
--- /dev/null
+++ b/gateway-service-nifi/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>gateway</artifactId>
+ <groupId>org.apache.knox</groupId>
+ <version>0.14.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>gateway-service-nifi</artifactId>
+ <description>Extension to the gateway for supporting Apache NiFi.</description>
+
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <dependencies>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-provider-ha</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java
new file mode 100644
index 0000000..013fd9c
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java
@@ -0,0 +1,106 @@
+/*
+ * 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.dispatch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.hadoop.gateway.util.MimeTypes;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ContentType;
+
+public class NiFiDispatch extends DefaultDispatch {
+
+ @Override
+ protected void executeRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse) throws IOException {
+ outboundRequest = NiFiRequestUtil.modifyOutboundRequest(outboundRequest, inboundRequest);
+ HttpResponse inboundResponse = executeOutboundRequest(outboundRequest);
+ writeOutboundResponse(outboundRequest, inboundRequest, outboundResponse, inboundResponse);
+ }
+
+ /**
+ * Overridden to provide a spot to modify the outbound response before its stream is closed.
+ */
+ protected void writeOutboundResponse(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
+ // Copy the client respond header to the server respond.
+ outboundResponse.setStatus(inboundResponse.getStatusLine().getStatusCode());
+ Header[] headers = inboundResponse.getAllHeaders();
+ Set<String> excludeHeaders = getOutboundResponseExcludeHeaders();
+ boolean hasExcludeHeaders = false;
+ if ((excludeHeaders != null) && !(excludeHeaders.isEmpty())) {
+ hasExcludeHeaders = true;
+ }
+ for ( Header header : headers ) {
+ String name = header.getName();
+ if (hasExcludeHeaders && excludeHeaders.contains(name.toUpperCase())) {
+ continue;
+ }
+ String value = header.getValue();
+ outboundResponse.addHeader(name, value);
+ }
+
+ HttpEntity entity = inboundResponse.getEntity();
+ if( entity != null ) {
+ outboundResponse.setContentType( getInboundResponseContentType( entity ) );
+ InputStream stream = entity.getContent();
+ try {
+ NiFiResponseUtil.modifyOutboundResponse(inboundRequest, outboundResponse, inboundResponse);
+ writeResponse( inboundRequest, outboundResponse, stream );
+ } finally {
+ closeInboundResponse( inboundResponse, stream );
+ }
+ }
+ }
+
+ /**
+ * Overriden due to {@link DefaultDispatch#getInboundResponseContentType(HttpEntity) having private access, and the method is used by
+ * {@link #writeOutboundResponse(HttpUriRequest, HttpServletRequest, HttpServletResponse, HttpResponse)}}
+ */
+ private String getInboundResponseContentType( final HttpEntity entity ) {
+ String fullContentType = null;
+ if( entity != null ) {
+ ContentType entityContentType = ContentType.get( entity );
+ if( entityContentType != null ) {
+ if( entityContentType.getCharset() == null ) {
+ final String entityMimeType = entityContentType.getMimeType();
+ final String defaultCharset = MimeTypes.getDefaultCharsetForMimeType( entityMimeType );
+ if( defaultCharset != null ) {
+ LOG.usingDefaultCharsetForEntity( entityMimeType, defaultCharset );
+ entityContentType = entityContentType.withCharset( defaultCharset );
+ }
+ } else {
+ LOG.usingExplicitCharsetForEntity( entityContentType.getMimeType(), entityContentType.getCharset() );
+ }
+ fullContentType = entityContentType.toString();
+ }
+ }
+ if( fullContentType == null ) {
+ LOG.unknownResponseEntityContentType();
+ } else {
+ LOG.inboundResponseEntityContentType( fullContentType );
+ }
+ return fullContentType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java
new file mode 100644
index 0000000..4272086
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java
@@ -0,0 +1,111 @@
+/*
+ * 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.dispatch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.hadoop.gateway.ha.dispatch.DefaultHaDispatch;
+import org.apache.hadoop.gateway.util.MimeTypes;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ContentType;
+
+public class NiFiHaDispatch extends DefaultHaDispatch {
+
+ public NiFiHaDispatch() {
+ setServiceRole("NIFI");
+ }
+
+ @Override
+ protected void executeRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse) throws IOException {
+ outboundRequest = NiFiRequestUtil.modifyOutboundRequest(outboundRequest, inboundRequest);
+ HttpResponse inboundResponse = executeOutboundRequest(outboundRequest);
+ writeOutboundResponse(outboundRequest, inboundRequest, outboundResponse, inboundResponse);
+ }
+
+ /**
+ * Overridden to provide a spot to modify the outbound response before its stream is closed.
+ */
+ protected void writeOutboundResponse(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
+ // Copy the client respond header to the server respond.
+ outboundResponse.setStatus(inboundResponse.getStatusLine().getStatusCode());
+ Header[] headers = inboundResponse.getAllHeaders();
+ Set<String> excludeHeaders = getOutboundResponseExcludeHeaders();
+ boolean hasExcludeHeaders = false;
+ if ((excludeHeaders != null) && !(excludeHeaders.isEmpty())) {
+ hasExcludeHeaders = true;
+ }
+ for ( Header header : headers ) {
+ String name = header.getName();
+ if (hasExcludeHeaders && excludeHeaders.contains(name.toUpperCase())) {
+ continue;
+ }
+ String value = header.getValue();
+ outboundResponse.addHeader(name, value);
+ }
+
+ HttpEntity entity = inboundResponse.getEntity();
+ if( entity != null ) {
+ outboundResponse.setContentType( getInboundResponseContentType( entity ) );
+ InputStream stream = entity.getContent();
+ try {
+ NiFiResponseUtil.modifyOutboundResponse(inboundRequest, outboundResponse, inboundResponse);
+ writeResponse( inboundRequest, outboundResponse, stream );
+ } finally {
+ closeInboundResponse( inboundResponse, stream );
+ }
+ }
+ }
+
+ /**
+ * Overriden due to {@link DefaultDispatch#getInboundResponseContentType(HttpEntity) having private access, and the method is used by
+ * {@link #writeOutboundResponse(HttpUriRequest, HttpServletRequest, HttpServletResponse, HttpResponse)}}
+ */
+ private String getInboundResponseContentType( final HttpEntity entity ) {
+ String fullContentType = null;
+ if( entity != null ) {
+ ContentType entityContentType = ContentType.get( entity );
+ if( entityContentType != null ) {
+ if( entityContentType.getCharset() == null ) {
+ final String entityMimeType = entityContentType.getMimeType();
+ final String defaultCharset = MimeTypes.getDefaultCharsetForMimeType( entityMimeType );
+ if( defaultCharset != null ) {
+ DefaultDispatch.LOG.usingDefaultCharsetForEntity( entityMimeType, defaultCharset );
+ entityContentType = entityContentType.withCharset( defaultCharset );
+ }
+ } else {
+ DefaultDispatch.LOG.usingExplicitCharsetForEntity( entityContentType.getMimeType(), entityContentType.getCharset() );
+ }
+ fullContentType = entityContentType.toString();
+ }
+ }
+ if( fullContentType == null ) {
+ DefaultDispatch.LOG.unknownResponseEntityContentType();
+ } else {
+ DefaultDispatch.LOG.inboundResponseEntityContentType( fullContentType );
+ }
+ return fullContentType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java
new file mode 100644
index 0000000..f3e8e68
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java
@@ -0,0 +1,26 @@
+/*
+ * 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.dispatch;
+
+class NiFiHeaders {
+ static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";
+ static final String X_FORWARDED_HOST = "X-Forwarded-Server";
+ static final String X_FORWARDED_PORT = "X-Forwarded-Port";
+ static final String X_FORWARDED_CONTEXT = "X-Forwarded-Context";
+ static final String X_PROXIED_ENTITIES_CHAIN = "X-ProxiedEntitiesChain";
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java
new file mode 100644
index 0000000..9fdc425
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java
@@ -0,0 +1,89 @@
+/*
+ * 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.dispatch;
+
+import java.io.IOException;
+
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.gateway.security.SubjectUtils;
+import org.apache.http.Header;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.log4j.Logger;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+
+class NiFiRequestUtil {
+
+ static HttpUriRequest modifyOutboundRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest) throws IOException {
+ // preserve trailing slash from inbound request in the outbound request
+ if (inboundRequest.getPathInfo().endsWith("/")) {
+ String[] split = outboundRequest.getURI().toString().split("\\?");
+ if (!split[0].endsWith("/")) {
+ outboundRequest = RequestBuilder.copy(outboundRequest).setUri(split[0] + "/" + (split.length == 2 ? "?" + split[1] : "")).build();
+ }
+ }
+ // update the X-Forwarded-Context header to include the Knox-specific context path
+ final Header originalXForwardedContextHeader = outboundRequest.getFirstHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
+ if (originalXForwardedContextHeader != null) {
+ String xForwardedContextHeaderValue = originalXForwardedContextHeader.getValue();
+ if (!Strings.isNullOrEmpty(xForwardedContextHeaderValue)) {
+ // Inspect the inbound request and outbound request to determine the additional context path from the rewrite
+ // rules that needs to be added to the X-Forwarded-Context header to allow proper proxying to NiFi.
+ //
+ // NiFi does its own URL rewriting, and will not work with the context path provided by Knox
+ // (ie, "/gateway/sandbox").
+ //
+ // For example, if Knox has a rewrite rule "*://*:*/**/nifi-app/{**}?{**}", "/nifi-app" needs to be added
+ // to the existing value of the X-Forwarded-Context header, which ends up being "/gateway/sandbox/nifi-app".
+ String inboundRequestPathInfo = inboundRequest.getPathInfo();
+ String outboundRequestUriPath = outboundRequest.getURI().getPath();
+ String outboundRequestUriPathNoTrailingSlash = StringUtils.removeEnd(outboundRequestUriPath, "/");
+ String knoxRouteContext = null;
+ int index = inboundRequestPathInfo.lastIndexOf(outboundRequestUriPathNoTrailingSlash);
+ if (index >= 0) {
+ knoxRouteContext = inboundRequestPathInfo.substring(0, index);
+ } else {
+ Logger.getLogger(NiFiHaDispatch.class.getName()).error(String.format("Unable to find index of %s in %s", outboundRequestUriPathNoTrailingSlash, inboundRequestPathInfo));
+ }
+ outboundRequest.setHeader(NiFiHeaders.X_FORWARDED_CONTEXT, xForwardedContextHeaderValue + knoxRouteContext);
+ }
+ }
+
+ // NiFi requires the header "X-ProxiedEntitiesChain" to be set with the identity or identities of the authenticated requester.
+ // The effective principal (identity) in the requester subject must be added to "X-ProxiedEntitiesChain".
+ // If the request already has a populated "X-ProxiedEntitiesChain" header, the identities must be appended to it.
+ // If the user proxied through Knox is anonymous, the "Anonymous" identity needs to be represented in X-ProxiedEntitiesChain
+ // as empty angle brackets "<>".
+ final Subject subject = SubjectUtils.getCurrentSubject();
+ String effectivePrincipalName = SubjectUtils.getEffectivePrincipalName(subject);
+ outboundRequest.setHeader(NiFiHeaders.X_PROXIED_ENTITIES_CHAIN, Objects.firstNonNull(inboundRequest.getHeader(NiFiHeaders.X_PROXIED_ENTITIES_CHAIN), "") +
+ String.format("<%s>", effectivePrincipalName.equalsIgnoreCase("anonymous") ? "" : effectivePrincipalName));
+
+ // Make sure headers named "Cookie" are removed from the request to NiFi, since NiFi does not use cookies.
+ Header[] cookieHeaders = outboundRequest.getHeaders("Cookie");
+ for (Header cookieHeader : cookieHeaders) {
+ outboundRequest.removeHeader(cookieHeader);
+ }
+ return outboundRequest;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java
new file mode 100644
index 0000000..38c98b3
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java
@@ -0,0 +1,89 @@
+/*
+ * 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.dispatch;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URIBuilder;
+
+class NiFiResponseUtil {
+
+ static void modifyOutboundResponse(HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
+ // Only want to rewrite the Location header on a HTTP 302
+ if (inboundResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_FOUND) {
+ Header originalLocationHeader = inboundResponse.getFirstHeader("Location");
+ if (originalLocationHeader != null) {
+ String originalLocation = originalLocationHeader.getValue();
+ URIBuilder originalLocationUriBuilder;
+ try {
+ originalLocationUriBuilder = new URIBuilder(originalLocation);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unable to parse URI from Location header", e);
+ }
+ URIBuilder inboundRequestUriBuilder = null;
+ try {
+ inboundRequestUriBuilder = new URIBuilder(inboundRequest.getRequestURI());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unable to parse the inbound request URI", e);
+ }
+ /*
+ * if the path specified in the Location header fron the inbound response contains the inbound request's URI's path,
+ * then it's going to the same web context, and the Location header should be updated based on the X_FORWARDED_* headers.
+ */
+ String inboundRequestUriPath = inboundRequestUriBuilder.getPath();
+ String originalLocationUriPath = originalLocationUriBuilder.getPath();
+ if (originalLocationUriPath.contains(inboundRequestUriPath)) {
+ // check for trailing slash of Location header if it exists and preserve it
+ final String trailingSlash = originalLocationUriPath.endsWith("/") ? "/" : "";
+ // retain query params
+ final List<NameValuePair> queryParams = originalLocationUriBuilder.getQueryParams();
+
+ // check for proxy settings
+ final String scheme = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PROTO);
+ final String host = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_HOST);
+ final String port = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PORT);
+
+ final String baseContextPath = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
+ final String pathInfo = inboundRequest.getPathInfo();
+
+ try {
+ final URI newLocation = new URIBuilder().setScheme(scheme).setHost(host).setPort((StringUtils.isNumeric(port) ? Integer.parseInt(port) : -1)).setPath(
+ baseContextPath + pathInfo + trailingSlash).setParameters(queryParams).build();
+ outboundResponse.setHeader("Location", newLocation.toString());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unable to rewrite Location header in response", e);
+ }
+ }
+ } else {
+ throw new RuntimeException("Received HTTP 302, but response is missing Location header");
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-spi/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-spi/pom.xml b/gateway-spi/pom.xml
index ade9329..ce7f504 100644
--- a/gateway-spi/pom.xml
+++ b/gateway-spi/pom.xml
@@ -151,6 +151,10 @@
<artifactId>velocity</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
index 3c11468..706d436 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/DefaultHttpClientFactory.java
@@ -17,9 +17,23 @@
*/
package org.apache.hadoop.gateway.dispatch;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.servlet.FilterConfig;
+
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.services.GatewayServices;
import org.apache.hadoop.gateway.services.metrics.MetricsService;
+import org.apache.hadoop.gateway.services.security.AliasService;
+import org.apache.hadoop.gateway.services.security.AliasServiceException;
+import org.apache.hadoop.gateway.services.security.KeystoreService;
+import org.apache.hadoop.gateway.services.security.MasterService;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolException;
@@ -36,6 +50,8 @@ import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
@@ -43,31 +59,52 @@ import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
+import org.apache.http.ssl.SSLContexts;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
-import javax.servlet.FilterConfig;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
public class DefaultHttpClientFactory implements HttpClientFactory {
@Override
public HttpClient createHttpClient(FilterConfig filterConfig) {
HttpClientBuilder builder = null;
GatewayConfig gatewayConfig = (GatewayConfig) filterConfig.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+ GatewayServices services = (GatewayServices) filterConfig.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
if (gatewayConfig != null && gatewayConfig.isMetricsEnabled()) {
- GatewayServices services = (GatewayServices) filterConfig.getServletContext()
- .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
MetricsService metricsService = services.getService(GatewayServices.METRICS_SERVICE);
builder = metricsService.getInstrumented(HttpClientBuilder.class);
} else {
builder = HttpClients.custom();
}
+ if (Boolean.parseBoolean(filterConfig.getInitParameter("useTwoWaySsl"))) {
+ char[] keypass = null;
+ MasterService ms = services.getService("MasterService");
+ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
+ try {
+ keypass = as.getGatewayIdentityPassphrase();
+ } catch (AliasServiceException e) {
+ // nop - default passphrase will be used
+ }
+ if (keypass == null) {
+ // there has been no alias created for the key - let's assume it is the same as the keystore password
+ keypass = ms.getMasterSecret();
+ }
+
+ KeystoreService ks = services.getService(GatewayServices.KEYSTORE_SERVICE);
+ final SSLContext sslcontext;
+ try {
+ KeyStore keystoreForGateway = ks.getKeystoreForGateway();
+ sslcontext = SSLContexts.custom()
+ .loadTrustMaterial(keystoreForGateway, new TrustSelfSignedStrategy())
+ .loadKeyMaterial(keystoreForGateway, keypass)
+ .build();
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to create SSLContext", e);
+ }
+ builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext));
+ }
if ( "true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED)) ) {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UseJaasCredentials());
http://git-wip-us.apache.org/repos/asf/knox/blob/89dd7788/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d97548b..69c8115 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,7 @@
<module>gateway-shell-samples</module>
<module>gateway-shell-release</module>
<module>gateway-test-release-utils</module>
+ <module>gateway-service-nifi</module>
</modules>
<properties>
@@ -668,6 +669,11 @@
</dependency>
<dependency>
<groupId>${gateway-group}</groupId>
+ <artifactId>gateway-service-nifi</artifactId>
+ <version>${gateway-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
<artifactId>gateway-server</artifactId>
<version>${gateway-version}</version>
</dependency>
[15/16] knox git commit: Merge branch 'master' into
KNOX-998-Package_Restructuring
Posted by mo...@apache.org.
Merge branch 'master' into KNOX-998-Package_Restructuring
# Conflicts:
# gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
# gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/2c69152f
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/2c69152f
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/2c69152f
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 2c69152f49a22dbd6c9947a26965e3041a4f92d9
Parents: 1451428 d4b0dc6
Author: Sandeep More <mo...@apache.org>
Authored: Mon Nov 13 09:44:22 2017 -0500
Committer: Sandeep More <mo...@apache.org>
Committed: Mon Nov 13 09:44:22 2017 -0500
----------------------------------------------------------------------
CHANGES | 85 +++
build.xml | 2 +-
gateway-applications/pom.xml | 2 +-
gateway-demo-ldap-launcher/pom.xml | 2 +-
gateway-demo-ldap/pom.xml | 2 +-
gateway-discovery-ambari/pom.xml | 2 +-
gateway-i18n-logging-log4j/pom.xml | 2 +-
gateway-i18n-logging-sl4j/pom.xml | 2 +-
gateway-i18n/pom.xml | 2 +-
gateway-provider-ha/pom.xml | 2 +-
.../ha/provider/impl/DefaultURLManagerTest.java | 19 +
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
gateway-provider-jersey/pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
gateway-provider-rewrite/pom.xml | 2 +-
gateway-provider-security-authc-anon/pom.xml | 2 +-
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-pac4j/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/pom.xml | 6 +-
gateway-server-launcher/pom.xml | 2 +-
gateway-server-xforwarded-filter/pom.xml | 2 +-
gateway-server/pom.xml | 2 +-
.../knox/gateway/deploy/DeploymentFactory.java | 23 +
.../ServiceDefinitionDeploymentContributor.java | 14 +-
.../instr/InstrHttpClientBuilderProvider.java | 3 +-
.../builder/BeanPropertyTopologyBuilder.java | 11 +
.../topology/simple/SimpleDescriptor.java | 10 +
.../simple/SimpleDescriptorHandler.java | 51 +-
.../topology/simple/SimpleDescriptorImpl.java | 42 +-
.../xml/KnoxFormatXmlTopologyRules.java | 2 +
.../src/main/resources/conf/topology-v1.xsd | 1 +
.../simple/SimpleDescriptorFactoryTest.java | 631 +++++++++++++------
.../simple/SimpleDescriptorHandlerTest.java | 8 +
gateway-service-admin/pom.xml | 4 +-
.../service/admin/TopologiesResource.java | 25 +-
.../service/admin/beans/BeanConverter.java | 2 +
.../gateway/service/admin/beans/Topology.java | 11 +
gateway-service-as/pom.xml | 2 +-
gateway-service-definitions/pom.xml | 2 +-
.../service/definition/CustomDispatch.java | 11 +
.../resources/services/livy/0.4.0/rewrite.xml | 33 +
.../resources/services/livy/0.4.0/service.xml | 28 +
.../resources/services/nifi/1.4.0/rewrite.xml | 27 +
.../resources/services/nifi/1.4.0/service.xml | 30 +
.../services/oozieui/4.2.0/rewrite.xml | 27 +-
gateway-service-hbase/pom.xml | 2 +-
gateway-service-health/pom.xml | 4 +-
gateway-service-hive/pom.xml | 2 +-
gateway-service-knoxsso/pom.xml | 4 +-
gateway-service-knoxssout/pom.xml | 4 +-
gateway-service-knoxtoken/pom.xml | 4 +-
gateway-service-nifi/pom.xml | 38 ++
.../hadoop/gateway/dispatch/NiFiDispatch.java | 106 ++++
.../hadoop/gateway/dispatch/NiFiHaDispatch.java | 111 ++++
.../hadoop/gateway/dispatch/NiFiHeaders.java | 26 +
.../gateway/dispatch/NiFiRequestUtil.java | 89 +++
.../gateway/dispatch/NiFiResponseUtil.java | 89 +++
gateway-service-rm/pom.xml | 2 +-
gateway-service-storm/pom.xml | 2 +-
gateway-service-test/pom.xml | 4 +-
gateway-service-tgs/pom.xml | 2 +-
gateway-service-vault/pom.xml | 4 +-
gateway-service-webhdfs/pom.xml | 2 +-
gateway-shell-launcher/pom.xml | 2 +-
gateway-shell-release/pom.xml | 2 +-
gateway-shell-samples/pom.xml | 2 +-
gateway-shell/pom.xml | 2 +-
gateway-spi/pom.xml | 6 +-
.../dispatch/DefaultHttpClientFactory.java | 55 +-
.../knox/gateway/i18n/GatewaySpiMessages.java | 3 +
.../apache/knox/gateway/topology/Topology.java | 9 +
gateway-test-release-utils/pom.xml | 2 +-
gateway-test-release/pom.xml | 2 +-
gateway-test-release/webhdfs-kerb-test/pom.xml | 4 +-
gateway-test-release/webhdfs-test/pom.xml | 4 +-
gateway-test-utils/pom.xml | 2 +-
gateway-test/pom.xml | 2 +-
.../deploy/DeploymentFactoryFuncTest.java | 5 +
gateway-util-common/pom.xml | 2 +-
gateway-util-configinjector/pom.xml | 2 +-
gateway-util-launcher/pom.xml | 2 +-
gateway-util-urltemplate/pom.xml | 2 +-
hadoop-examples/pom.xml | 2 +-
knox-cli-launcher/pom.xml | 2 +-
pom.xml | 10 +-
99 files changed, 1504 insertions(+), 289 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-demo-ldap-launcher/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-demo-ldap/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/DefaultURLManagerTest.java
----------------------------------------------------------------------
diff --cc gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/DefaultURLManagerTest.java
index c8b6c58,0000000..a2cfa54
mode 100644,000000..100644
--- a/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/DefaultURLManagerTest.java
+++ b/gateway-provider-ha/src/test/java/org/apache/knox/gateway/ha/provider/impl/DefaultURLManagerTest.java
@@@ -1,73 -1,0 +1,92 @@@
+/**
+ * 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.knox.gateway.ha.provider.impl;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class DefaultURLManagerTest {
+
+ @Test
+ public void testActiveURLManagement() {
+ ArrayList<String> urls = new ArrayList<>();
+ String url1 = "http://host1";
+ urls.add(url1);
+ String url2 = "http://host2";
+ urls.add(url2);
+ DefaultURLManager manager = new DefaultURLManager();
+ manager.setURLs(urls);
+ assertTrue(manager.getURLs().containsAll(urls));
+ assertEquals(url1, manager.getActiveURL());
+ manager.markFailed(url1);
+ assertEquals(url2, manager.getActiveURL());
+ manager.markFailed(url2);
+ assertEquals(url1, manager.getActiveURL());
+ }
+
++ /**
++ * KNOX-1104
++ * Verify that a service with HaProvider configuration, but only a single URL does not break the HaProvider.
++ */
++ @Test
++ public void testSingleURLManagement() {
++ ArrayList<String> urls = new ArrayList<>();
++ String url1 = "http://host1";
++ urls.add(url1);
++ DefaultURLManager manager = new DefaultURLManager();
++ manager.setURLs(urls);
++ assertTrue(manager.getURLs().containsAll(urls));
++ assertEquals(url1, manager.getActiveURL());
++ manager.markFailed(url1);
++ assertEquals(url1, manager.getActiveURL());
++ manager.markFailed(url1);
++ assertEquals(url1, manager.getActiveURL());
++ }
++
+ @Test
+ public void testMarkingFailedURL() {
+ ArrayList<String> urls = new ArrayList<>();
+ String url1 = "http://host1:4555";
+ urls.add(url1);
+ String url2 = "http://host2:1234";
+ urls.add(url2);
+ String url3 = "http://host1:1234";
+ urls.add(url3);
+ String url4 = "http://host2:4555";
+ urls.add(url4);
+ DefaultURLManager manager = new DefaultURLManager();
+ manager.setURLs(urls);
+ assertTrue(manager.getURLs().containsAll(urls));
+ assertEquals(url1, manager.getActiveURL());
+ manager.markFailed(url1);
+ assertEquals(url2, manager.getActiveURL());
+ manager.markFailed(url1);
+ assertEquals(url2, manager.getActiveURL());
+ manager.markFailed(url3);
+ assertEquals(url2, manager.getActiveURL());
+ manager.markFailed(url4);
+ assertEquals(url2, manager.getActiveURL());
+ manager.markFailed(url2);
+ assertEquals(url3, manager.getActiveURL());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-release/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server-launcher/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
index bb8f1f2,0000000..b3eabb2
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java
@@@ -1,772 -1,0 +1,795 @@@
+/**
+ * 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.knox.gateway.deploy;
+
+import java.beans.Statement;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.GatewayServlet;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.deploy.impl.ApplicationDeploymentContributor;
+import org.apache.knox.gateway.descriptor.GatewayDescriptor;
+import org.apache.knox.gateway.descriptor.GatewayDescriptorFactory;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.registry.ServiceRegistry;
+import org.apache.knox.gateway.topology.Application;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+import org.apache.knox.gateway.topology.Topology;
+import org.apache.knox.gateway.topology.Version;
+import org.apache.knox.gateway.util.ServiceDefinitionsLoader;
+import org.apache.knox.gateway.util.Urls;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.Asset;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.descriptor.api.Descriptors;
+import org.jboss.shrinkwrap.descriptor.api.webapp30.WebAppDescriptor;
+import org.jboss.shrinkwrap.descriptor.api.webcommon30.FilterType;
+import org.jboss.shrinkwrap.descriptor.api.webcommon30.ServletType;
+
+public abstract class DeploymentFactory {
+
+ private static final String SERVLET_NAME_SUFFIX = "-knox-gateway-servlet";
+ private static final String FILTER_NAME_SUFFIX = "-knox-gateway-filter";
+ private static final GatewayMessages log = MessagesFactory.get( GatewayMessages.class );
+ private static GatewayServices gatewayServices = null;
+
+ private static Map<String,Map<String,Map<Version, ServiceDeploymentContributor>>> SERVICE_CONTRIBUTOR_MAP;
+ static {
+ loadServiceContributors();
+ }
+
+ private static Set<ProviderDeploymentContributor> PROVIDER_CONTRIBUTORS;
+ private static Map<String,Map<String,ProviderDeploymentContributor>> PROVIDER_CONTRIBUTOR_MAP;
+ static {
+ loadProviderContributors();
+ }
+
+ public static void setGatewayServices(GatewayServices services) {
+ DeploymentFactory.gatewayServices = services;
+ }
+
+ static List<Application> findApplicationsByUrl( Topology topology, String url ) {
+ List<Application> foundApps = new ArrayList<Application>();
+ if( topology != null ) {
+ url = Urls.trimLeadingAndTrailingSlash( url );
+ Collection<Application> searchApps = topology.getApplications();
+ if( searchApps != null ) {
+ for( Application searchApp : searchApps ) {
+ List<String> searchUrls = searchApp.getUrls();
+ if( searchUrls == null || searchUrls.isEmpty() ) {
+ searchUrls = new ArrayList<String>(1);
+ searchUrls.add( searchApp.getName() );
+ }
+ for( String searchUrl : searchUrls ) {
+ if( url.equalsIgnoreCase( Urls.trimLeadingAndTrailingSlash( searchUrl ) ) ) {
+ foundApps.add( searchApp );
+ break;
+ }
+ }
+ }
+ }
+ }
+ return foundApps;
+ }
+
+ // Verify that there are no two apps with duplicate urls.
+ static void validateNoAppsWithDuplicateUrlsInTopology( Topology topology ) {
+ if( topology != null ) {
+ Collection<Application> apps = topology.getApplications();
+ if( apps != null ) {
+ for( Application app : apps ) {
+ List<String> urls = app.getUrls();
+ if( urls == null || urls.isEmpty() ) {
+ urls = new ArrayList<String>(1);
+ urls.add( app.getName() );
+ }
+ for( String url : urls ) {
+ List<Application> dups = findApplicationsByUrl( topology, url );
+ if( dups != null ) {
+ for( Application dup : dups ) {
+ if( dup != app ) {
+ throw new DeploymentException( "Topology " + topology.getName() + " contains applications " + app.getName() + " and " + dup.getName() + " with the same url: " + url );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Verify that if there are services that there are no applications with a root url.
+ static void validateNoAppsWithRootUrlsInServicesTopology( Topology topology ) {
+ if( topology != null ) {
+ if( topology.getServices() != null && !topology.getServices().isEmpty() ) {
+ List<Application> dups = findApplicationsByUrl( topology, "/" );
+ if( dups != null && !dups.isEmpty() ) {
+ throw new DeploymentException( "Topology " + topology.getName() + " contains both services and an application " + dups.get( 0 ).getName() + " with a root url." );
+ }
+ }
+ }
+ }
+
+ static void validateTopology( Topology topology ) {
+ validateNoAppsWithRootUrlsInServicesTopology( topology );
+ validateNoAppsWithDuplicateUrlsInTopology( topology );
+ }
+
+ public static EnterpriseArchive createDeployment( GatewayConfig config, Topology topology ) {
+ validateTopology( topology );
+ loadStacksServiceContributors( config );
+ Map<String,List<ProviderDeploymentContributor>> providers = selectContextProviders( topology );
+ Map<String,List<ServiceDeploymentContributor>> services = selectContextServices( topology );
+ Map<String,ServiceDeploymentContributor> applications = selectContextApplications( config, topology );
+ EnterpriseArchive ear = ShrinkWrap.create( EnterpriseArchive.class, topology.getName() );
+ ear.addAsResource( toStringAsset( topology ), "topology.xml" );
+ if( !services.isEmpty() ) {
+ WebArchive war = createServicesDeployment( config, topology, providers, services );
+ ear.addAsModule( war );
+ }
+ if( !applications.isEmpty() ) {
+ for( Map.Entry<String, ServiceDeploymentContributor> application : applications.entrySet() ) {
+ WebArchive war = createApplicationDeployment( config, topology, providers, application );
+ ear.addAsModule( war );
+ }
+ }
+ return ear;
+ }
+
+ private static WebArchive createServicesDeployment(
+ GatewayConfig config,
+ Topology topology,
+ Map<String,List<ProviderDeploymentContributor>> providers,
+ Map<String,List<ServiceDeploymentContributor>> services ) {
+ DeploymentContext context = createDeploymentContext( config, "/", topology, providers );
+ initialize( context, providers, services, null );
+ contribute( context, providers, services, null );
+ finalize( context, providers, services, null );
+ return context.getWebArchive();
+ }
+
+ public static WebArchive createApplicationDeployment(
+ GatewayConfig config,
+ Topology topology,
+ Map<String,List<ProviderDeploymentContributor>> providers,
+ Map.Entry<String,ServiceDeploymentContributor> application ) {
+ String appPath = "/" + Urls.trimLeadingAndTrailingSlash( application.getKey() );
+ DeploymentContext context = createDeploymentContext( config, appPath, topology, providers );
+ initialize( context, providers, null, application );
+ contribute( context, providers, null, application );
+ finalize( context, providers, null, application );
+ return context.getWebArchive();
+ }
+
+ private static Asset toStringAsset( Topology topology ) {
+ StringWriter writer = new StringWriter();
+ String xml;
+ try {
+ Map<String,Object> properties = new HashMap<>(2);
+ properties.put( "eclipselink-oxm-xml",
+ "org/apache/knox/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();
+ } catch (IOException e) {
+ throw new DeploymentException( "Failed to marshall topology.", e );
+ } catch (JAXBException e) {
+ throw new DeploymentException( "Failed to marshall topology.", e );
+ }
+ StringAsset asset = new StringAsset( xml );
+ return asset;
+ }
+
+ private static DeploymentContext createDeploymentContext(
+ GatewayConfig config,
+ String archivePath,
+ Topology topology,
+ Map<String,List<ProviderDeploymentContributor>> providers ) {
+ archivePath = Urls.encode( archivePath );
+ WebArchive webArchive = ShrinkWrap.create( WebArchive.class, archivePath );
+ WebAppDescriptor webAppDesc = Descriptors.create( WebAppDescriptor.class );
+ GatewayDescriptor gateway = GatewayDescriptorFactory.create();
+ DeploymentContext context = new DeploymentContextImpl(
+ config, topology, gateway, webArchive, webAppDesc, providers );
+ return context;
+ }
+
+ // Scan through the providers in the topology. Collect any named providers in their roles list.
+ // Scan through all of the loaded providers. For each that doesn't have an existing provider in the role
+ // list add it.
+ private static Map<String,List<ProviderDeploymentContributor>> selectContextProviders( Topology topology ) {
+ Map<String,List<ProviderDeploymentContributor>> providers = new LinkedHashMap<String, List<ProviderDeploymentContributor>>();
++ addMissingDefaultProviders(topology);
+ collectTopologyProviders( topology, providers );
+ collectDefaultProviders( providers );
+ return providers;
+ }
+
++ private static void addMissingDefaultProviders(Topology topology) {
++ Collection<Provider> providers = topology.getProviders();
++ HashMap<String, String> providerMap = new HashMap<>();
++ for (Provider provider : providers) {
++ providerMap.put(provider.getRole(), provider.getName());
++ }
++ // first make sure that the required provider is available from the serviceloaders
++ // for some tests the number of providers are limited to the classpath of the module
++ // and exceptions will be thrown as topologies are deployed even though they will
++ // work fine at actual server runtime.
++ if (PROVIDER_CONTRIBUTOR_MAP.get("identity-assertion") != null) {
++ // check for required providers and add the defaults if missing
++ if (!providerMap.containsKey("identity-assertion")) {
++ Provider idassertion = new Provider();
++ idassertion.setRole("identity-assertion");
++ idassertion.setName("Default");
++ idassertion.setEnabled(true);
++ providers.add(idassertion);
++ }
++ }
++ }
++
+ private static void collectTopologyProviders(
+ Topology topology, Map<String, List<ProviderDeploymentContributor>> defaults ) {
+ for( Provider provider : topology.getProviders() ) {
+ String name = provider.getName();
+ if( name != null ) {
+ String role = provider.getRole();
+ Map<String,ProviderDeploymentContributor> nameMap = PROVIDER_CONTRIBUTOR_MAP.get( role );
+ if( nameMap != null ) {
+ ProviderDeploymentContributor contributor = nameMap.get( name );
+ // If there isn't a contributor with this role/name try to find a "*" contributor.
+ if( contributor == null ) {
+ nameMap = PROVIDER_CONTRIBUTOR_MAP.get( "*" );
+ if( nameMap != null ) {
+ contributor = nameMap.get( name );
+ }
+ }
+ if( contributor != null ) {
+ List list = defaults.get( role );
+ if( list == null ) {
+ list = new ArrayList( 1 );
+ defaults.put( role, list );
+ }
+ if( !list.contains( contributor ) ) {
+ list.add( contributor );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static void collectDefaultProviders( Map<String,List<ProviderDeploymentContributor>> defaults ) {
+ for( ProviderDeploymentContributor contributor : PROVIDER_CONTRIBUTORS ) {
+ String role = contributor.getRole();
+ List<ProviderDeploymentContributor> list = defaults.get( role );
+ if( list == null ) {
+ list = new ArrayList<ProviderDeploymentContributor>();
+ defaults.put( role, list );
+ }
+ if( list.isEmpty() ) {
+ list.add( contributor );
+ }
+ }
+ }
+
+ // Scan through the services in the topology.
+ // For each that we find add it to the list of service roles included in the topology.
+ private static Map<String,List<ServiceDeploymentContributor>> selectContextServices( Topology topology ) {
+ Map<String,List<ServiceDeploymentContributor>> defaults
+ = new HashMap<>();
+ for( Service service : topology.getServices() ) {
+ String role = service.getRole();
+ ServiceDeploymentContributor contributor = getServiceContributor( role, service.getName(), service.getVersion() );
+ if( contributor != null ) {
+ List<ServiceDeploymentContributor> list = defaults.get( role );
+ if( list == null ) {
+ list = new ArrayList<ServiceDeploymentContributor>( 1 );
+ defaults.put( role, list );
+ }
+ if( !list.contains( contributor ) ) {
+ list.add( contributor );
+ }
+ }
+ }
+ return defaults;
+ }
+
+ private static Map<String,ServiceDeploymentContributor> selectContextApplications(
+ GatewayConfig config, Topology topology ) {
+ Map<String,ServiceDeploymentContributor> contributors = new HashMap<>();
+ if( topology != null ) {
+ for( Application application : topology.getApplications() ) {
+ String name = application.getName();
+ if( name == null || name.isEmpty() ) {
+ throw new DeploymentException( "Topologies cannot contain an application without a name." );
+ }
+ ApplicationDeploymentContributor contributor = new ApplicationDeploymentContributor( config, application );
+ List<String> urls = application.getUrls();
+ if( urls == null || urls.isEmpty() ) {
+ urls = new ArrayList<String>( 1 );
+ urls.add( "/" + name );
+ }
+ for( String url : urls ) {
+ if( url == null || url.isEmpty() || url.equals( "/" ) ) {
+ if( !topology.getServices().isEmpty() ) {
+ throw new DeploymentException( String.format(
+ "Topologies with services cannot contain an application (%s) with a root url.", name ) );
+ }
+ }
+ contributors.put( url, contributor );
+ }
+ }
+ }
+ return contributors;
+ }
+
+ private static void initialize(
+ DeploymentContext context,
+ Map<String,List<ProviderDeploymentContributor>> providers,
+ Map<String,List<ServiceDeploymentContributor>> services,
+ Map.Entry<String,ServiceDeploymentContributor> applications ) {
+ WebAppDescriptor wad = context.getWebAppDescriptor();
+ String topoName = context.getTopology().getName();
+ if( applications == null ) {
+ String servletName = topoName + SERVLET_NAME_SUFFIX;
+ wad.createServlet().servletName( servletName ).servletClass( GatewayServlet.class.getName() );
+ wad.createServletMapping().servletName( servletName ).urlPattern( "/*" );
+ } else {
+ String filterName = topoName + FILTER_NAME_SUFFIX;
+ wad.createFilter().filterName( filterName ).filterClass( GatewayServlet.class.getName() );
+ wad.createFilterMapping().filterName( filterName ).urlPattern( "/*" );
+ }
+ if (gatewayServices != null) {
+ gatewayServices.initializeContribution(context);
+ } else {
+ log.gatewayServicesNotInitialized();
+ }
+ initializeProviders( context, providers );
+ initializeServices( context, services );
+ initializeApplications( context, applications );
+ }
+
+ private static void initializeProviders(
+ DeploymentContext context,
+ Map<String,List<ProviderDeploymentContributor>> providers ) {
+ if( providers != null ) {
+ for( Entry<String, List<ProviderDeploymentContributor>> entry : providers.entrySet() ) {
+ for( ProviderDeploymentContributor contributor : entry.getValue() ) {
+ try {
+ injectServices( contributor );
+ log.initializeProvider( contributor.getName(), contributor.getRole() );
+ contributor.initializeContribution( context );
+ } catch( Exception e ) {
+ log.failedToInitializeContribution( e );
+ throw new DeploymentException( "Failed to initialize contribution.", e );
+ }
+ }
+ }
+ }
+ }
+
+ private static void initializeServices( DeploymentContext context, Map<String, List<ServiceDeploymentContributor>> services ) {
+ if( services != null ) {
+ for( Entry<String, List<ServiceDeploymentContributor>> entry : services.entrySet() ) {
+ for( ServiceDeploymentContributor contributor : entry.getValue() ) {
+ try {
+ injectServices( contributor );
+ log.initializeService( contributor.getName(), contributor.getRole() );
+ contributor.initializeContribution( context );
+ } catch( Exception e ) {
+ log.failedToInitializeContribution( e );
+ throw new DeploymentException( "Failed to initialize contribution.", e );
+ }
+ }
+ }
+ }
+ }
+
+ private static void initializeApplications( DeploymentContext context, Map.Entry<String, ServiceDeploymentContributor> application ) {
+ if( application != null ) {
+ ServiceDeploymentContributor contributor = application.getValue();
+ if( contributor != null ) {
+ try {
+ injectServices( contributor );
+ log.initializeApplication( contributor.getName() );
+ contributor.initializeContribution( context );
+ } catch( Exception e ) {
+ log.failedToInitializeContribution( e );
+ throw new DeploymentException( "Failed to initialize application contribution.", e );
+ }
+ }
+ }
+ }
+
+ private static void injectServices(Object contributor) {
+ if (gatewayServices != null) {
+ Statement stmt = null;
+ for(String serviceName : gatewayServices.getServiceNames()) {
+
+ try {
+ // TODO: this is just a temporary injection solution
+ // TODO: test for the existence of the setter before attempting it
+ // TODO: avoid exception throwing when there is no setter
+ stmt = new Statement(contributor, "set" + serviceName, new Object[]{gatewayServices.getService(serviceName)});
+ stmt.execute();
+ } catch (NoSuchMethodException e) {
+ // TODO: eliminate the possibility of this being thrown up front
+ } catch (Exception e) {
+ // Maybe it makes sense to throw exception
+ log.failedToInjectService( serviceName, e );
+ throw new DeploymentException("Failed to inject service.", e);
+ }
+ }
+ }
+ }
+
+ private static void contribute(
+ DeploymentContext context,
+ Map<String,List<ProviderDeploymentContributor>> providers,
+ Map<String,List<ServiceDeploymentContributor>> services,
+ Map.Entry<String,ServiceDeploymentContributor> applications ) {
+ Topology topology = context.getTopology();
+ contributeProviders( context, topology, providers );
+ contributeServices( context, topology, services );
+ contributeApplications( context, topology, applications );
+ }
+
+ private static void contributeProviders( DeploymentContext context, Topology topology, Map<String, List<ProviderDeploymentContributor>> providers ) {
+ for( Provider provider : topology.getProviders() ) {
+ ProviderDeploymentContributor contributor = getProviderContributor( providers, provider.getRole(), provider.getName() );
+ if( contributor != null && provider.isEnabled() ) {
+ try {
+ log.contributeProvider( provider.getName(), provider.getRole() );
+ contributor.contributeProvider( context, provider );
+ } catch( Exception e ) {
+ // Maybe it makes sense to throw exception
+ log.failedToContributeProvider( provider.getName(), provider.getRole(), e );
+ throw new DeploymentException("Failed to contribute provider.", e);
+ }
+ }
+ }
+ }
+
+ private static void contributeServices( DeploymentContext context, Topology topology, Map<String, List<ServiceDeploymentContributor>> services ) {
+ if( services != null ) {
+ for( Service service : topology.getServices() ) {
+ ServiceDeploymentContributor contributor = getServiceContributor( service.getRole(), service.getName(), service.getVersion() );
+ if( contributor != null ) {
+ try {
+ log.contributeService( service.getName(), service.getRole() );
+ contributor.contributeService( context, service );
+ if( gatewayServices != null ) {
+ ServiceRegistry sr = gatewayServices.getService( GatewayServices.SERVICE_REGISTRY_SERVICE );
+ if( sr != null ) {
+ String regCode = sr.getRegistrationCode( topology.getName() );
+ sr.registerService( regCode, topology.getName(), service.getRole(), service.getUrls() );
+ }
+ }
+ } catch( Exception e ) {
+ // Maybe it makes sense to throw exception
+ log.failedToContributeService( service.getName(), service.getRole(), e );
+ throw new DeploymentException( "Failed to contribute service.", e );
+ }
+ }
+ }
+ }
+ }
+
+ private static void contributeApplications( DeploymentContext context, Topology topology, Map.Entry<String, ServiceDeploymentContributor> applications ) {
+ if( applications != null ) {
+ ServiceDeploymentContributor contributor = applications.getValue();
+ if( contributor != null ) {
+ try {
+ log.contributeApplication( contributor.getName() );
+ Application applicationDesc = topology.getApplication( applications.getKey() );
+ contributor.contributeService( context, applicationDesc );
+ } catch( Exception e ) {
+ log.failedToInitializeContribution( e );
+ throw new DeploymentException( "Failed to contribution application.", e );
+ }
+ }
+ }
+ }
+
+ public static ProviderDeploymentContributor getProviderContributor( String role, String name ) {
+ ProviderDeploymentContributor contributor = null;
+ Map<String,ProviderDeploymentContributor> nameMap = PROVIDER_CONTRIBUTOR_MAP.get( role );
+ if( nameMap != null ) {
+ if( name != null ) {
+ contributor = nameMap.get( name );
+ } else if ( !nameMap.isEmpty() ) {
+ contributor = nameMap.values().iterator().next();
+ }
+ }
+ return contributor;
+ }
+
+ public static ServiceDeploymentContributor getServiceContributor( String role, String name, Version version ) {
+ ServiceDeploymentContributor contributor = null;
+ Map<String,Map<Version, ServiceDeploymentContributor>> nameMap = SERVICE_CONTRIBUTOR_MAP.get( role );
+ if( nameMap != null && !nameMap.isEmpty()) {
+ Map<Version, ServiceDeploymentContributor> versionMap = null;
+ if ( name == null ) {
+ versionMap = nameMap.values().iterator().next();
+ } else {
+ versionMap = nameMap.get( name );
+ }
+ if ( versionMap != null && !versionMap.isEmpty()) {
+ if( version == null ) {
+ contributor = ((TreeMap<Version, ServiceDeploymentContributor>) versionMap).firstEntry().getValue();
+ } else {
+ contributor = versionMap.get( version );
+ }
+ }
+ }
+ return contributor;
+ }
+
+ private static void finalize(
+ DeploymentContext context,
+ Map<String,List<ProviderDeploymentContributor>> providers,
+ Map<String,List<ServiceDeploymentContributor>> services,
+ Map.Entry<String,ServiceDeploymentContributor> application ) {
+ try {
+ // Write the gateway descriptor (gateway.xml) into the war.
+ StringWriter writer = new StringWriter();
+ GatewayDescriptorFactory.store( context.getGatewayDescriptor(), "xml", writer );
+ context.getWebArchive().addAsWebInfResource(
+ new StringAsset( writer.toString() ),
+ GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
+
+ // Set the location of the gateway descriptor as a servlet init param.
+ if( application == null ) {
+ String servletName = context.getTopology().getName() + SERVLET_NAME_SUFFIX;
+ ServletType<WebAppDescriptor> servlet = findServlet( context, servletName );
+ // Coverity CID 1352314
+ if( servlet == null ) {
+ throw new DeploymentException( "Missing servlet " + servletName );
+ } else {
+ servlet.createInitParam()
+ .paramName( GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_PARAM )
+ .paramValue( "/WEB-INF/" + GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
+ }
+ } else {
+ String servletName = context.getTopology().getName() + FILTER_NAME_SUFFIX;
+ FilterType<WebAppDescriptor> filter = findFilter( context, servletName );
+ // Coverity CID 1352313
+ if( filter == null ) {
+ throw new DeploymentException( "Missing filter " + servletName );
+ } else {
+ filter.createInitParam()
+ .paramName( GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_PARAM )
+ .paramValue( "/WEB-INF/" + GatewayServlet.GATEWAY_DESCRIPTOR_LOCATION_DEFAULT );
+ }
+ }
+ if (gatewayServices != null) {
+ gatewayServices.finalizeContribution(context);
+ }
+ finalizeProviders( context, providers );
+ finalizeServices( context, services );
+ finalizeApplications( context, application );
+ writeDeploymentDescriptor( context, application != null );
+ } catch ( IOException e ) {
+ throw new RuntimeException( e );
+ }
+ }
+
+ private static void finalizeProviders( DeploymentContext context, Map<String, List<ProviderDeploymentContributor>> providers ) {
+ if( providers != null ) {
+ for( Entry<String, List<ProviderDeploymentContributor>> entry : providers.entrySet() ) {
+ for( ProviderDeploymentContributor contributor : entry.getValue() ) {
+ try {
+ log.finalizeProvider( contributor.getName(), contributor.getRole() );
+ contributor.finalizeContribution( context );
+ } catch( Exception e ) {
+ // Maybe it makes sense to throw exception
+ log.failedToFinalizeContribution( e );
+ throw new DeploymentException( "Failed to finalize contribution.", e );
+ }
+ }
+ }
+ }
+ }
+
+ private static void finalizeServices( DeploymentContext context, Map<String, List<ServiceDeploymentContributor>> services ) {
+ if( services != null ) {
+ for( Entry<String, List<ServiceDeploymentContributor>> entry : services.entrySet() ) {
+ for( ServiceDeploymentContributor contributor : entry.getValue() ) {
+ try {
+ log.finalizeService( contributor.getName(), contributor.getRole() );
+ contributor.finalizeContribution( context );
+ } catch( Exception e ) {
+ // Maybe it makes sense to throw exception
+ log.failedToFinalizeContribution( e );
+ throw new DeploymentException( "Failed to finalize contribution.", e );
+ }
+ }
+ }
+ }
+ }
+
+ private static void finalizeApplications( DeploymentContext context, Map.Entry<String, ServiceDeploymentContributor> application ) {
+ if( application != null ) {
+ ServiceDeploymentContributor contributor = application.getValue();
+ if( contributor != null ) {
+ try {
+ log.finalizeApplication( contributor.getName() );
+ contributor.finalizeContribution( context );
+ } catch( Exception e ) {
+ log.failedToInitializeContribution( e );
+ throw new DeploymentException( "Failed to contribution application.", e );
+ }
+ }
+ }
+ }
+
+ private static void writeDeploymentDescriptor( DeploymentContext context, boolean override ) {
+ // Write the web.xml into the war.
+ Asset webXmlAsset = new StringAsset( context.getWebAppDescriptor().exportAsString() );
+ if( override ) {
+ context.getWebArchive().addAsWebInfResource( webXmlAsset, "override-web.xml" );
+ } else {
+ context.getWebArchive().setWebXML( webXmlAsset );
+ }
+ }
+
+ public static ServletType<WebAppDescriptor> findServlet( DeploymentContext context, String name ) {
+ List<ServletType<WebAppDescriptor>> servlets = context.getWebAppDescriptor().getAllServlet();
+ for( ServletType<WebAppDescriptor> servlet : servlets ) {
+ if( name.equals( servlet.getServletName() ) ) {
+ return servlet;
+ }
+ }
+ return null;
+ }
+
+ public static FilterType<WebAppDescriptor> findFilter( DeploymentContext context, String name ) {
+ List<FilterType<WebAppDescriptor>> filters = context.getWebAppDescriptor().getAllFilter();
+ for( FilterType<WebAppDescriptor> filter : filters ) {
+ if( name.equals( filter.getFilterName() ) ) {
+ return filter;
+ }
+ }
+ return null;
+ }
+
+ private static void loadStacksServiceContributors( GatewayConfig config ) {
+ String stacks = config.getGatewayServicesDir();
+ log.usingServicesDirectory(stacks);
+ File stacksDir = new File(stacks);
+ Set<ServiceDeploymentContributor> deploymentContributors = ServiceDefinitionsLoader
+ .loadServiceDefinitions(stacksDir);
+ addServiceDeploymentContributors(deploymentContributors.iterator());
+ }
+
+ private static void loadServiceContributors() {
+ SERVICE_CONTRIBUTOR_MAP = new HashMap<>();
+ ServiceLoader<ServiceDeploymentContributor> loader = ServiceLoader.load( ServiceDeploymentContributor.class );
+ Iterator<ServiceDeploymentContributor> contributors = loader.iterator();
+ addServiceDeploymentContributors(contributors);
+ }
+
+ private static void addServiceDeploymentContributors(Iterator<ServiceDeploymentContributor> contributors) {
+ while( contributors.hasNext() ) {
+ ServiceDeploymentContributor contributor = contributors.next();
+ if( contributor.getName() == null ) {
+ log.ignoringServiceContributorWithMissingName( contributor.getClass().getName() );
+ continue;
+ }
+ if( contributor.getRole() == null ) {
+ log.ignoringServiceContributorWithMissingRole( contributor.getClass().getName() );
+ continue;
+ }
+ if( contributor.getVersion() == null ) {
+ log.ignoringServiceContributorWithMissingVersion(contributor.getClass().getName());
+ continue;
+ }
+ Map<String,Map<Version, ServiceDeploymentContributor>> nameMap = SERVICE_CONTRIBUTOR_MAP.get( contributor.getRole() );
+ if( nameMap == null ) {
+ nameMap = new HashMap<>();
+ SERVICE_CONTRIBUTOR_MAP.put( contributor.getRole(), nameMap );
+ }
+ Map<Version, ServiceDeploymentContributor> versionMap = nameMap.get(contributor.getName());
+ if (versionMap == null) {
+ versionMap = new TreeMap<>();
+ nameMap.put(contributor.getName(), versionMap);
+ }
+ versionMap.put( contributor.getVersion(), contributor );
+ }
+ }
+
+ private static void loadProviderContributors() {
+ Set<ProviderDeploymentContributor> set = new HashSet<>();
+ Map<String,Map<String,ProviderDeploymentContributor>> roleMap
+ = new HashMap<>();
+
+ ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
+ Iterator<ProviderDeploymentContributor> contributors = loader.iterator();
+ while( contributors.hasNext() ) {
+ ProviderDeploymentContributor contributor = contributors.next();
+ if( contributor.getName() == null ) {
+ log.ignoringProviderContributorWithMissingName( contributor.getClass().getName() );
+ continue;
+ }
+ if( contributor.getRole() == null ) {
+ log.ignoringProviderContributorWithMissingRole( contributor.getClass().getName() );
+ continue;
+ }
+ set.add( contributor );
+ Map nameMap = roleMap.get( contributor.getRole() );
+ if( nameMap == null ) {
+ nameMap = new HashMap<>();
+ roleMap.put( contributor.getRole(), nameMap );
+ }
+ nameMap.put( contributor.getName(), contributor );
+ }
+ PROVIDER_CONTRIBUTORS = set;
+ PROVIDER_CONTRIBUTOR_MAP = roleMap;
+ }
+
+ static ProviderDeploymentContributor getProviderContributor(
+ Map<String,List<ProviderDeploymentContributor>> providers, String role, String name ) {
+ ProviderDeploymentContributor contributor = null;
+ if( name == null ) {
+ List<ProviderDeploymentContributor> list = providers.get( role );
+ if( list != null && !list.isEmpty() ) {
+ contributor = list.get( 0 );
+ }
+ } else {
+ contributor = getProviderContributor( role, name );
+ // Explicit configuration that is wrong should just fail
+ // rather than randomly select a provider. Implicit default
+ // providers can be selected when no name is provided.
+ if (contributor == null || !contributor.getRole().equals(role) ||
+ !contributor.getName().equals(name)) {
+ throw new DeploymentException(
+ "Failed to contribute provider. Role: " +
+ role + " Name: " + name + ". Please check the topology for" +
+ " errors in name and role and that the provider is " +
+ "on the classpath.");
+ }
+ }
+ return contributor;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
index a056ac7,0000000..7e69af5
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ServiceDefinitionDeploymentContributor.java
@@@ -1,256 -1,0 +1,264 @@@
+/**
+ * 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.knox.gateway.deploy.impl;
+
+import org.apache.knox.gateway.config.impl.GatewayConfigImpl;
+import org.apache.knox.gateway.deploy.DeploymentContext;
+import org.apache.knox.gateway.deploy.ServiceDeploymentContributorBase;
+import org.apache.knox.gateway.descriptor.FilterDescriptor;
+import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
+import org.apache.knox.gateway.descriptor.ResourceDescriptor;
+import org.apache.knox.gateway.dispatch.GatewayDispatchFilter;
+import org.apache.knox.gateway.filter.XForwardedHeaderFilter;
+import org.apache.knox.gateway.filter.rewrite.api.CookieScopeServletFilter;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+import org.apache.knox.gateway.service.definition.CustomDispatch;
+import org.apache.knox.gateway.service.definition.Policy;
+import org.apache.knox.gateway.service.definition.Rewrite;
+import org.apache.knox.gateway.service.definition.Route;
+import org.apache.knox.gateway.service.definition.ServiceDefinition;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+import org.apache.knox.gateway.topology.Version;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ServiceDefinitionDeploymentContributor extends ServiceDeploymentContributorBase {
+
+ private static final String DISPATCH_ROLE = "dispatch";
+
+ private static final String DISPATCH_IMPL_PARAM = "dispatch-impl";
+
+ private static final String HTTP_CLIENT_FACTORY_PARAM = "httpClientFactory";
+
+ private static final String SERVICE_ROLE_PARAM = "serviceRole";
+
+ private static final String XFORWARDED_FILTER_NAME = "XForwardedHeaderFilter";
+
+ private static final String XFORWARDED_FILTER_ROLE = "xforwardedheaders";
+
+ private static final String DEFAULT_HA_DISPATCH_CLASS = "org.apache.knox.gateway.ha.dispatch.DefaultHaDispatch";
+
+ private static final String COOKIE_SCOPING_FILTER_NAME = "CookieScopeServletFilter";
+
+ private static final String COOKIE_SCOPING_FILTER_ROLE = "cookiescopef";
+
+ private ServiceDefinition serviceDefinition;
+
+ private UrlRewriteRulesDescriptor serviceRules;
+
+ public ServiceDefinitionDeploymentContributor(ServiceDefinition serviceDefinition, UrlRewriteRulesDescriptor serviceRules) {
+ this.serviceDefinition = serviceDefinition;
+ this.serviceRules = serviceRules;
+ }
+
+ @Override
+ public String getRole() {
+ return serviceDefinition.getRole();
+ }
+
+ @Override
+ public String getName() {
+ return serviceDefinition.getName();
+ }
+
+ @Override
+ public Version getVersion() {
+ return new Version(serviceDefinition.getVersion());
+ }
+
+ @Override
+ public void contributeService(DeploymentContext context, Service service) throws Exception {
+ contributeRewriteRules(context, service);
+ contributeResources(context, service);
+ }
+
+ private void contributeRewriteRules(DeploymentContext context, Service service) {
+ if ( serviceRules != null ) {
+ UrlRewriteRulesDescriptor clusterRules = context.getDescriptor("rewrite");
+ clusterRules.addRules(serviceRules);
+ }
+ }
+
+ private void contributeResources(DeploymentContext context, Service service) {
+ Map<String, String> filterParams = new HashMap<>();
+ List<Route> bindings = serviceDefinition.getRoutes();
+ for ( Route binding : bindings ) {
+ List<Rewrite> filters = binding.getRewrites();
+ if ( filters != null && !filters.isEmpty() ) {
+ filterParams.clear();
+ for ( Rewrite filter : filters ) {
+ filterParams.put(filter.getTo(), filter.getApply());
+ }
+ }
+ try {
+ contributeResource(context, service, binding, filterParams);
+ } catch ( URISyntaxException e ) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ private void contributeResource(DeploymentContext context, Service service, Route binding, Map<String, String> filterParams) throws URISyntaxException {
+ List<FilterParamDescriptor> params = new ArrayList<FilterParamDescriptor>();
+ ResourceDescriptor resource = context.getGatewayDescriptor().addResource();
+ resource.role(service.getRole());
+ resource.pattern(binding.getPath());
+ //add x-forwarded filter if enabled in config
+ if (context.getGatewayConfig().isXForwardedEnabled()) {
+ resource.addFilter().name(XFORWARDED_FILTER_NAME).role(XFORWARDED_FILTER_ROLE).impl(XForwardedHeaderFilter.class);
+ }
+ if (context.getGatewayConfig().isCookieScopingToPathEnabled()) {
+ FilterDescriptor filter = resource.addFilter().name(COOKIE_SCOPING_FILTER_NAME).role(COOKIE_SCOPING_FILTER_ROLE).impl(CookieScopeServletFilter.class);
+ filter.param().name(GatewayConfigImpl.HTTP_PATH).value(context.getGatewayConfig().getGatewayPath());
+ }
+ List<Policy> policyBindings = binding.getPolicies();
+ if ( policyBindings == null ) {
+ policyBindings = serviceDefinition.getPolicies();
+ }
+ if ( policyBindings == null ) {
+ //add default set
+ addDefaultPolicies(context, service, filterParams, params, resource);
+ } else {
+ addPolicies(context, service, filterParams, params, resource, policyBindings);
+ }
+ addDispatchFilter(context, service, resource, binding);
+ }
+
+ private void addPolicies(DeploymentContext context, Service service, Map<String, String> filterParams, List<FilterParamDescriptor> params, ResourceDescriptor resource, List<Policy> policyBindings) throws URISyntaxException {
+ for ( Policy policyBinding : policyBindings ) {
+ String role = policyBinding.getRole();
+ if ( role == null ) {
+ throw new IllegalArgumentException("Policy defined has no role for service " + service.getName());
+ }
+ role = role.trim().toLowerCase();
+ if ( "rewrite".equals(role) ) {
+ addRewriteFilter(context, service, filterParams, params, resource);
+ } else if ( topologyContainsProviderType(context, role) ) {
+ context.contributeFilter(service, resource, role, policyBinding.getName(), null);
+ }
+ }
+ }
+
+ private void addDefaultPolicies(DeploymentContext context, Service service, Map<String, String> filterParams, List<FilterParamDescriptor> params, ResourceDescriptor resource) throws URISyntaxException {
+ addWebAppSecFilters(context, service, resource);
+ addAuthenticationFilter(context, service, resource);
+ addRewriteFilter(context, service, filterParams, params, resource);
+ addIdentityAssertionFilter(context, service, resource);
+ addAuthorizationFilter(context, service, resource);
+ }
+
+ private void addRewriteFilter(DeploymentContext context, Service service, Map<String, String> filterParams, List<FilterParamDescriptor> params, ResourceDescriptor resource) throws URISyntaxException {
+ if ( !filterParams.isEmpty() ) {
+ for ( Map.Entry<String, String> filterParam : filterParams.entrySet() ) {
+ params.add(resource.createFilterParam().name(filterParam.getKey()).value(filterParam.getValue()));
+ }
+ }
+ addRewriteFilter(context, service, resource, params);
+ }
+
+ private void addDispatchFilter(DeploymentContext context, Service service, ResourceDescriptor resource, Route binding) {
+ CustomDispatch customDispatch = binding.getDispatch();
+ if ( customDispatch == null ) {
+ customDispatch = serviceDefinition.getDispatch();
+ }
+ boolean isHaEnabled = isHaEnabled(context);
+ if ( customDispatch != null ) {
+ String haContributorName = customDispatch.getHaContributorName();
+ String haClassName = customDispatch.getHaClassName();
+ String httpClientFactory = customDispatch.getHttpClientFactory();
++ boolean useTwoWaySsl = customDispatch.getUseTwoWaySsl();
+ if ( isHaEnabled) {
+ if (haContributorName != null) {
+ addDispatchFilter(context, service, resource, DISPATCH_ROLE, haContributorName);
+ } else if (haClassName != null) {
- addDispatchFilterForClass(context, service, resource, haClassName, httpClientFactory);
++ addDispatchFilterForClass(context, service, resource, haClassName, httpClientFactory, useTwoWaySsl);
+ } else {
+ addDefaultHaDispatchFilter(context, service, resource);
+ }
+ } else {
+ String contributorName = customDispatch.getContributorName();
+ if ( contributorName != null ) {
+ addDispatchFilter(context, service, resource, DISPATCH_ROLE, contributorName);
+ } else {
+ String className = customDispatch.getClassName();
+ if ( className != null ) {
- addDispatchFilterForClass(context, service, resource, className, httpClientFactory);
++ addDispatchFilterForClass(context, service, resource, className, httpClientFactory, useTwoWaySsl);
+ } else {
+ //final fallback to the default dispatch
+ addDispatchFilter(context, service, resource, DISPATCH_ROLE, "http-client");
+ }
+ }
+ }
+ } else if (isHaEnabled) {
+ addDefaultHaDispatchFilter(context, service, resource);
+ } else {
+ addDispatchFilter(context, service, resource, DISPATCH_ROLE, "http-client");
+ }
+ }
+
+ private void addDefaultHaDispatchFilter(DeploymentContext context, Service service, ResourceDescriptor resource) {
+ FilterDescriptor filter = addDispatchFilterForClass(context, service, resource, DEFAULT_HA_DISPATCH_CLASS, null);
+ filter.param().name(SERVICE_ROLE_PARAM).value(service.getRole());
+ }
+
- private FilterDescriptor addDispatchFilterForClass(DeploymentContext context, Service service, ResourceDescriptor resource, String dispatchClass, String httpClientFactory) {
++ private FilterDescriptor addDispatchFilterForClass(DeploymentContext context, Service service, ResourceDescriptor resource, String dispatchClass, String httpClientFactory, boolean useTwoWaySsl) {
+ FilterDescriptor filter = resource.addFilter().name(getName()).role(DISPATCH_ROLE).impl(GatewayDispatchFilter.class);
+ filter.param().name(DISPATCH_IMPL_PARAM).value(dispatchClass);
+ if (httpClientFactory != null) {
+ filter.param().name(HTTP_CLIENT_FACTORY_PARAM).value(httpClientFactory);
+ }
++ // let's take the value of useTwoWaySsl which is derived from the service definition
++ // then allow it to be overridden by service params from the topology
++ filter.param().name("useTwoWaySsl").value(Boolean.toString(useTwoWaySsl));
+ for ( Map.Entry<String, String> serviceParam : service.getParams().entrySet() ) {
+ filter.param().name(serviceParam.getKey()).value(serviceParam.getValue());
+ }
+ if ( context.getGatewayConfig().isHadoopKerberosSecured() ) {
+ filter.param().name("kerberos").value("true");
+ } else {
+ //TODO: [sumit] Get rid of special case. Add config/param capabilities to service definitions?
+ //special case for hive
+ filter.param().name("basicAuthPreemptive").value("true");
+ }
+ return filter;
+ }
+
++ private FilterDescriptor addDispatchFilterForClass(DeploymentContext context, Service service, ResourceDescriptor resource, String dispatchClass, String httpClientFactory) {
++ return addDispatchFilterForClass(context, service, resource, dispatchClass, httpClientFactory, false);
++ }
++
+ private boolean isHaEnabled(DeploymentContext context) {
+ Provider provider = getProviderByRole(context, "ha");
+ if ( provider != null && provider.isEnabled() ) {
+ Map<String, String> params = provider.getParams();
+ if ( params != null ) {
+ if ( params.containsKey(getRole()) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
index 073adcd,0000000..1299d6f
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/metrics/impl/instr/InstrHttpClientBuilderProvider.java
@@@ -1,71 -1,0 +1,70 @@@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.services.metrics.impl.instr;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.httpclient.HttpClientMetricNameStrategy;
+import com.codahale.metrics.httpclient.InstrumentedHttpRequestExecutor;
+import org.apache.knox.gateway.services.metrics.InstrumentationProvider;
+import org.apache.knox.gateway.services.metrics.MetricsContext;
+import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.apache.http.RequestLine;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+
+import java.net.URISyntaxException;
+
+public class InstrHttpClientBuilderProvider implements
+ InstrumentationProvider<HttpClientBuilder> {
+
+ @Override
+ public HttpClientBuilder getInstrumented(MetricsContext metricsContext) {
+ MetricRegistry registry = (MetricRegistry) metricsContext.getProperty(DefaultMetricsService.METRICS_REGISTRY);
- return HttpClientBuilder.create().setRequestExecutor(new InstrumentedHttpRequestExecutor(registry, TOPOLOGY_URL_AND_METHOD)).
- setConnectionManager(new PoolingHttpClientConnectionManager());
++ return HttpClientBuilder.create().setRequestExecutor(new InstrumentedHttpRequestExecutor(registry, TOPOLOGY_URL_AND_METHOD));
+ }
+
+ @Override
+ public HttpClientBuilder getInstrumented(HttpClientBuilder instanceClass, MetricsContext metricsContext) {
+ throw new UnsupportedOperationException();
+ }
+
+ private static final HttpClientMetricNameStrategy TOPOLOGY_URL_AND_METHOD = new HttpClientMetricNameStrategy() {
+ public String getNameFor(String name, HttpRequest request) {
+ try {
+ String context = "";
+ Header header = request.getFirstHeader("X-Forwarded-Context");
+ if (header != null) {
+ context = header.getValue();
+ }
+ RequestLine requestLine = request.getRequestLine();
+ URIBuilder uriBuilder = new URIBuilder(requestLine.getUri());
+ String resourcePath = InstrUtils.getResourcePath(uriBuilder.removeQuery().build().toString());
+ return MetricRegistry.name("service", new String[]{name, context + resourcePath, methodNameString(request)});
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private String methodNameString(HttpRequest request) {
+ return request.getRequestLine().getMethod().toLowerCase() + "-requests";
+ }
+ };
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/topology/builder/BeanPropertyTopologyBuilder.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/topology/builder/BeanPropertyTopologyBuilder.java
index a1a2609,0000000..afeade0
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/topology/builder/BeanPropertyTopologyBuilder.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/topology/builder/BeanPropertyTopologyBuilder.java
@@@ -1,105 -1,0 +1,116 @@@
+/**
+ * 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.knox.gateway.topology.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.knox.gateway.topology.Application;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+import org.apache.knox.gateway.topology.Topology;
+
+public class BeanPropertyTopologyBuilder implements TopologyBuilder {
+
+ private String name;
+ private String defaultService;
++ private boolean isGenerated;
+ private List<Provider> providers;
+ private List<Service> services;
+ private List<Application> applications;
+
+ public BeanPropertyTopologyBuilder() {
+ providers = new ArrayList<Provider>();
+ services = new ArrayList<Service>();
+ applications = new ArrayList<Application>();
+ }
+
+ public BeanPropertyTopologyBuilder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String name() {
+ return name;
+ }
+
++ public BeanPropertyTopologyBuilder generated(String isGenerated) {
++ this.isGenerated = Boolean.valueOf(isGenerated);
++ return this;
++ }
++
++ public boolean isGenerated() {
++ return isGenerated;
++ }
++
+ public BeanPropertyTopologyBuilder defaultService(String defaultService) {
+ this.defaultService = defaultService;
+ return this;
+ }
+
+ public String defaultService() {
+ return defaultService;
+ }
+
+ public BeanPropertyTopologyBuilder addProvider(Provider provider) {
+ providers.add(provider);
+ return this;
+ }
+
+ public List<Provider> providers() {
+ return providers;
+ }
+
+ public BeanPropertyTopologyBuilder addService(Service service) {
+ services.add(service);
+ return this;
+ }
+
+ public List<Service> services() {
+ return services;
+ }
+
+ public BeanPropertyTopologyBuilder addApplication( Application application ) {
+ applications.add(application);
+ return this;
+ }
+
+ public List<Application> applications() {
+ return applications;
+ }
+
+ public Topology build() {
+ Topology topology = new Topology();
+ topology.setName(name);
+ topology.setDefaultServicePath(defaultService);
++ topology.setGenerated(isGenerated);
+
+ for (Provider provider : providers) {
+ topology.addProvider(provider);
+ }
+
+ for (Service service : services) {
+ topology.addService(service);
+ }
+
+ for (Application application : applications) {
+ topology.addApplication(application);
+ }
+
+ return topology;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptor.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptor.java
index 25997b1,0000000..7d25286
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptor.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptor.java
@@@ -1,48 -1,0 +1,58 @@@
+/**
+ * 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.knox.gateway.topology.simple;
+
+import java.util.List;
+import java.util.Map;
+
+public interface SimpleDescriptor {
+
+ String getName();
+
+ String getDiscoveryType();
+
+ String getDiscoveryAddress();
+
+ String getDiscoveryUser();
+
+ String getDiscoveryPasswordAlias();
+
+ String getClusterName();
+
+ String getProviderConfig();
+
+ List<Service> getServices();
+
++ List<Application> getApplications();
++
+
+ interface Service {
+ String getName();
+
+ Map<String, String> getParams();
+
+ List<String> getURLs();
+ }
++
++ interface Application {
++ String getName();
++
++ Map<String, String> getParams();
++
++ List<String> getURLs();
++ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
index b54432d,0000000..2e3214d
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandler.java
@@@ -1,267 -1,0 +1,316 @@@
+/**
+ * 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.knox.gateway.topology.simple;
+
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.topology.discovery.DefaultServiceDiscoveryConfig;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryFactory;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+
+/**
+ * Processes simple topology descriptors, producing full topology files, which can subsequently be deployed to the
+ * gateway.
+ */
+public class SimpleDescriptorHandler {
+
+ private static final Service[] NO_GATEWAY_SERVICES = new Service[]{};
+
+ private static final SimpleDescriptorMessages log = MessagesFactory.get(SimpleDescriptorMessages.class);
+
+ public static Map<String, File> handle(File desc) throws IOException {
+ return handle(desc, NO_GATEWAY_SERVICES);
+ }
+
+ public static Map<String, File> handle(File desc, Service...gatewayServices) throws IOException {
+ return handle(desc, desc.getParentFile(), gatewayServices);
+ }
+
+ public static Map<String, File> handle(File desc, File destDirectory) throws IOException {
+ return handle(desc, destDirectory, NO_GATEWAY_SERVICES);
+ }
+
+ public static Map<String, File> handle(File desc, File destDirectory, Service...gatewayServices) throws IOException {
+ return handle(SimpleDescriptorFactory.parse(desc.getAbsolutePath()), desc.getParentFile(), destDirectory, gatewayServices);
+ }
+
+ public static Map<String, File> handle(SimpleDescriptor desc, File srcDirectory, File destDirectory) {
+ return handle(desc, srcDirectory, destDirectory, NO_GATEWAY_SERVICES);
+ }
+
+ public static Map<String, File> handle(SimpleDescriptor desc, File srcDirectory, File destDirectory, Service...gatewayServices) {
+ Map<String, File> result = new HashMap<>();
+
+ File topologyDescriptor;
+
+ DefaultServiceDiscoveryConfig sdc = new DefaultServiceDiscoveryConfig(desc.getDiscoveryAddress());
+ sdc.setUser(desc.getDiscoveryUser());
+ sdc.setPasswordAlias(desc.getDiscoveryPasswordAlias());
- ServiceDiscovery sd = ServiceDiscoveryFactory.get(desc.getDiscoveryType(), gatewayServices);
++
++ // Use the discovery type from the descriptor. If it's unspecified, employ the default type.
++ String discoveryType = desc.getDiscoveryType();
++ if (discoveryType == null) {
++ discoveryType = "AMBARI";
++ }
++
++ ServiceDiscovery sd = ServiceDiscoveryFactory.get(discoveryType, gatewayServices);
+ ServiceDiscovery.Cluster cluster = sd.discover(sdc, desc.getClusterName());
+
+ List<String> validServiceNames = new ArrayList<>();
+
+ Map<String, Map<String, String>> serviceParams = new HashMap<>();
+ Map<String, List<String>> serviceURLs = new HashMap<>();
+
+ if (cluster != null) {
+ for (SimpleDescriptor.Service descService : desc.getServices()) {
+ String serviceName = descService.getName();
+
+ List<String> descServiceURLs = descService.getURLs();
+ if (descServiceURLs == null || descServiceURLs.isEmpty()) {
+ descServiceURLs = cluster.getServiceURLs(serviceName);
+ }
+
+ // Validate the discovered service URLs
+ List<String> validURLs = new ArrayList<>();
+ if (descServiceURLs != null && !descServiceURLs.isEmpty()) {
+ // Validate the URL(s)
+ for (String descServiceURL : descServiceURLs) {
+ if (validateURL(serviceName, descServiceURL)) {
+ validURLs.add(descServiceURL);
+ }
+ }
+
+ if (!validURLs.isEmpty()) {
+ validServiceNames.add(serviceName);
+ }
+ }
+
+ // If there is at least one valid URL associated with the service, then add it to the map
+ if (!validURLs.isEmpty()) {
+ serviceURLs.put(serviceName, validURLs);
+ } else {
+ log.failedToDiscoverClusterServiceURLs(serviceName, cluster.getName());
+ }
+
+ // Service params
+ if (descService.getParams() != null) {
+ serviceParams.put(serviceName, descService.getParams());
+ if (!validServiceNames.contains(serviceName)) {
+ validServiceNames.add(serviceName);
+ }
+ }
+ }
+ } else {
+ log.failedToDiscoverClusterServices(desc.getClusterName());
+ }
+
+ BufferedWriter fw = null;
+ topologyDescriptor = null;
+ File providerConfig;
+ try {
+ // Verify that the referenced provider configuration exists before attempting to reading it
+ providerConfig = resolveProviderConfigurationReference(desc.getProviderConfig(), srcDirectory);
+ if (providerConfig == null) {
+ log.failedToResolveProviderConfigRef(desc.getProviderConfig());
+ throw new IllegalArgumentException("Unresolved provider configuration reference: " +
+ desc.getProviderConfig() + " ; Topology update aborted!");
+ }
+ result.put("reference", providerConfig);
+
+ // TODO: Should the contents of the provider config be validated before incorporating it into the topology?
+
+ String topologyFilename = desc.getName();
+ if (topologyFilename == null) {
+ topologyFilename = desc.getClusterName();
+ }
+ topologyDescriptor = new File(destDirectory, topologyFilename + ".xml");
++
+ fw = new BufferedWriter(new FileWriter(topologyDescriptor));
+
++ fw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
++
++ fw.write("<!--==============================================-->\n");
++ fw.write("<!-- DO NOT EDIT. This is an auto-generated file. -->\n");
++ fw.write("<!--==============================================-->\n");
++
+ fw.write("<topology>\n");
+
++ // KNOX-1105 Indicate that this topology was auto-generated
++ fw.write(" <generated>true</generated>\n");
++
+ // Copy the externalized provider configuration content into the topology descriptor in-line
+ InputStreamReader policyReader = new InputStreamReader(new FileInputStream(providerConfig));
+ char[] buffer = new char[1024];
+ int count;
+ while ((count = policyReader.read(buffer)) > 0) {
+ fw.write(buffer, 0, count);
+ }
+ policyReader.close();
+
++ // Services
+ // Sort the service names to write the services alphabetically
+ List<String> serviceNames = new ArrayList<>(validServiceNames);
+ Collections.sort(serviceNames);
+
+ // Write the service declarations
+ for (String serviceName : serviceNames) {
+ fw.write(" <service>\n");
+ fw.write(" <role>" + serviceName + "</role>\n");
+
+ // URLs
+ List<String> urls = serviceURLs.get(serviceName);
+ if (urls != null) {
+ for (String url : urls) {
+ fw.write(" <url>" + url + "</url>\n");
+ }
+ }
+
+ // Params
+ Map<String, String> svcParams = serviceParams.get(serviceName);
+ if (svcParams != null) {
+ for (String paramName : svcParams.keySet()) {
+ fw.write(" <param>\n");
+ fw.write(" <name>" + paramName + "</name>\n");
+ fw.write(" <value>" + svcParams.get(paramName) + "</value>\n");
+ fw.write(" </param>\n");
+ }
+ }
+
+ fw.write(" </service>\n");
+ }
+
++ // Applications
++ List<SimpleDescriptor.Application> apps = desc.getApplications();
++ if (apps != null) {
++ for (SimpleDescriptor.Application app : apps) {
++ fw.write(" <application>\n");
++ fw.write(" <name>" + app.getName() + "</name>\n");
++
++ // URLs
++ List<String> urls = app.getURLs();
++ if (urls != null) {
++ for (String url : urls) {
++ fw.write(" <url>" + url + "</url>\n");
++ }
++ }
++
++ // Params
++ Map<String, String> appParams = app.getParams();
++ if (appParams != null) {
++ for (String paramName : appParams.keySet()) {
++ fw.write(" <param>\n");
++ fw.write(" <name>" + paramName + "</name>\n");
++ fw.write(" <value>" + appParams.get(paramName) + "</value>\n");
++ fw.write(" </param>\n");
++ }
++ }
++
++ fw.write(" </application>\n");
++ }
++ }
++
+ fw.write("</topology>\n");
+
+ fw.flush();
+ } catch (IOException e) {
+ log.failedToGenerateTopologyFromSimpleDescriptor(topologyDescriptor.getName(), e);
+ topologyDescriptor.delete();
+ } finally {
+ if (fw != null) {
+ try {
+ fw.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ result.put("topology", topologyDescriptor);
+ return result;
+ }
+
++
+ private static boolean validateURL(String serviceName, String url) {
+ boolean result = false;
+
+ if (url != null && !url.isEmpty()) {
+ try {
+ new URI(url);
+ result = true;
+ } catch (URISyntaxException e) {
+ log.serviceURLValidationFailed(serviceName, url, e);
+ }
+ }
+
+ return result;
+ }
+
+
+ private static File resolveProviderConfigurationReference(String reference, File srcDirectory) {
+ File providerConfig;
+
+ // If the reference includes a path
+ if (reference.contains(File.separator)) {
+ // Check if it's an absolute path
+ providerConfig = new File(reference);
+ if (!providerConfig.exists()) {
+ // If it's not an absolute path, try treating it as a relative path
+ providerConfig = new File(srcDirectory, reference);
+ if (!providerConfig.exists()) {
+ providerConfig = null;
+ }
+ }
+ } else { // No file path, just a name
+ // Check if it's co-located with the referencing descriptor
+ providerConfig = new File(srcDirectory, reference);
+ if (!providerConfig.exists()) {
+ // Check the shared-providers config location
+ File sharedProvidersDir = new File(srcDirectory, "../shared-providers");
+ if (sharedProvidersDir.exists()) {
+ providerConfig = new File(sharedProvidersDir, reference);
+ if (!providerConfig.exists()) {
+ // Check if it's a valid name without the extension
+ providerConfig = new File(sharedProvidersDir, reference + ".xml");
+ if (!providerConfig.exists()) {
+ providerConfig = null;
+ }
+ }
+ }
+ }
+ }
+
+ return providerConfig;
+ }
+
+}
[16/16] knox git commit: KNOX-998 - Bring branch up to speed with
0.14.0 RC1
Posted by mo...@apache.org.
KNOX-998 - Bring branch up to speed with 0.14.0 RC1
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/e70904b3
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/e70904b3
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/e70904b3
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: e70904b3d32af5df4c55f652187eda6b3719ab37
Parents: 2c69152
Author: Sandeep More <mo...@apache.org>
Authored: Mon Nov 13 10:47:33 2017 -0500
Committer: Sandeep More <mo...@apache.org>
Committed: Mon Nov 13 10:47:33 2017 -0500
----------------------------------------------------------------------
gateway-adapter/pom.xml | 2 +-
.../service/admin/TopologiesResource.java | 2 +-
.../resources/services/nifi/1.4.0/service.xml | 2 +-
.../hadoop/gateway/dispatch/NiFiDispatch.java | 106 ------------------
.../hadoop/gateway/dispatch/NiFiHaDispatch.java | 111 -------------------
.../hadoop/gateway/dispatch/NiFiHeaders.java | 26 -----
.../gateway/dispatch/NiFiRequestUtil.java | 89 ---------------
.../gateway/dispatch/NiFiResponseUtil.java | 89 ---------------
.../knox/gateway/dispatch/NiFiDispatch.java | 106 ++++++++++++++++++
.../knox/gateway/dispatch/NiFiHaDispatch.java | 111 +++++++++++++++++++
.../knox/gateway/dispatch/NiFiHeaders.java | 26 +++++
.../knox/gateway/dispatch/NiFiRequestUtil.java | 89 +++++++++++++++
.../knox/gateway/dispatch/NiFiResponseUtil.java | 88 +++++++++++++++
.../src/test/resources/log4j.properties | 2 +-
14 files changed, 424 insertions(+), 425 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-adapter/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-adapter/pom.xml b/gateway-adapter/pom.xml
index 4bb62e3..d6bd49e 100644
--- a/gateway-adapter/pom.xml
+++ b/gateway-adapter/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-adapter</artifactId>
<name>gateway-adapter</name>
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
----------------------------------------------------------------------
diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
index 9ecd7fc..f960734 100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
@@ -145,7 +145,7 @@ public class TopologiesResource {
// Check for existing topology with the same name, to see if it had been generated
boolean existingGenerated = false;
- for (org.apache.hadoop.gateway.topology.Topology existingTopology : ts.getTopologies()) {
+ for (org.apache.knox.gateway.topology.Topology existingTopology : ts.getTopologies()) {
if(existingTopology.getName().equals(id)) {
existingGenerated = existingTopology.isGenerated();
break;
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
index 2ccc10d..d600e2d 100644
--- a/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
@@ -26,5 +26,5 @@
<rewrite apply="NIFI/nifi/inbound/path/query-other" to="request.url"/>
</route>
</routes>
- <dispatch classname="org.apache.hadoop.gateway.dispatch.NiFiDispatch" ha-classname="org.apache.hadoop.gateway.dispatch.NiFiHaDispatch" />
+ <dispatch classname="org.apache.knox.gateway.dispatch.NiFiDispatch" ha-classname="org.apache.knox.gateway.dispatch.NiFiHaDispatch" />
</service>
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java
deleted file mode 100644
index 013fd9c..0000000
--- a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiDispatch.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.dispatch;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.hadoop.gateway.util.MimeTypes;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.entity.ContentType;
-
-public class NiFiDispatch extends DefaultDispatch {
-
- @Override
- protected void executeRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse) throws IOException {
- outboundRequest = NiFiRequestUtil.modifyOutboundRequest(outboundRequest, inboundRequest);
- HttpResponse inboundResponse = executeOutboundRequest(outboundRequest);
- writeOutboundResponse(outboundRequest, inboundRequest, outboundResponse, inboundResponse);
- }
-
- /**
- * Overridden to provide a spot to modify the outbound response before its stream is closed.
- */
- protected void writeOutboundResponse(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
- // Copy the client respond header to the server respond.
- outboundResponse.setStatus(inboundResponse.getStatusLine().getStatusCode());
- Header[] headers = inboundResponse.getAllHeaders();
- Set<String> excludeHeaders = getOutboundResponseExcludeHeaders();
- boolean hasExcludeHeaders = false;
- if ((excludeHeaders != null) && !(excludeHeaders.isEmpty())) {
- hasExcludeHeaders = true;
- }
- for ( Header header : headers ) {
- String name = header.getName();
- if (hasExcludeHeaders && excludeHeaders.contains(name.toUpperCase())) {
- continue;
- }
- String value = header.getValue();
- outboundResponse.addHeader(name, value);
- }
-
- HttpEntity entity = inboundResponse.getEntity();
- if( entity != null ) {
- outboundResponse.setContentType( getInboundResponseContentType( entity ) );
- InputStream stream = entity.getContent();
- try {
- NiFiResponseUtil.modifyOutboundResponse(inboundRequest, outboundResponse, inboundResponse);
- writeResponse( inboundRequest, outboundResponse, stream );
- } finally {
- closeInboundResponse( inboundResponse, stream );
- }
- }
- }
-
- /**
- * Overriden due to {@link DefaultDispatch#getInboundResponseContentType(HttpEntity) having private access, and the method is used by
- * {@link #writeOutboundResponse(HttpUriRequest, HttpServletRequest, HttpServletResponse, HttpResponse)}}
- */
- private String getInboundResponseContentType( final HttpEntity entity ) {
- String fullContentType = null;
- if( entity != null ) {
- ContentType entityContentType = ContentType.get( entity );
- if( entityContentType != null ) {
- if( entityContentType.getCharset() == null ) {
- final String entityMimeType = entityContentType.getMimeType();
- final String defaultCharset = MimeTypes.getDefaultCharsetForMimeType( entityMimeType );
- if( defaultCharset != null ) {
- LOG.usingDefaultCharsetForEntity( entityMimeType, defaultCharset );
- entityContentType = entityContentType.withCharset( defaultCharset );
- }
- } else {
- LOG.usingExplicitCharsetForEntity( entityContentType.getMimeType(), entityContentType.getCharset() );
- }
- fullContentType = entityContentType.toString();
- }
- }
- if( fullContentType == null ) {
- LOG.unknownResponseEntityContentType();
- } else {
- LOG.inboundResponseEntityContentType( fullContentType );
- }
- return fullContentType;
- }
-}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java
deleted file mode 100644
index 4272086..0000000
--- a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHaDispatch.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.dispatch;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.hadoop.gateway.ha.dispatch.DefaultHaDispatch;
-import org.apache.hadoop.gateway.util.MimeTypes;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.entity.ContentType;
-
-public class NiFiHaDispatch extends DefaultHaDispatch {
-
- public NiFiHaDispatch() {
- setServiceRole("NIFI");
- }
-
- @Override
- protected void executeRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse) throws IOException {
- outboundRequest = NiFiRequestUtil.modifyOutboundRequest(outboundRequest, inboundRequest);
- HttpResponse inboundResponse = executeOutboundRequest(outboundRequest);
- writeOutboundResponse(outboundRequest, inboundRequest, outboundResponse, inboundResponse);
- }
-
- /**
- * Overridden to provide a spot to modify the outbound response before its stream is closed.
- */
- protected void writeOutboundResponse(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
- // Copy the client respond header to the server respond.
- outboundResponse.setStatus(inboundResponse.getStatusLine().getStatusCode());
- Header[] headers = inboundResponse.getAllHeaders();
- Set<String> excludeHeaders = getOutboundResponseExcludeHeaders();
- boolean hasExcludeHeaders = false;
- if ((excludeHeaders != null) && !(excludeHeaders.isEmpty())) {
- hasExcludeHeaders = true;
- }
- for ( Header header : headers ) {
- String name = header.getName();
- if (hasExcludeHeaders && excludeHeaders.contains(name.toUpperCase())) {
- continue;
- }
- String value = header.getValue();
- outboundResponse.addHeader(name, value);
- }
-
- HttpEntity entity = inboundResponse.getEntity();
- if( entity != null ) {
- outboundResponse.setContentType( getInboundResponseContentType( entity ) );
- InputStream stream = entity.getContent();
- try {
- NiFiResponseUtil.modifyOutboundResponse(inboundRequest, outboundResponse, inboundResponse);
- writeResponse( inboundRequest, outboundResponse, stream );
- } finally {
- closeInboundResponse( inboundResponse, stream );
- }
- }
- }
-
- /**
- * Overriden due to {@link DefaultDispatch#getInboundResponseContentType(HttpEntity) having private access, and the method is used by
- * {@link #writeOutboundResponse(HttpUriRequest, HttpServletRequest, HttpServletResponse, HttpResponse)}}
- */
- private String getInboundResponseContentType( final HttpEntity entity ) {
- String fullContentType = null;
- if( entity != null ) {
- ContentType entityContentType = ContentType.get( entity );
- if( entityContentType != null ) {
- if( entityContentType.getCharset() == null ) {
- final String entityMimeType = entityContentType.getMimeType();
- final String defaultCharset = MimeTypes.getDefaultCharsetForMimeType( entityMimeType );
- if( defaultCharset != null ) {
- DefaultDispatch.LOG.usingDefaultCharsetForEntity( entityMimeType, defaultCharset );
- entityContentType = entityContentType.withCharset( defaultCharset );
- }
- } else {
- DefaultDispatch.LOG.usingExplicitCharsetForEntity( entityContentType.getMimeType(), entityContentType.getCharset() );
- }
- fullContentType = entityContentType.toString();
- }
- }
- if( fullContentType == null ) {
- DefaultDispatch.LOG.unknownResponseEntityContentType();
- } else {
- DefaultDispatch.LOG.inboundResponseEntityContentType( fullContentType );
- }
- return fullContentType;
- }
-}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java
deleted file mode 100644
index f3e8e68..0000000
--- a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiHeaders.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.dispatch;
-
-class NiFiHeaders {
- static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";
- static final String X_FORWARDED_HOST = "X-Forwarded-Server";
- static final String X_FORWARDED_PORT = "X-Forwarded-Port";
- static final String X_FORWARDED_CONTEXT = "X-Forwarded-Context";
- static final String X_PROXIED_ENTITIES_CHAIN = "X-ProxiedEntitiesChain";
-}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java
deleted file mode 100644
index 9fdc425..0000000
--- a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiRequestUtil.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.dispatch;
-
-import java.io.IOException;
-
-import javax.security.auth.Subject;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.hadoop.gateway.security.SubjectUtils;
-import org.apache.http.Header;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.log4j.Logger;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Strings;
-
-class NiFiRequestUtil {
-
- static HttpUriRequest modifyOutboundRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest) throws IOException {
- // preserve trailing slash from inbound request in the outbound request
- if (inboundRequest.getPathInfo().endsWith("/")) {
- String[] split = outboundRequest.getURI().toString().split("\\?");
- if (!split[0].endsWith("/")) {
- outboundRequest = RequestBuilder.copy(outboundRequest).setUri(split[0] + "/" + (split.length == 2 ? "?" + split[1] : "")).build();
- }
- }
- // update the X-Forwarded-Context header to include the Knox-specific context path
- final Header originalXForwardedContextHeader = outboundRequest.getFirstHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
- if (originalXForwardedContextHeader != null) {
- String xForwardedContextHeaderValue = originalXForwardedContextHeader.getValue();
- if (!Strings.isNullOrEmpty(xForwardedContextHeaderValue)) {
- // Inspect the inbound request and outbound request to determine the additional context path from the rewrite
- // rules that needs to be added to the X-Forwarded-Context header to allow proper proxying to NiFi.
- //
- // NiFi does its own URL rewriting, and will not work with the context path provided by Knox
- // (ie, "/gateway/sandbox").
- //
- // For example, if Knox has a rewrite rule "*://*:*/**/nifi-app/{**}?{**}", "/nifi-app" needs to be added
- // to the existing value of the X-Forwarded-Context header, which ends up being "/gateway/sandbox/nifi-app".
- String inboundRequestPathInfo = inboundRequest.getPathInfo();
- String outboundRequestUriPath = outboundRequest.getURI().getPath();
- String outboundRequestUriPathNoTrailingSlash = StringUtils.removeEnd(outboundRequestUriPath, "/");
- String knoxRouteContext = null;
- int index = inboundRequestPathInfo.lastIndexOf(outboundRequestUriPathNoTrailingSlash);
- if (index >= 0) {
- knoxRouteContext = inboundRequestPathInfo.substring(0, index);
- } else {
- Logger.getLogger(NiFiHaDispatch.class.getName()).error(String.format("Unable to find index of %s in %s", outboundRequestUriPathNoTrailingSlash, inboundRequestPathInfo));
- }
- outboundRequest.setHeader(NiFiHeaders.X_FORWARDED_CONTEXT, xForwardedContextHeaderValue + knoxRouteContext);
- }
- }
-
- // NiFi requires the header "X-ProxiedEntitiesChain" to be set with the identity or identities of the authenticated requester.
- // The effective principal (identity) in the requester subject must be added to "X-ProxiedEntitiesChain".
- // If the request already has a populated "X-ProxiedEntitiesChain" header, the identities must be appended to it.
- // If the user proxied through Knox is anonymous, the "Anonymous" identity needs to be represented in X-ProxiedEntitiesChain
- // as empty angle brackets "<>".
- final Subject subject = SubjectUtils.getCurrentSubject();
- String effectivePrincipalName = SubjectUtils.getEffectivePrincipalName(subject);
- outboundRequest.setHeader(NiFiHeaders.X_PROXIED_ENTITIES_CHAIN, Objects.firstNonNull(inboundRequest.getHeader(NiFiHeaders.X_PROXIED_ENTITIES_CHAIN), "") +
- String.format("<%s>", effectivePrincipalName.equalsIgnoreCase("anonymous") ? "" : effectivePrincipalName));
-
- // Make sure headers named "Cookie" are removed from the request to NiFi, since NiFi does not use cookies.
- Header[] cookieHeaders = outboundRequest.getHeaders("Cookie");
- for (Header cookieHeader : cookieHeaders) {
- outboundRequest.removeHeader(cookieHeader);
- }
- return outboundRequest;
- }
-}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java b/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java
deleted file mode 100644
index 38c98b3..0000000
--- a/gateway-service-nifi/src/main/java/org/apache/hadoop/gateway/dispatch/NiFiResponseUtil.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.dispatch;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URIBuilder;
-
-class NiFiResponseUtil {
-
- static void modifyOutboundResponse(HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
- // Only want to rewrite the Location header on a HTTP 302
- if (inboundResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_FOUND) {
- Header originalLocationHeader = inboundResponse.getFirstHeader("Location");
- if (originalLocationHeader != null) {
- String originalLocation = originalLocationHeader.getValue();
- URIBuilder originalLocationUriBuilder;
- try {
- originalLocationUriBuilder = new URIBuilder(originalLocation);
- } catch (URISyntaxException e) {
- throw new RuntimeException("Unable to parse URI from Location header", e);
- }
- URIBuilder inboundRequestUriBuilder = null;
- try {
- inboundRequestUriBuilder = new URIBuilder(inboundRequest.getRequestURI());
- } catch (URISyntaxException e) {
- throw new RuntimeException("Unable to parse the inbound request URI", e);
- }
- /*
- * if the path specified in the Location header fron the inbound response contains the inbound request's URI's path,
- * then it's going to the same web context, and the Location header should be updated based on the X_FORWARDED_* headers.
- */
- String inboundRequestUriPath = inboundRequestUriBuilder.getPath();
- String originalLocationUriPath = originalLocationUriBuilder.getPath();
- if (originalLocationUriPath.contains(inboundRequestUriPath)) {
- // check for trailing slash of Location header if it exists and preserve it
- final String trailingSlash = originalLocationUriPath.endsWith("/") ? "/" : "";
- // retain query params
- final List<NameValuePair> queryParams = originalLocationUriBuilder.getQueryParams();
-
- // check for proxy settings
- final String scheme = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PROTO);
- final String host = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_HOST);
- final String port = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PORT);
-
- final String baseContextPath = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
- final String pathInfo = inboundRequest.getPathInfo();
-
- try {
- final URI newLocation = new URIBuilder().setScheme(scheme).setHost(host).setPort((StringUtils.isNumeric(port) ? Integer.parseInt(port) : -1)).setPath(
- baseContextPath + pathInfo + trailingSlash).setParameters(queryParams).build();
- outboundResponse.setHeader("Location", newLocation.toString());
- } catch (URISyntaxException e) {
- throw new RuntimeException("Unable to rewrite Location header in response", e);
- }
- }
- } else {
- throw new RuntimeException("Received HTTP 302, but response is missing Location header");
- }
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiDispatch.java b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiDispatch.java
new file mode 100644
index 0000000..d939180
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiDispatch.java
@@ -0,0 +1,106 @@
+/*
+ * 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.knox.gateway.dispatch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.knox.gateway.util.MimeTypes;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ContentType;
+
+public class NiFiDispatch extends DefaultDispatch {
+
+ @Override
+ protected void executeRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse) throws IOException {
+ outboundRequest = NiFiRequestUtil.modifyOutboundRequest(outboundRequest, inboundRequest);
+ HttpResponse inboundResponse = executeOutboundRequest(outboundRequest);
+ writeOutboundResponse(outboundRequest, inboundRequest, outboundResponse, inboundResponse);
+ }
+
+ /**
+ * Overridden to provide a spot to modify the outbound response before its stream is closed.
+ */
+ protected void writeOutboundResponse(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
+ // Copy the client respond header to the server respond.
+ outboundResponse.setStatus(inboundResponse.getStatusLine().getStatusCode());
+ Header[] headers = inboundResponse.getAllHeaders();
+ Set<String> excludeHeaders = getOutboundResponseExcludeHeaders();
+ boolean hasExcludeHeaders = false;
+ if ((excludeHeaders != null) && !(excludeHeaders.isEmpty())) {
+ hasExcludeHeaders = true;
+ }
+ for ( Header header : headers ) {
+ String name = header.getName();
+ if (hasExcludeHeaders && excludeHeaders.contains(name.toUpperCase())) {
+ continue;
+ }
+ String value = header.getValue();
+ outboundResponse.addHeader(name, value);
+ }
+
+ HttpEntity entity = inboundResponse.getEntity();
+ if( entity != null ) {
+ outboundResponse.setContentType( getInboundResponseContentType( entity ) );
+ InputStream stream = entity.getContent();
+ try {
+ NiFiResponseUtil.modifyOutboundResponse(inboundRequest, outboundResponse, inboundResponse);
+ writeResponse( inboundRequest, outboundResponse, stream );
+ } finally {
+ closeInboundResponse( inboundResponse, stream );
+ }
+ }
+ }
+
+ /**
+ * Overriden due to {@link DefaultDispatch#getInboundResponseContentType(HttpEntity) having private access, and the method is used by
+ * {@link #writeOutboundResponse(HttpUriRequest, HttpServletRequest, HttpServletResponse, HttpResponse)}}
+ */
+ private String getInboundResponseContentType( final HttpEntity entity ) {
+ String fullContentType = null;
+ if( entity != null ) {
+ ContentType entityContentType = ContentType.get( entity );
+ if( entityContentType != null ) {
+ if( entityContentType.getCharset() == null ) {
+ final String entityMimeType = entityContentType.getMimeType();
+ final String defaultCharset = MimeTypes.getDefaultCharsetForMimeType( entityMimeType );
+ if( defaultCharset != null ) {
+ LOG.usingDefaultCharsetForEntity( entityMimeType, defaultCharset );
+ entityContentType = entityContentType.withCharset( defaultCharset );
+ }
+ } else {
+ LOG.usingExplicitCharsetForEntity( entityContentType.getMimeType(), entityContentType.getCharset() );
+ }
+ fullContentType = entityContentType.toString();
+ }
+ }
+ if( fullContentType == null ) {
+ LOG.unknownResponseEntityContentType();
+ } else {
+ LOG.inboundResponseEntityContentType( fullContentType );
+ }
+ return fullContentType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHaDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHaDispatch.java b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHaDispatch.java
new file mode 100644
index 0000000..5e1e3a0
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHaDispatch.java
@@ -0,0 +1,111 @@
+/*
+ * 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.knox.gateway.dispatch;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.knox.gateway.ha.dispatch.DefaultHaDispatch;
+import org.apache.knox.gateway.util.MimeTypes;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.ContentType;
+
+public class NiFiHaDispatch extends DefaultHaDispatch {
+
+ public NiFiHaDispatch() {
+ setServiceRole("NIFI");
+ }
+
+ @Override
+ protected void executeRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse) throws IOException {
+ outboundRequest = NiFiRequestUtil.modifyOutboundRequest(outboundRequest, inboundRequest);
+ HttpResponse inboundResponse = executeOutboundRequest(outboundRequest);
+ writeOutboundResponse(outboundRequest, inboundRequest, outboundResponse, inboundResponse);
+ }
+
+ /**
+ * Overridden to provide a spot to modify the outbound response before its stream is closed.
+ */
+ protected void writeOutboundResponse(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
+ // Copy the client respond header to the server respond.
+ outboundResponse.setStatus(inboundResponse.getStatusLine().getStatusCode());
+ Header[] headers = inboundResponse.getAllHeaders();
+ Set<String> excludeHeaders = getOutboundResponseExcludeHeaders();
+ boolean hasExcludeHeaders = false;
+ if ((excludeHeaders != null) && !(excludeHeaders.isEmpty())) {
+ hasExcludeHeaders = true;
+ }
+ for ( Header header : headers ) {
+ String name = header.getName();
+ if (hasExcludeHeaders && excludeHeaders.contains(name.toUpperCase())) {
+ continue;
+ }
+ String value = header.getValue();
+ outboundResponse.addHeader(name, value);
+ }
+
+ HttpEntity entity = inboundResponse.getEntity();
+ if( entity != null ) {
+ outboundResponse.setContentType( getInboundResponseContentType( entity ) );
+ InputStream stream = entity.getContent();
+ try {
+ NiFiResponseUtil.modifyOutboundResponse(inboundRequest, outboundResponse, inboundResponse);
+ writeResponse( inboundRequest, outboundResponse, stream );
+ } finally {
+ closeInboundResponse( inboundResponse, stream );
+ }
+ }
+ }
+
+ /**
+ * Overriden due to {@link DefaultDispatch#getInboundResponseContentType(HttpEntity) having private access, and the method is used by
+ * {@link #writeOutboundResponse(HttpUriRequest, HttpServletRequest, HttpServletResponse, HttpResponse)}}
+ */
+ private String getInboundResponseContentType( final HttpEntity entity ) {
+ String fullContentType = null;
+ if( entity != null ) {
+ ContentType entityContentType = ContentType.get( entity );
+ if( entityContentType != null ) {
+ if( entityContentType.getCharset() == null ) {
+ final String entityMimeType = entityContentType.getMimeType();
+ final String defaultCharset = MimeTypes.getDefaultCharsetForMimeType( entityMimeType );
+ if( defaultCharset != null ) {
+ DefaultDispatch.LOG.usingDefaultCharsetForEntity( entityMimeType, defaultCharset );
+ entityContentType = entityContentType.withCharset( defaultCharset );
+ }
+ } else {
+ DefaultDispatch.LOG.usingExplicitCharsetForEntity( entityContentType.getMimeType(), entityContentType.getCharset() );
+ }
+ fullContentType = entityContentType.toString();
+ }
+ }
+ if( fullContentType == null ) {
+ DefaultDispatch.LOG.unknownResponseEntityContentType();
+ } else {
+ DefaultDispatch.LOG.inboundResponseEntityContentType( fullContentType );
+ }
+ return fullContentType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHeaders.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHeaders.java b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHeaders.java
new file mode 100644
index 0000000..2de967e
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiHeaders.java
@@ -0,0 +1,26 @@
+/*
+ * 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.knox.gateway.dispatch;
+
+class NiFiHeaders {
+ static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";
+ static final String X_FORWARDED_HOST = "X-Forwarded-Server";
+ static final String X_FORWARDED_PORT = "X-Forwarded-Port";
+ static final String X_FORWARDED_CONTEXT = "X-Forwarded-Context";
+ static final String X_PROXIED_ENTITIES_CHAIN = "X-ProxiedEntitiesChain";
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiRequestUtil.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiRequestUtil.java b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiRequestUtil.java
new file mode 100644
index 0000000..7df3a09
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiRequestUtil.java
@@ -0,0 +1,89 @@
+/*
+ * 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.knox.gateway.dispatch;
+
+import java.io.IOException;
+
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.knox.gateway.security.SubjectUtils;
+import org.apache.http.Header;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.log4j.Logger;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+
+class NiFiRequestUtil {
+
+ static HttpUriRequest modifyOutboundRequest(HttpUriRequest outboundRequest, HttpServletRequest inboundRequest) throws IOException {
+ // preserve trailing slash from inbound request in the outbound request
+ if (inboundRequest.getPathInfo().endsWith("/")) {
+ String[] split = outboundRequest.getURI().toString().split("\\?");
+ if (!split[0].endsWith("/")) {
+ outboundRequest = RequestBuilder.copy(outboundRequest).setUri(split[0] + "/" + (split.length == 2 ? "?" + split[1] : "")).build();
+ }
+ }
+ // update the X-Forwarded-Context header to include the Knox-specific context path
+ final Header originalXForwardedContextHeader = outboundRequest.getFirstHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
+ if (originalXForwardedContextHeader != null) {
+ String xForwardedContextHeaderValue = originalXForwardedContextHeader.getValue();
+ if (!Strings.isNullOrEmpty(xForwardedContextHeaderValue)) {
+ // Inspect the inbound request and outbound request to determine the additional context path from the rewrite
+ // rules that needs to be added to the X-Forwarded-Context header to allow proper proxying to NiFi.
+ //
+ // NiFi does its own URL rewriting, and will not work with the context path provided by Knox
+ // (ie, "/gateway/sandbox").
+ //
+ // For example, if Knox has a rewrite rule "*://*:*/**/nifi-app/{**}?{**}", "/nifi-app" needs to be added
+ // to the existing value of the X-Forwarded-Context header, which ends up being "/gateway/sandbox/nifi-app".
+ String inboundRequestPathInfo = inboundRequest.getPathInfo();
+ String outboundRequestUriPath = outboundRequest.getURI().getPath();
+ String outboundRequestUriPathNoTrailingSlash = StringUtils.removeEnd(outboundRequestUriPath, "/");
+ String knoxRouteContext = null;
+ int index = inboundRequestPathInfo.lastIndexOf(outboundRequestUriPathNoTrailingSlash);
+ if (index >= 0) {
+ knoxRouteContext = inboundRequestPathInfo.substring(0, index);
+ } else {
+ Logger.getLogger(NiFiHaDispatch.class.getName()).error(String.format("Unable to find index of %s in %s", outboundRequestUriPathNoTrailingSlash, inboundRequestPathInfo));
+ }
+ outboundRequest.setHeader(NiFiHeaders.X_FORWARDED_CONTEXT, xForwardedContextHeaderValue + knoxRouteContext);
+ }
+ }
+
+ // NiFi requires the header "X-ProxiedEntitiesChain" to be set with the identity or identities of the authenticated requester.
+ // The effective principal (identity) in the requester subject must be added to "X-ProxiedEntitiesChain".
+ // If the request already has a populated "X-ProxiedEntitiesChain" header, the identities must be appended to it.
+ // If the user proxied through Knox is anonymous, the "Anonymous" identity needs to be represented in X-ProxiedEntitiesChain
+ // as empty angle brackets "<>".
+ final Subject subject = SubjectUtils.getCurrentSubject();
+ String effectivePrincipalName = SubjectUtils.getEffectivePrincipalName(subject);
+ outboundRequest.setHeader(NiFiHeaders.X_PROXIED_ENTITIES_CHAIN, Objects.firstNonNull(inboundRequest.getHeader(NiFiHeaders.X_PROXIED_ENTITIES_CHAIN), "") +
+ String.format("<%s>", effectivePrincipalName.equalsIgnoreCase("anonymous") ? "" : effectivePrincipalName));
+
+ // Make sure headers named "Cookie" are removed from the request to NiFi, since NiFi does not use cookies.
+ Header[] cookieHeaders = outboundRequest.getHeaders("Cookie");
+ for (Header cookieHeader : cookieHeaders) {
+ outboundRequest.removeHeader(cookieHeader);
+ }
+ return outboundRequest;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiResponseUtil.java
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiResponseUtil.java b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiResponseUtil.java
new file mode 100644
index 0000000..b2d9ebb
--- /dev/null
+++ b/gateway-service-nifi/src/main/java/org/apache/knox/gateway/dispatch/NiFiResponseUtil.java
@@ -0,0 +1,88 @@
+/*
+ * 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.knox.gateway.dispatch;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URIBuilder;
+
+class NiFiResponseUtil {
+
+ static void modifyOutboundResponse(HttpServletRequest inboundRequest, HttpServletResponse outboundResponse, HttpResponse inboundResponse) throws IOException {
+ // Only want to rewrite the Location header on a HTTP 302
+ if (inboundResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_FOUND) {
+ Header originalLocationHeader = inboundResponse.getFirstHeader("Location");
+ if (originalLocationHeader != null) {
+ String originalLocation = originalLocationHeader.getValue();
+ URIBuilder originalLocationUriBuilder;
+ try {
+ originalLocationUriBuilder = new URIBuilder(originalLocation);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unable to parse URI from Location header", e);
+ }
+ URIBuilder inboundRequestUriBuilder = null;
+ try {
+ inboundRequestUriBuilder = new URIBuilder(inboundRequest.getRequestURI());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unable to parse the inbound request URI", e);
+ }
+ /*
+ * if the path specified in the Location header fron the inbound response contains the inbound request's URI's path,
+ * then it's going to the same web context, and the Location header should be updated based on the X_FORWARDED_* headers.
+ */
+ String inboundRequestUriPath = inboundRequestUriBuilder.getPath();
+ String originalLocationUriPath = originalLocationUriBuilder.getPath();
+ if (originalLocationUriPath.contains(inboundRequestUriPath)) {
+ // check for trailing slash of Location header if it exists and preserve it
+ final String trailingSlash = originalLocationUriPath.endsWith("/") ? "/" : "";
+ // retain query params
+ final List<NameValuePair> queryParams = originalLocationUriBuilder.getQueryParams();
+
+ // check for proxy settings
+ final String scheme = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PROTO);
+ final String host = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_HOST);
+ final String port = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_PORT);
+
+ final String baseContextPath = inboundRequest.getHeader(NiFiHeaders.X_FORWARDED_CONTEXT);
+ final String pathInfo = inboundRequest.getPathInfo();
+
+ try {
+ final URI newLocation = new URIBuilder().setScheme(scheme).setHost(host).setPort((StringUtils.isNumeric(port) ? Integer.parseInt(port) : -1)).setPath(
+ baseContextPath + pathInfo + trailingSlash).setParameters(queryParams).build();
+ outboundResponse.setHeader("Location", newLocation.toString());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unable to rewrite Location header in response", e);
+ }
+ }
+ } else {
+ throw new RuntimeException("Received HTTP 302, but response is missing Location header");
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/knox/blob/e70904b3/gateway-test/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/resources/log4j.properties b/gateway-test/src/test/resources/log4j.properties
index e500707..f3ee344 100644
--- a/gateway-test/src/test/resources/log4j.properties
+++ b/gateway-test/src/test/resources/log4j.properties
@@ -24,7 +24,7 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n
#log4j.logger.org.apache.knox.gateway=DEBUG
-#log4j.logger.org.apache.hadoop.test=DEBUG
+#log4j.logger.org.apache.knox.test=DEBUG
#log4j.logger.org.apache.knox.gateway.http=TRACE
#log4j.logger.org.apache.knox.gateway.http.request.body=OFF
#log4j.logger.org.apache.knox.gateway.http.response.body=OFF
[12/16] knox git commit: Merge branch 'master' into
KNOX-998-Package_Restructuring
Posted by mo...@apache.org.
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-test/src/test/java/org/apache/knox/gateway/deploy/DeploymentFactoryFuncTest.java
----------------------------------------------------------------------
diff --cc gateway-test/src/test/java/org/apache/knox/gateway/deploy/DeploymentFactoryFuncTest.java
index c9f262b,0000000..8208e4f
mode 100644,000000..100644
--- a/gateway-test/src/test/java/org/apache/knox/gateway/deploy/DeploymentFactoryFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/knox/gateway/deploy/DeploymentFactoryFuncTest.java
@@@ -1,658 -1,0 +1,663 @@@
+/**
+ * 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.knox.gateway.deploy;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.knox.gateway.GatewayTestConfig;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.filter.XForwardedHeaderFilter;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter;
+import org.apache.knox.gateway.services.DefaultGatewayServices;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.topology.Application;
+import org.apache.knox.gateway.topology.Param;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+import org.apache.knox.gateway.topology.Topology;
+import org.apache.knox.gateway.util.XmlUtils;
+import org.apache.knox.test.TestUtils;
+import org.apache.knox.test.log.NoOpAppender;
+import org.apache.log4j.Appender;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ArchivePath;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import static org.apache.knox.test.TestUtils.LOG_ENTER;
+import static org.apache.knox.test.TestUtils.LOG_EXIT;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.xml.HasXPath.hasXPath;
+import static org.junit.Assert.fail;
+
+public class DeploymentFactoryFuncTest {
+
+ private static final long SHORT_TIMEOUT = 1000L;
+ private static final long MEDIUM_TIMEOUT = 5 * SHORT_TIMEOUT;
+ private static final long LONG_TIMEOUT = 10 * MEDIUM_TIMEOUT;
+
+ @Test( timeout = MEDIUM_TIMEOUT )
+ public void testGenericProviderDeploymentContributor() throws ParserConfigurationException, SAXException, IOException, TransformerException {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ File targetDir = new File( System.getProperty( "user.dir" ), "target" );
+ File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() );
+ gatewayDir.mkdirs();
+
+ ((GatewayTestConfig) config).setGatewayHomeDir( gatewayDir.getAbsolutePath() );
+
+ File deployDir = new File( config.getGatewayDeploymentDir() );
+ deployDir.mkdirs();
+
+ // ((GatewayTestConfig) config).setDeploymentDir( "clusters" );
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String,String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Topology topology = new Topology();
+ topology.setName( "test-cluster" );
+ Service service = new Service();
+ service.setRole( "WEBHDFS" );
+ service.addUrl( "http://localhost:50070/test-service-url" );
+ topology.addService( service );
+
+ Provider provider = new Provider();
+ provider.setRole( "federation" );
+ provider.setName( "HeaderPreAuth" );
+ provider.setEnabled( true );
+ Param param = new Param();
+ param.setName( "filter" );
+ param.setValue( "org.opensource.ExistingFilter" );
+ provider.addParam( param );
+ param = new Param();
+ param.setName( "test-param-name" );
+ param.setValue( "test-param-value" );
+ provider.addParam( param );
+ topology.addProvider( provider );
+
+ EnterpriseArchive war = DeploymentFactory.createDeployment( config, topology );
+
+ Document gateway = XmlUtils.readXml( war.get( "%2F/WEB-INF/gateway.xml" ).getAsset().openStream() );
+ //dump( gateway );
+
+ //by default the first filter will be the X-Forwarded header filter
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[1]/role", equalTo( "xforwardedheaders" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[1]/name", equalTo( "XForwardedHeaderFilter" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[1]/class", equalTo( "org.apache.knox.gateway.filter.XForwardedHeaderFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/role", equalTo( "federation" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/name", equalTo( "HeaderPreAuth" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/class", equalTo( "org.apache.knox.gateway.preauth.filter.HeaderPreAuthFederationFilter" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[1]/name", equalTo( "filter" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[1]/value", equalTo( "org.opensource.ExistingFilter" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[2]/name", equalTo( "test-param-name" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[2]/value", equalTo( "test-param-value" ) ) );
++
++ // testing for the adding of missing identity assertion provider - since it isn't explicitly added above
++ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[4]/role", equalTo( "identity-assertion" ) ) );
++ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[4]/name", equalTo( "Default" ) ) );
++
+ LOG_EXIT();
+ }
+
+ @Test( timeout = LONG_TIMEOUT )
+ public void testInvalidGenericProviderDeploymentContributor() throws ParserConfigurationException, SAXException, IOException, TransformerException {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ File targetDir = new File( System.getProperty( "user.dir" ), "target" );
+ File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() );
+ gatewayDir.mkdirs();
+ ((GatewayTestConfig) config).setGatewayHomeDir( gatewayDir.getAbsolutePath() );
+ File deployDir = new File( config.getGatewayDeploymentDir() );
+ deployDir.mkdirs();
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String,String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Topology topology = new Topology();
+ topology.setName( "test-cluster" );
+ Service service = new Service();
+ service.setRole( "WEBHDFS" );
+ service.addUrl( "http://localhost:50070/test-service-url" );
+ topology.addService( service );
+
+ Provider provider = new Provider();
+ provider.setRole( "authentication" );
+ provider.setName( "generic" );
+ provider.setEnabled( true );
+ Param param; // = new ProviderParam();
+ // Missing filter param.
+ //param.setName( "filter" );
+ //param.setValue( "org.opensource.ExistingFilter" );
+ //provider.addParam( param );
+ param = new Param();
+ param.setName( "test-param-name" );
+ param.setValue( "test-param-value" );
+ provider.addParam( param );
+ topology.addProvider( provider );
+
+ Enumeration<Appender> appenders = NoOpAppender.setUp();
+ try {
+ DeploymentFactory.createDeployment( config, topology );
+ fail( "Should have throws IllegalArgumentException" );
+ } catch ( DeploymentException e ) {
+ // Expected.
+ } finally {
+ NoOpAppender.tearDown( appenders );
+ }
+ LOG_EXIT();
+ }
+
+ @Test( timeout = MEDIUM_TIMEOUT )
+ public void testSimpleTopology() throws IOException, SAXException, ParserConfigurationException, URISyntaxException, TransformerException {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ //Testing without x-forwarded headers filter
+ ((GatewayTestConfig)config).setXForwardedEnabled(false);
+ File targetDir = new File( System.getProperty( "user.dir" ), "target" );
+ File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() );
+ gatewayDir.mkdirs();
+ ((GatewayTestConfig) config).setGatewayHomeDir( gatewayDir.getAbsolutePath() );
+ File deployDir = new File( config.getGatewayDeploymentDir() );
+ deployDir.mkdirs();
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String,String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Topology topology = new Topology();
+ topology.setName( "test-cluster" );
+ Service service = new Service();
+ service.setRole( "WEBHDFS" );
+ service.addUrl( "http://localhost:50070/webhdfs" );
+ topology.addService( service );
+ Provider provider = new Provider();
+ provider.setRole( "authentication" );
+ provider.setName( "ShiroProvider" );
+ provider.setEnabled( true );
+ Param param = new Param();
+ param.setName( "contextConfigLocation" );
+ param.setValue( "classpath:app-context-security.xml" );
+ provider.addParam( param );
+ topology.addProvider( provider );
+ Provider asserter = new Provider();
+ asserter.setRole( "identity-assertion" );
+ asserter.setName("Default");
+ asserter.setEnabled( true );
+ topology.addProvider( asserter );
+ Provider authorizer = new Provider();
+ authorizer.setRole( "authorization" );
+ authorizer.setName("AclsAuthz");
+ authorizer.setEnabled( true );
+ topology.addProvider( authorizer );
+
+ EnterpriseArchive 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 web = XmlUtils.readXml( war.get( "%2F/WEB-INF/web.xml" ).getAsset().openStream() );
+ assertThat( web, hasXPath( "/web-app" ) );
+ assertThat( web, hasXPath( "/web-app/servlet" ) );
+ assertThat( web, hasXPath( "/web-app/servlet/servlet-name" ) );
+ assertThat( web, hasXPath( "/web-app/servlet/servlet-name", equalTo( "test-cluster-knox-gateway-servlet" ) ) );
+ assertThat( web, hasXPath( "/web-app/servlet/servlet-class", equalTo( "org.apache.knox.gateway.GatewayServlet" ) ) );
+ assertThat( web, hasXPath( "/web-app/servlet/init-param/param-name", equalTo( "gatewayDescriptorLocation" ) ) );
+ assertThat( web, hasXPath( "/web-app/servlet/init-param/param-value", equalTo( "/WEB-INF/gateway.xml" ) ) );
+ assertThat( web, hasXPath( "/web-app/servlet-mapping/servlet-name", equalTo( "test-cluster-knox-gateway-servlet" ) ) );
+ assertThat( web, hasXPath( "/web-app/servlet-mapping/url-pattern", equalTo( "/*" ) ) );
+
+ Document gateway = XmlUtils.readXml( war.get( "%2F/WEB-INF/gateway.xml" ).getAsset().openStream() );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/pattern", equalTo( "/webhdfs/v1/?**" ) ) );
+ //assertThat( gateway, hasXPath( "/gateway/resource[1]/target", equalTo( "http://localhost:50070/webhdfs/v1/?{**}" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[1]/role", equalTo( "authentication" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[1]/class", equalTo( "org.apache.knox.gateway.filter.ResponseCookieFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/role", equalTo( "authentication" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/class", equalTo( "org.apache.shiro.web.servlet.ShiroFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[3]/role", equalTo( "authentication" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[3]/class", equalTo( "org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[4]/role", equalTo( "rewrite" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[4]/class", equalTo( "org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[5]/role", equalTo( "identity-assertion" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[5]/class", equalTo( "org.apache.knox.gateway.identityasserter.filter.IdentityAsserterFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/role", equalTo( "authorization" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/name", equalTo( "AclsAuthz" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/class", equalTo( "org.apache.knox.gateway.filter.AclsAuthorizationFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/role", equalTo( "dispatch" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/name", equalTo( "webhdfs" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/class", equalTo( "org.apache.knox.gateway.dispatch.GatewayDispatchFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/pattern", equalTo( "/webhdfs/v1/**?**" ) ) );
+ //assertThat( gateway, hasXPath( "/gateway/resource[2]/target", equalTo( "http://localhost:50070/webhdfs/v1/{path=**}?{**}" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[1]/role", equalTo( "authentication" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[1]/class", equalTo( "org.apache.knox.gateway.filter.ResponseCookieFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[2]/role", equalTo( "authentication" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[2]/class", equalTo( "org.apache.shiro.web.servlet.ShiroFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[3]/role", equalTo( "authentication" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[3]/class", equalTo( "org.apache.knox.gateway.filter.ShiroSubjectIdentityAdapter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[4]/role", equalTo( "rewrite" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[4]/class", equalTo( "org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[5]/role", equalTo( "identity-assertion" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[5]/class", equalTo( "org.apache.knox.gateway.identityasserter.filter.IdentityAsserterFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/role", equalTo( "authorization" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/name", equalTo( "AclsAuthz" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/class", equalTo( "org.apache.knox.gateway.filter.AclsAuthorizationFilter" ) ) );
+
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/role", equalTo( "dispatch" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/name", equalTo( "webhdfs" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/class", equalTo( "org.apache.knox.gateway.dispatch.GatewayDispatchFilter" ) ) );
+
+ LOG_EXIT();
+ }
+
+
+ @Test( timeout = LONG_TIMEOUT )
+ public void testWebXmlGeneration() throws IOException, SAXException, ParserConfigurationException, URISyntaxException {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ File targetDir = new File(System.getProperty("user.dir"), "target");
+ File gatewayDir = new File(targetDir, "gateway-home-" + UUID.randomUUID());
+ gatewayDir.mkdirs();
+ ((GatewayTestConfig) config).setGatewayHomeDir(gatewayDir.getAbsolutePath());
+ File deployDir = new File(config.getGatewayDeploymentDir());
+ deployDir.mkdirs();
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String, String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Topology topology = new Topology();
+ topology.setName("test-cluster");
+ Service service = new Service();
+ service.setRole("WEBHDFS");
+ service.addUrl("http://localhost:50070/webhdfs");
+ topology.addService(service);
+ Provider provider = new Provider();
+ provider.setRole("authentication");
+ provider.setName("ShiroProvider");
+ provider.setEnabled(true);
+ Param param = new Param();
+ param.setName("contextConfigLocation");
+ param.setValue("classpath:app-context-security.xml");
+ provider.addParam(param);
+ topology.addProvider(provider);
+ Provider asserter = new Provider();
+ asserter.setRole("identity-assertion");
+ asserter.setName("Default");
+ asserter.setEnabled(true);
+ topology.addProvider(asserter);
+ Provider authorizer = new Provider();
+ authorizer.setRole("authorization");
+ authorizer.setName("AclsAuthz");
+ authorizer.setEnabled(true);
+ topology.addProvider(authorizer);
+ Provider ha = new Provider();
+ ha.setRole("ha");
+ ha.setName("HaProvider");
+ ha.setEnabled(true);
+ topology.addProvider(ha);
+
+ for (int i = 0; i < 10; i++) {
+ createAndTestDeployment(config, topology);
+ }
+ LOG_EXIT();
+ }
+
+ private void createAndTestDeployment(GatewayConfig config, Topology topology) throws IOException, SAXException, ParserConfigurationException {
+
+ EnterpriseArchive 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 web = XmlUtils.readXml(war.get("%2F/WEB-INF/web.xml").getAsset().openStream());
+ assertThat(web, hasXPath("/web-app/servlet/servlet-class", equalTo("org.apache.knox.gateway.GatewayServlet")));
+ assertThat(web, hasXPath("/web-app/servlet/init-param/param-name", equalTo("gatewayDescriptorLocation")));
+ assertThat(web, hasXPath("/web-app/servlet/init-param/param-value", equalTo("/WEB-INF/gateway.xml")));
+ assertThat(web, hasXPath("/web-app/servlet-mapping/servlet-name", equalTo("test-cluster-knox-gateway-servlet")));
+ assertThat(web, hasXPath("/web-app/servlet-mapping/url-pattern", equalTo("/*")));
+ //testing the order of listener classes generated
+ assertThat(web, hasXPath("/web-app/listener[2]/listener-class", equalTo("org.apache.knox.gateway.services.GatewayServicesContextListener")));
+ assertThat(web, hasXPath("/web-app/listener[3]/listener-class", equalTo("org.apache.knox.gateway.services.GatewayMetricsServletContextListener")));
+ assertThat(web, hasXPath("/web-app/listener[4]/listener-class", equalTo("org.apache.knox.gateway.ha.provider" +
+ ".HaServletContextListener")));
+ assertThat(web, hasXPath("/web-app/listener[5]/listener-class", equalTo("org.apache.knox.gateway.filter" +
+ ".rewrite.api.UrlRewriteServletContextListener")));
+ }
+
+ @Test( timeout = LONG_TIMEOUT )
+ public void testDeploymentWithServiceParams() throws Exception {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ File targetDir = new File(System.getProperty("user.dir"), "target");
+ File gatewayDir = new File(targetDir, "gateway-home-" + UUID.randomUUID());
+ gatewayDir.mkdirs();
+ ((GatewayTestConfig) config).setGatewayHomeDir(gatewayDir.getAbsolutePath());
+ File deployDir = new File(config.getGatewayDeploymentDir());
+ deployDir.mkdirs();
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String, String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Service service;
+ Param param;
+ Topology topology = new Topology();
+ topology.setName( "test-cluster" );
+
+ service = new Service();
+ service.setRole( "HIVE" );
+ service.setUrls( Arrays.asList( new String[]{ "http://hive-host:50001/" } ) );
+ param = new Param();
+ param.setName( "someparam" );
+ param.setValue( "somevalue" );
+ service.addParam( param );
+ topology.addService( service );
+
+ service = new Service();
+ service.setRole( "WEBHBASE" );
+ service.setUrls( Arrays.asList( new String[]{ "http://hbase-host:50002/" } ) );
+ param = new Param();
+ param.setName( "replayBufferSize" );
+ param.setValue( "33" );
+ service.addParam( param );
+ topology.addService( service );
+
+ service = new Service();
+ service.setRole( "OOZIE" );
+ service.setUrls( Arrays.asList( new String[]{ "http://hbase-host:50003/" } ) );
+ param = new Param();
+ param.setName( "otherparam" );
+ param.setValue( "65" );
+ service.addParam( param );
+ topology.addService( service );
+
+ EnterpriseArchive war = DeploymentFactory.createDeployment( config, topology );
+ Document doc = XmlUtils.readXml( war.get( "%2F/WEB-INF/gateway.xml" ).getAsset().openStream() );
+ // dump( doc );
+
+ Node resourceNode, filterNode, paramNode;
+ String value;
+
+ resourceNode = node( doc, "gateway/resource[role/text()='HIVE']" );
+ assertThat( resourceNode, is(not(nullValue())));
+ filterNode = node( resourceNode, "filter[role/text()='dispatch']" );
+ assertThat( filterNode, is(not(nullValue())));
+ paramNode = node( filterNode, "param[name/text()='someparam']" );
+ value = value( paramNode, "value/text()" );
+ assertThat( value, is( "somevalue" ) ) ;
+
+ resourceNode = node( doc, "gateway/resource[role/text()='WEBHBASE']" );
+ assertThat( resourceNode, is(not(nullValue())));
+ filterNode = node( resourceNode, "filter[role/text()='dispatch']" );
+ assertThat( filterNode, is(not(nullValue())));
+ paramNode = node( filterNode, "param[name/text()='replayBufferSize']" );
+ value = value( paramNode, "value/text()" );
+ assertThat( value, is( "33" ) ) ;
+
+ resourceNode = node( doc, "gateway/resource[role/text()='OOZIE']" );
+ assertThat( resourceNode, is(not(nullValue())));
+ filterNode = node( resourceNode, "filter[role/text()='dispatch']" );
+ assertThat( filterNode, is(not(nullValue())));
+ paramNode = node( filterNode, "param[name/text()='otherparam']" );
+ value = value( paramNode, "value/text()" );
+ assertThat( value, is( "65" ) ) ;
+
+ FileUtils.deleteQuietly( deployDir );
+
+ LOG_EXIT();
+ }
+
+ @Test( timeout = MEDIUM_TIMEOUT )
+ public void testDeploymentWithApplication() throws Exception {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ File targetDir = new File(System.getProperty("user.dir"), "target");
+ File gatewayDir = new File(targetDir, "gateway-home-" + UUID.randomUUID());
+ gatewayDir.mkdirs();
+ ((GatewayTestConfig) config).setGatewayHomeDir(gatewayDir.getAbsolutePath());
+ File deployDir = new File(config.getGatewayDeploymentDir());
+ deployDir.mkdirs();
+ URL serviceUrl = TestUtils.getResourceUrl( DeploymentFactoryFuncTest.class, "test-apps/minimal-test-app/service.xml" );
+ File serviceFile = new File( serviceUrl.toURI() );
+ File appsDir = serviceFile.getParentFile().getParentFile();
+ ((GatewayTestConfig)config).setGatewayApplicationsDir(appsDir.getAbsolutePath());
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String, String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Topology topology = new Topology();
+ topology.setName( "test-topology" );
+
+ Application app;
+
+ app = new Application();
+ app.setName( "minimal-test-app" );
+ app.addUrl( "/minimal-test-app-path" );
+ topology.addApplication( app );
+
+ EnterpriseArchive archive = DeploymentFactory.createDeployment( config, topology );
+ assertThat( archive, notNullValue() );
+
+ Document doc;
+
+ doc = XmlUtils.readXml( archive.get( "META-INF/topology.xml" ).getAsset().openStream() );
+ assertThat( doc, notNullValue() );
+
+ doc = XmlUtils.readXml( archive.get( "%2Fminimal-test-app-path/WEB-INF/gateway.xml" ).getAsset().openStream() );
+ assertThat( doc, notNullValue() );
+ //dump( doc );
+ assertThat( doc, hasXPath("/gateway/resource/pattern", equalTo("/**?**")));
+ assertThat( doc, hasXPath("/gateway/resource/filter[1]/role", equalTo("xforwardedheaders")));
+ assertThat( doc, hasXPath("/gateway/resource/filter[1]/name", equalTo("XForwardedHeaderFilter")));
+ assertThat( doc, hasXPath("/gateway/resource/filter[1]/class", equalTo(XForwardedHeaderFilter.class.getName())));
+ assertThat( doc, hasXPath("/gateway/resource/filter[2]/role", equalTo("rewrite")));
+ assertThat( doc, hasXPath("/gateway/resource/filter[2]/name", equalTo("url-rewrite")));
+ assertThat( doc, hasXPath("/gateway/resource/filter[2]/class", equalTo(UrlRewriteServletFilter.class.getName())));
+
+ LOG_EXIT();
+ }
+
+ @Test( timeout = MEDIUM_TIMEOUT )
+ public void testDeploymentWithServicesAndApplications() throws Exception {
+ LOG_ENTER();
+ GatewayConfig config = new GatewayTestConfig();
+ File targetDir = new File(System.getProperty("user.dir"), "target");
+ File gatewayDir = new File(targetDir, "gateway-home-" + UUID.randomUUID());
+ gatewayDir.mkdirs();
+ ((GatewayTestConfig) config).setGatewayHomeDir(gatewayDir.getAbsolutePath());
+ File deployDir = new File(config.getGatewayDeploymentDir());
+ deployDir.mkdirs();
+ URL serviceUrl = TestUtils.getResourceUrl( DeploymentFactoryFuncTest.class, "test-apps/minimal-test-app/service.xml" );
+ File serviceFile = new File( serviceUrl.toURI() );
+ File appsDir = serviceFile.getParentFile().getParentFile();
+ ((GatewayTestConfig)config).setGatewayApplicationsDir(appsDir.getAbsolutePath());
+
+ DefaultGatewayServices srvcs = new DefaultGatewayServices();
+ Map<String, String> options = new HashMap<>();
+ options.put("persist-master", "false");
+ options.put("master", "password");
+ try {
+ DeploymentFactory.setGatewayServices(srvcs);
+ srvcs.init(config, options);
+ } catch (ServiceLifecycleException e) {
+ e.printStackTrace(); // I18N not required.
+ }
+
+ Topology topology = new Topology();
+ topology.setName( "test-topology" );
+
+ Application app;
+
+ topology.setName( "test-cluster" );
+ Service service = new Service();
+ service.setRole( "WEBHDFS" );
+ service.addUrl( "http://localhost:50070/test-service-url" );
+ topology.addService( service );
+
+ app = new Application();
+ app.setName( "minimal-test-app" );
+ app.addUrl( "/minimal-test-app-path-one" );
+ topology.addApplication( app );
+
+ app.setName( "minimal-test-app" );
+ app.addUrl( "/minimal-test-app-path-two" );
+ topology.addApplication( app );
+
+ EnterpriseArchive archive = DeploymentFactory.createDeployment( config, topology );
+ assertThat( archive, notNullValue() );
+
+ Document doc;
+ org.jboss.shrinkwrap.api.Node node;
+
+ node = archive.get( "META-INF/topology.xml" );
+ assertThat( "Find META-INF/topology.xml", node, notNullValue() );
+ doc = XmlUtils.readXml( node.getAsset().openStream() );
+ assertThat( "Parse META-INF/topology.xml", doc, notNullValue() );
+
+ node = archive.get( "%2F" );
+ assertThat( "Find %2F", node, notNullValue() );
+ node = archive.get( "%2F/WEB-INF/gateway.xml" );
+ assertThat( "Find %2F/WEB-INF/gateway.xml", node, notNullValue() );
+ doc = XmlUtils.readXml( node.getAsset().openStream() );
+ assertThat( "Parse %2F/WEB-INF/gateway.xml", doc, notNullValue() );
+
+ WebArchive war = archive.getAsType( WebArchive.class, "%2Fminimal-test-app-path-one" );
+ assertThat( "Find %2Fminimal-test-app-path-one", war, notNullValue() );
+ node = war.get( "/WEB-INF/gateway.xml" );
+ assertThat( "Find %2Fminimal-test-app-path-one/WEB-INF/gateway.xml", node, notNullValue() );
+ doc = XmlUtils.readXml( node.getAsset().openStream() );
+ assertThat( "Parse %2Fminimal-test-app-path-one/WEB-INF/gateway.xml", doc, notNullValue() );
+
+ war = archive.getAsType( WebArchive.class, "%2Fminimal-test-app-path-two" );
+ assertThat( "Find %2Fminimal-test-app-path-two", war, notNullValue() );
+ node = war.get( "/WEB-INF/gateway.xml" );
+ assertThat( "Find %2Fminimal-test-app-path-two/WEB-INF/gateway.xml", node, notNullValue() );
+ doc = XmlUtils.readXml( node.getAsset().openStream() );
+ assertThat( "Parse %2Fminimal-test-app-path-two/WEB-INF/gateway.xml", doc, notNullValue() );
+
+ LOG_EXIT();
+ }
+
+ private Node node( Node scope, String expression ) throws XPathExpressionException {
+ return (Node)XPathFactory.newInstance().newXPath().compile( expression ).evaluate( scope, XPathConstants.NODE );
+ }
+
+ private String value( Node scope, String expression ) throws XPathExpressionException {
+ return XPathFactory.newInstance().newXPath().compile( expression ).evaluate( scope );
+ }
+
+ private static void dump( org.jboss.shrinkwrap.api.Node node, String prefix ) {
+ System.out.println( prefix + ": " + node.getPath() );
+ Set<org.jboss.shrinkwrap.api.Node> children = node.getChildren();
+ if( children != null && !children.isEmpty() ) {
+ for( org.jboss.shrinkwrap.api.Node child : children ) {
+ dump( child, prefix + " " );
+ }
+ }
+ }
+
+ private static void dump( Archive archive ) {
+ Map<ArchivePath,org.jboss.shrinkwrap.api.Node> content = archive.getContent();
+ for( Map.Entry<ArchivePath,org.jboss.shrinkwrap.api.Node> entry : content.entrySet() ) {
+ dump( entry.getValue(), " " );
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/knox-cli-launcher/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/pom.xml
----------------------------------------------------------------------
[02/16] knox git commit: KNOX-1034 - Make Default identity-assertion
provider actually be the default
Posted by mo...@apache.org.
KNOX-1034 - Make Default identity-assertion provider actually be the default
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/67ad3e38
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/67ad3e38
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/67ad3e38
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 67ad3e38f3d415d4ed7f7ae76ed5e27d9cb33a3f
Parents: 4d60e41
Author: Larry McCay <lm...@hortonworks.com>
Authored: Sat Nov 4 12:08:43 2017 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Sat Nov 4 12:09:10 2017 -0400
----------------------------------------------------------------------
.../gateway/deploy/DeploymentFactory.java | 23 ++++++++++++++++++++
.../deploy/DeploymentFactoryFuncTest.java | 5 +++++
2 files changed, 28 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/67ad3e38/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
index 5c9922c..36cbb2a 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/deploy/DeploymentFactory.java
@@ -239,11 +239,34 @@ public abstract class DeploymentFactory {
// list add it.
private static Map<String,List<ProviderDeploymentContributor>> selectContextProviders( Topology topology ) {
Map<String,List<ProviderDeploymentContributor>> providers = new LinkedHashMap<String, List<ProviderDeploymentContributor>>();
+ addMissingDefaultProviders(topology);
collectTopologyProviders( topology, providers );
collectDefaultProviders( providers );
return providers;
}
+ private static void addMissingDefaultProviders(Topology topology) {
+ Collection<Provider> providers = topology.getProviders();
+ HashMap<String, String> providerMap = new HashMap<>();
+ for (Provider provider : providers) {
+ providerMap.put(provider.getRole(), provider.getName());
+ }
+ // first make sure that the required provider is available from the serviceloaders
+ // for some tests the number of providers are limited to the classpath of the module
+ // and exceptions will be thrown as topologies are deployed even though they will
+ // work fine at actual server runtime.
+ if (PROVIDER_CONTRIBUTOR_MAP.get("identity-assertion") != null) {
+ // check for required providers and add the defaults if missing
+ if (!providerMap.containsKey("identity-assertion")) {
+ Provider idassertion = new Provider();
+ idassertion.setRole("identity-assertion");
+ idassertion.setName("Default");
+ idassertion.setEnabled(true);
+ providers.add(idassertion);
+ }
+ }
+ }
+
private static void collectTopologyProviders(
Topology topology, Map<String, List<ProviderDeploymentContributor>> defaults ) {
for( Provider provider : topology.getProviders() ) {
http://git-wip-us.apache.org/repos/asf/knox/blob/67ad3e38/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
index 6f0924c..8d0d74f 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
@@ -139,6 +139,11 @@ public class DeploymentFactoryFuncTest {
assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[1]/value", equalTo( "org.opensource.ExistingFilter" ) ) );
assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[2]/name", equalTo( "test-param-name" ) ) );
assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[2]/param[2]/value", equalTo( "test-param-value" ) ) );
+
+ // testing for the adding of missing identity assertion provider - since it isn't explicitly added above
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[4]/role", equalTo( "identity-assertion" ) ) );
+ assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[4]/name", equalTo( "Default" ) ) );
+
LOG_EXIT();
}
[09/16] knox git commit: KNOX-1105 - Provide indication that
topologies were generated from simple descriptors (Phil Zampino via lmccay)
Posted by mo...@apache.org.
KNOX-1105 - Provide indication that topologies were generated from simple descriptors (Phil Zampino via lmccay)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/f52dc201
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/f52dc201
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/f52dc201
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: f52dc20159ae1d8adcd6e9f9966b7bb6b42d14cf
Parents: a068eb8
Author: Larry McCay <lm...@hortonworks.com>
Authored: Wed Nov 8 19:04:40 2017 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Wed Nov 8 19:04:40 2017 -0500
----------------------------------------------------------------------
.../builder/BeanPropertyTopologyBuilder.java | 11 +++++++++
.../simple/SimpleDescriptorHandler.java | 20 +++++++++++++++-
.../xml/KnoxFormatXmlTopologyRules.java | 2 ++
.../src/main/resources/conf/topology-v1.xsd | 1 +
.../simple/SimpleDescriptorHandlerTest.java | 8 +++++++
.../service/admin/TopologiesResource.java | 25 ++++++++++++++++----
.../service/admin/beans/BeanConverter.java | 2 ++
.../gateway/service/admin/beans/Topology.java | 11 +++++++++
.../hadoop/gateway/i18n/GatewaySpiMessages.java | 3 +++
.../hadoop/gateway/topology/Topology.java | 9 +++++++
10 files changed, 87 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/builder/BeanPropertyTopologyBuilder.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/builder/BeanPropertyTopologyBuilder.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/builder/BeanPropertyTopologyBuilder.java
index 65278a1..5058508 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/builder/BeanPropertyTopologyBuilder.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/builder/BeanPropertyTopologyBuilder.java
@@ -28,6 +28,7 @@ public class BeanPropertyTopologyBuilder implements TopologyBuilder {
private String name;
private String defaultService;
+ private boolean isGenerated;
private List<Provider> providers;
private List<Service> services;
private List<Application> applications;
@@ -47,6 +48,15 @@ public class BeanPropertyTopologyBuilder implements TopologyBuilder {
return name;
}
+ public BeanPropertyTopologyBuilder generated(String isGenerated) {
+ this.isGenerated = Boolean.valueOf(isGenerated);
+ return this;
+ }
+
+ public boolean isGenerated() {
+ return isGenerated;
+ }
+
public BeanPropertyTopologyBuilder defaultService(String defaultService) {
this.defaultService = defaultService;
return this;
@@ -87,6 +97,7 @@ public class BeanPropertyTopologyBuilder implements TopologyBuilder {
Topology topology = new Topology();
topology.setName(name);
topology.setDefaultServicePath(defaultService);
+ topology.setGenerated(isGenerated);
for (Provider provider : providers) {
topology.addProvider(provider);
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
index 040eb86..089925d 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
@@ -77,7 +77,14 @@ public class SimpleDescriptorHandler {
DefaultServiceDiscoveryConfig sdc = new DefaultServiceDiscoveryConfig(desc.getDiscoveryAddress());
sdc.setUser(desc.getDiscoveryUser());
sdc.setPasswordAlias(desc.getDiscoveryPasswordAlias());
- ServiceDiscovery sd = ServiceDiscoveryFactory.get(desc.getDiscoveryType(), gatewayServices);
+
+ // Use the discovery type from the descriptor. If it's unspecified, employ the default type.
+ String discoveryType = desc.getDiscoveryType();
+ if (discoveryType == null) {
+ discoveryType = "AMBARI";
+ }
+
+ ServiceDiscovery sd = ServiceDiscoveryFactory.get(discoveryType, gatewayServices);
ServiceDiscovery.Cluster cluster = sd.discover(sdc, desc.getClusterName());
List<String> validServiceNames = new ArrayList<>();
@@ -148,10 +155,20 @@ public class SimpleDescriptorHandler {
topologyFilename = desc.getClusterName();
}
topologyDescriptor = new File(destDirectory, topologyFilename + ".xml");
+
fw = new BufferedWriter(new FileWriter(topologyDescriptor));
+ fw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+
+ fw.write("<!--==============================================-->\n");
+ fw.write("<!-- DO NOT EDIT. This is an auto-generated file. -->\n");
+ fw.write("<!--==============================================-->\n");
+
fw.write("<topology>\n");
+ // KNOX-1105 Indicate that this topology was auto-generated
+ fw.write(" <generated>true</generated>\n");
+
// Copy the externalized provider configuration content into the topology descriptor in-line
InputStreamReader policyReader = new InputStreamReader(new FileInputStream(providerConfig));
char[] buffer = new char[1024];
@@ -243,6 +260,7 @@ public class SimpleDescriptorHandler {
return result;
}
+
private static boolean validateURL(String serviceName, String url) {
boolean result = false;
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/xml/KnoxFormatXmlTopologyRules.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
index cb30769..7f9ec3e 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
@@ -33,6 +33,7 @@ public class KnoxFormatXmlTopologyRules extends AbstractRulesModule {
private static final String NAME_TAG = "name";
private static final String VERSION_TAG = "version";
private static final String DEFAULT_SERVICE_TAG = "path";
+ private static final String GENERATED_TAG = "generated";
private static final String APPLICATION_TAG = "application";
private static final String SERVICE_TAG = "service";
private static final String ROLE_TAG = "role";
@@ -50,6 +51,7 @@ public class KnoxFormatXmlTopologyRules extends AbstractRulesModule {
forPattern( ROOT_TAG + "/" + NAME_TAG ).callMethod("name").usingElementBodyAsArgument();
forPattern( ROOT_TAG + "/" + VERSION_TAG ).callMethod("version").usingElementBodyAsArgument();
forPattern( ROOT_TAG + "/" + DEFAULT_SERVICE_TAG ).callMethod("defaultService").usingElementBodyAsArgument();
+ forPattern( ROOT_TAG + "/" + GENERATED_TAG ).callMethod("generated").usingElementBodyAsArgument();
forPattern( ROOT_TAG + "/" + APPLICATION_TAG ).createObject().ofType( Application.class ).then().setNext( "addApplication" );
forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + ROLE_TAG ).setBeanProperty();
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-server/src/main/resources/conf/topology-v1.xsd
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/resources/conf/topology-v1.xsd b/gateway-server/src/main/resources/conf/topology-v1.xsd
index 96c9ba2..936c701 100644
--- a/gateway-server/src/main/resources/conf/topology-v1.xsd
+++ b/gateway-server/src/main/resources/conf/topology-v1.xsd
@@ -22,6 +22,7 @@ limitations under the License.
<h:element name="name" minOccurs="0" maxOccurs="1"/>
<h:element name="path" minOccurs="0" maxOccurs="1"/>
+ <h:element name="generated" type="h:boolean" minOccurs="0"/>
<h:element name="gateway" minOccurs="0" maxOccurs="1">
<h:complexType>
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandlerTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandlerTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandlerTest.java
index a1fda1c..3a62980 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandlerTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandlerTest.java
@@ -44,9 +44,12 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
+import static org.hamcrest.Matchers.hasXPath;
+import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -231,6 +234,11 @@ public class SimpleDescriptorHandlerTest {
// Parse the topology descriptor
Document topologyXml = XmlUtils.readXml(topologyFile);
+ // KNOX-1105 Mark generated topology files
+ assertThat("Expected the \"generated\" marker element in the topology XML, with value of \"true\".",
+ topologyXml,
+ hasXPath("/topology/generated", is("true")));
+
// Validate the provider configuration
Document extProviderConf = XmlUtils.readXml(new ByteArrayInputStream(TEST_PROVIDER_CONFIG.getBytes()));
Node gatewayNode = (Node) xpath.compile("/topology/gateway").evaluate(topologyXml, XPathConstants.NODE);
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/TopologiesResource.java
----------------------------------------------------------------------
diff --git a/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/TopologiesResource.java b/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/TopologiesResource.java
index 445e85d..67a053b 100644
--- a/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/TopologiesResource.java
+++ b/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/TopologiesResource.java
@@ -135,16 +135,33 @@ public class TopologiesResource {
@Consumes({APPLICATION_JSON, APPLICATION_XML})
@Path(SINGLE_TOPOLOGY_API_PATH)
public Topology uploadTopology(@PathParam("id") String id, Topology t) {
+ Topology result = null;
- GatewayServices gs = (GatewayServices) request.getServletContext()
- .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ GatewayServices gs =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
t.setName(id);
TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
- ts.deployTopology(BeanConverter.getTopology(t));
+ // Check for existing topology with the same name, to see if it had been generated
+ boolean existingGenerated = false;
+ for (org.apache.hadoop.gateway.topology.Topology existingTopology : ts.getTopologies()) {
+ if(existingTopology.getName().equals(id)) {
+ existingGenerated = existingTopology.isGenerated();
+ break;
+ }
+ }
- return getTopology(id);
+ // If a topology with the same ID exists, which had been generated, then DO NOT overwrite it because it will be
+ // out of sync with the source descriptor. Otherwise, deploy the updated version.
+ if (!existingGenerated) {
+ ts.deployTopology(BeanConverter.getTopology(t));
+ result = getTopology(id);
+ } else {
+ log.disallowedOverwritingGeneratedTopology(id);
+ }
+
+ return result;
}
@DELETE
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/BeanConverter.java
----------------------------------------------------------------------
diff --git a/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/BeanConverter.java b/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/BeanConverter.java
index f94dcad..b25f0de 100644
--- a/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/BeanConverter.java
+++ b/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/BeanConverter.java
@@ -29,6 +29,7 @@ public class BeanConverter {
topologyResource.setTimestamp(topology.getTimestamp());
topologyResource.setPath(topology.getDefaultServicePath());
topologyResource.setUri(topology.getUri());
+ topologyResource.setGenerated(topology.isGenerated());
for ( org.apache.hadoop.gateway.topology.Provider provider : topology.getProviders() ) {
topologyResource.getProviders().add( getProvider(provider) );
}
@@ -47,6 +48,7 @@ public class BeanConverter {
deploymentTopology.setTimestamp(topology.getTimestamp());
deploymentTopology.setDefaultServicePath(topology.getPath());
deploymentTopology.setUri(topology.getUri());
+ deploymentTopology.setGenerated(topology.isGenerated());
for ( Provider provider : topology.getProviders() ) {
deploymentTopology.addProvider( getProvider(provider) );
}
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/Topology.java
----------------------------------------------------------------------
diff --git a/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/Topology.java b/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/Topology.java
index a197c27..67ecc27 100644
--- a/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/Topology.java
+++ b/gateway-service-admin/src/main/java/org/apache/hadoop/gateway/service/admin/beans/Topology.java
@@ -39,6 +39,9 @@ public class Topology {
@XmlElement
private long timestamp;
+ @XmlElement(name="generated")
+ private boolean isGenerated;
+
@XmlElement(name="provider")
@XmlElementWrapper(name="gateway")
public List<Provider> providers;
@@ -84,6 +87,14 @@ public class Topology {
this.timestamp = timestamp;
}
+ public boolean isGenerated() {
+ return isGenerated;
+ }
+
+ public void setGenerated(boolean isGenerated) {
+ this.isGenerated = isGenerated;
+ }
+
public List<Service> getServices() {
if (services == null) {
services = new ArrayList<>();
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/gateway-spi/src/main/java/org/apache/hadoop/gateway/i18n/GatewaySpiMessages.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/i18n/GatewaySpiMessages.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/i18n/GatewaySpiMessages.java
index aad4d8a..4a5b926 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/i18n/GatewaySpiMessages.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/i18n/GatewaySpiMessages.java
@@ -88,4 +88,7 @@ public interface GatewaySpiMessages {
@Message(level = MessageLevel.ERROR, text = "Invalid resource URI {0} : {1}")
void invalidResourceURI(final String uri, final String reason, @StackTrace(level = MessageLevel.DEBUG) Exception e );
+ @Message( level = MessageLevel.ERROR, text = "Topology {0} cannot be manually overwritten because it was generated from a simple descriptor." )
+ void disallowedOverwritingGeneratedTopology(final String topologyName);
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/f52dc201/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 c366421..6415afe 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
@@ -33,6 +33,7 @@ public class Topology {
private String name;
private String defaultServicePath = null;
private long timestamp;
+ private boolean isGenerated;
public List<Provider> providerList = new ArrayList<Provider>();
private Map<String,Map<String,Provider>> providerMap = new HashMap<>();
public List<Service> services = new ArrayList<Service>();
@@ -76,6 +77,14 @@ public class Topology {
defaultServicePath = servicePath;
}
+ public void setGenerated(boolean isGenerated) {
+ this.isGenerated = isGenerated;
+ }
+
+ public boolean isGenerated() {
+ return isGenerated;
+ }
+
public Collection<Service> getServices() {
return services;
}
[04/16] knox git commit: KNOX-1106 - Tighten the rewrite rule on
oozieui to reduce false positives (Wei Han via Sandeep More)
Posted by mo...@apache.org.
KNOX-1106 - Tighten the rewrite rule on oozieui to reduce false positives (Wei Han via Sandeep More)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/12217b17
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/12217b17
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/12217b17
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 12217b17d181d995d53e49d48a19baa48f130577
Parents: 7f58a16
Author: Sandeep More <mo...@apache.org>
Authored: Mon Nov 6 11:29:27 2017 -0500
Committer: Sandeep More <mo...@apache.org>
Committed: Mon Nov 6 11:29:27 2017 -0500
----------------------------------------------------------------------
.../services/oozieui/4.2.0/rewrite.xml | 27 +++++++++++++++-----
1 file changed, 21 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/12217b17/gateway-service-definitions/src/main/resources/services/oozieui/4.2.0/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/oozieui/4.2.0/rewrite.xml b/gateway-service-definitions/src/main/resources/services/oozieui/4.2.0/rewrite.xml
index 2198b4b..2e04eec 100644
--- a/gateway-service-definitions/src/main/resources/services/oozieui/4.2.0/rewrite.xml
+++ b/gateway-service-definitions/src/main/resources/services/oozieui/4.2.0/rewrite.xml
@@ -16,13 +16,28 @@
limitations under the License.
-->
<rules>
- <rule dir="IN" name="OOZIEUI/oozie/inbound/root" pattern="*://*:*/**/oozie/">
- <rewrite template="{$serviceUrl[OOZIEUI]}/"/>
+ <rule dir="IN" name="OOZIEUI/oozie/inbound/root" flow="OR">
+ <match pattern="http://*:*/**/oozie/">
+ <rewrite template="{$serviceUrl[OOZIEUI]}/"/>
+ </match>
+ <match pattern="https://*:*/**/oozie/">
+ <rewrite template="{$serviceUrl[OOZIEUI]}/"/>
+ </match>
</rule>
- <rule dir="IN" name="OOZIEUI/oozie/inbound/path" pattern="*://*:*/**/oozie/{**}">
- <rewrite template="{$serviceUrl[OOZIEUI]}/{**}"/>
+ <rule dir="IN" name="OOZIEUI/oozie/inbound/path" flow="OR">
+ <match pattern="http://*:*/**/oozie/{**}">
+ <rewrite template="{$serviceUrl[OOZIEUI]}/{**}"/>
+ </match>
+ <match pattern="https://*:*/**/oozie/{**}">
+ <rewrite template="{$serviceUrl[OOZIEUI]}/{**}"/>
+ </match>
</rule>
- <rule dir="IN" name="OOZIEUI/oozie/inbound/query" pattern="*://*:*/**/oozie/{**}?{**}">
- <rewrite template="{$serviceUrl[OOZIEUI]}/{**}?{**}"/>
+ <rule dir="IN" name="OOZIEUI/oozie/inbound/query" flow="OR">
+ <match pattern="http://*:*/**/oozie/{**}?{**}">
+ <rewrite template="{$serviceUrl[OOZIEUI]}/{**}?{**}"/>
+ </match>
+ <match pattern="https://*:*/**/oozie/{**}?{**}">
+ <rewrite template="{$serviceUrl[OOZIEUI]}/{**}?{**}"/>
+ </match>
</rule>
</rules>
\ No newline at end of file
[03/16] knox git commit: KNOX-1104 - Test to verify behavior of
HaProvider service with only a single URL ( Phil Zampino via Sandeep More)
Posted by mo...@apache.org.
KNOX-1104 - Test to verify behavior of HaProvider service with only a single URL ( Phil Zampino via Sandeep More)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/7f58a165
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/7f58a165
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/7f58a165
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 7f58a165f1af9fb7ab45169f5e58b858fdc9c682
Parents: 67ad3e3
Author: Sandeep More <mo...@apache.org>
Authored: Sun Nov 5 15:26:46 2017 -0500
Committer: Sandeep More <mo...@apache.org>
Committed: Sun Nov 5 15:26:46 2017 -0500
----------------------------------------------------------------------
.../ha/provider/impl/DefaultURLManagerTest.java | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/7f58a165/gateway-provider-ha/src/test/java/org/apache/hadoop/gateway/ha/provider/impl/DefaultURLManagerTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-ha/src/test/java/org/apache/hadoop/gateway/ha/provider/impl/DefaultURLManagerTest.java b/gateway-provider-ha/src/test/java/org/apache/hadoop/gateway/ha/provider/impl/DefaultURLManagerTest.java
index 6c07d23..619abbc 100644
--- a/gateway-provider-ha/src/test/java/org/apache/hadoop/gateway/ha/provider/impl/DefaultURLManagerTest.java
+++ b/gateway-provider-ha/src/test/java/org/apache/hadoop/gateway/ha/provider/impl/DefaultURLManagerTest.java
@@ -43,6 +43,25 @@ public class DefaultURLManagerTest {
assertEquals(url1, manager.getActiveURL());
}
+ /**
+ * KNOX-1104
+ * Verify that a service with HaProvider configuration, but only a single URL does not break the HaProvider.
+ */
+ @Test
+ public void testSingleURLManagement() {
+ ArrayList<String> urls = new ArrayList<>();
+ String url1 = "http://host1";
+ urls.add(url1);
+ DefaultURLManager manager = new DefaultURLManager();
+ manager.setURLs(urls);
+ assertTrue(manager.getURLs().containsAll(urls));
+ assertEquals(url1, manager.getActiveURL());
+ manager.markFailed(url1);
+ assertEquals(url1, manager.getActiveURL());
+ manager.markFailed(url1);
+ assertEquals(url1, manager.getActiveURL());
+ }
+
@Test
public void testMarkingFailedURL() {
ArrayList<String> urls = new ArrayList<>();
[08/16] knox git commit: KNOX-1110 - Simple Descriptors Must
Accommodate Application elements (Phil Zampino via lmccay)
Posted by mo...@apache.org.
KNOX-1110 - Simple Descriptors Must Accommodate Application elements (Phil Zampino via lmccay)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/a068eb8d
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/a068eb8d
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/a068eb8d
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: a068eb8da8848ca5b5729fb568984621bfb60bf2
Parents: 6b250b1
Author: Larry McCay <lm...@hortonworks.com>
Authored: Wed Nov 8 18:21:09 2017 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Wed Nov 8 18:21:09 2017 -0500
----------------------------------------------------------------------
.../topology/simple/SimpleDescriptor.java | 10 +
.../simple/SimpleDescriptorHandler.java | 31 +
.../topology/simple/SimpleDescriptorImpl.java | 42 +-
.../simple/SimpleDescriptorFactoryTest.java | 631 +++++++++++++------
4 files changed, 527 insertions(+), 187 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/a068eb8d/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptor.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptor.java
index 7072965..9cb0e2f 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptor.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptor.java
@@ -37,6 +37,8 @@ public interface SimpleDescriptor {
List<Service> getServices();
+ List<Application> getApplications();
+
interface Service {
String getName();
@@ -45,4 +47,12 @@ public interface SimpleDescriptor {
List<String> getURLs();
}
+
+ interface Application {
+ String getName();
+
+ Map<String, String> getParams();
+
+ List<String> getURLs();
+ }
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a068eb8d/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
index 70c9539..040eb86 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorHandler.java
@@ -161,6 +161,7 @@ public class SimpleDescriptorHandler {
}
policyReader.close();
+ // Services
// Sort the service names to write the services alphabetically
List<String> serviceNames = new ArrayList<>(validServiceNames);
Collections.sort(serviceNames);
@@ -192,6 +193,36 @@ public class SimpleDescriptorHandler {
fw.write(" </service>\n");
}
+ // Applications
+ List<SimpleDescriptor.Application> apps = desc.getApplications();
+ if (apps != null) {
+ for (SimpleDescriptor.Application app : apps) {
+ fw.write(" <application>\n");
+ fw.write(" <name>" + app.getName() + "</name>\n");
+
+ // URLs
+ List<String> urls = app.getURLs();
+ if (urls != null) {
+ for (String url : urls) {
+ fw.write(" <url>" + url + "</url>\n");
+ }
+ }
+
+ // Params
+ Map<String, String> appParams = app.getParams();
+ if (appParams != null) {
+ for (String paramName : appParams.keySet()) {
+ fw.write(" <param>\n");
+ fw.write(" <name>" + paramName + "</name>\n");
+ fw.write(" <value>" + appParams.get(paramName) + "</value>\n");
+ fw.write(" </param>\n");
+ }
+ }
+
+ fw.write(" </application>\n");
+ }
+ }
+
fw.write("</topology>\n");
fw.flush();
http://git-wip-us.apache.org/repos/asf/knox/blob/a068eb8d/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorImpl.java
index bb430a1..7de38a8 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorImpl.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorImpl.java
@@ -46,6 +46,9 @@ class SimpleDescriptorImpl implements SimpleDescriptor {
@JsonProperty("services")
private List<ServiceImpl> services;
+ @JsonProperty("applications")
+ private List<ApplicationImpl> applications;
+
private String name = null;
void setName(String name) {
@@ -90,7 +93,18 @@ class SimpleDescriptorImpl implements SimpleDescriptor {
@Override
public List<Service> getServices() {
List<Service> result = new ArrayList<>();
- result.addAll(services);
+ if (services != null) {
+ result.addAll(services);
+ }
+ return result;
+ }
+
+ @Override
+ public List<Application> getApplications() {
+ List<Application> result = new ArrayList<>();
+ if (applications != null) {
+ result.addAll(applications);
+ }
return result;
}
@@ -120,4 +134,30 @@ class SimpleDescriptorImpl implements SimpleDescriptor {
}
}
+ public static class ApplicationImpl implements Application {
+ @JsonProperty("name")
+ private String name;
+
+ @JsonProperty("params")
+ private Map<String, String> params;
+
+ @JsonProperty("urls")
+ private List<String> urls;
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Map<String, String> getParams() {
+ return params;
+ }
+
+ @Override
+ public List<String> getURLs() {
+ return urls;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/a068eb8d/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorFactoryTest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorFactoryTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorFactoryTest.java
index 2ba8758..129ff7c 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorFactoryTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/topology/simple/SimpleDescriptorFactoryTest.java
@@ -27,13 +27,57 @@ import static org.junit.Assert.*;
public class SimpleDescriptorFactoryTest {
+ private enum FileType {
+ JSON,
+ YAML
+ }
@Test
public void testParseJSONSimpleDescriptor() throws Exception {
+ testParseSimpleDescriptor(FileType.JSON);
+ }
+
+ @Test
+ public void testParseYAMLSimpleDescriptor() throws Exception {
+ testParseSimpleDescriptor(FileType.YAML);
+ }
+
+ @Test
+ public void testParseJSONSimpleDescriptorWithServiceParams() throws Exception {
+ testParseSimpleDescriptorWithServiceParams(FileType.JSON);
+ }
+
+ @Test
+ public void testParseYAMLSimpleDescriptorWithServiceParams() throws Exception {
+ testParseSimpleDescriptorWithServiceParams(FileType.YAML);
+ }
+
+ @Test
+ public void testParseJSONSimpleDescriptorWithApplications() throws Exception {
+ testParseSimpleDescriptorWithApplications(FileType.JSON);
+ }
+
+ @Test
+ public void testParseYAMLSimpleDescriptorApplications() throws Exception {
+ testParseSimpleDescriptorWithApplications(FileType.YAML);
+ }
+
+
+ @Test
+ public void testParseJSONSimpleDescriptorWithServicesAndApplications() throws Exception {
+ testParseSimpleDescriptorWithServicesAndApplications(FileType.JSON);
+ }
+
+ @Test
+ public void testParseYAMLSimpleDescriptorWithServicesAndApplications() throws Exception {
+ testParseSimpleDescriptorWithServicesAndApplications(FileType.YAML);
+ }
+
+ private void testParseSimpleDescriptor(FileType type) throws Exception {
final String discoveryType = "AMBARI";
final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
- final String discoveryUser = "admin";
+ final String discoveryUser = "joeblow";
final String providerConfig = "ambari-cluster-policy.xml";
final String clusterName = "myCluster";
@@ -42,20 +86,27 @@ public class SimpleDescriptorFactoryTest {
services.put("JOBTRACKER", null);
services.put("RESOURCEMANAGER", null);
services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
- services.put("AMBARIUI", Arrays.asList("http://c6401.ambari.apache.org:8080"));
+ services.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
- String fileName = "test-topology.json";
- File testJSON = null;
+ String fileName = "test-topology." + getFileExtensionForType(type);
+ File testFile = null;
try {
- testJSON = writeJSON(fileName, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testJSON.getAbsolutePath());
+ testFile = writeDescriptorFile(type,
+ fileName,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services);
+ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services);
} catch (Exception e) {
e.printStackTrace();
} finally {
- if (testJSON != null) {
+ if (testFile != null) {
try {
- testJSON.delete();
+ testFile.delete();
} catch (Exception e) {
// Ignore
}
@@ -63,8 +114,7 @@ public class SimpleDescriptorFactoryTest {
}
}
- @Test
- public void testParseJSONSimpleDescriptorWithServiceParams() throws Exception {
+ private void testParseSimpleDescriptorWithServiceParams(FileType type) throws Exception {
final String discoveryType = "AMBARI";
final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
@@ -99,25 +149,24 @@ public class SimpleDescriptorFactoryTest {
customRoleParams.put("custom.param.2", "value2");
serviceParams.put("CustomRole", customRoleParams);
- String fileName = "test-topology.json";
- File testJSON = null;
+ String fileName = "test-topology." + getFileExtensionForType(type);
+ File testFile = null;
try {
- testJSON = writeJSON(fileName,
- discoveryType,
- discoveryAddress,
- discoveryUser,
- providerConfig,
- clusterName,
- services,
- serviceParams);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testJSON.getAbsolutePath());
+ testFile = writeDescriptorFile(type,
+ fileName,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services,
+ serviceParams);
+ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services, serviceParams);
- } catch (Exception e) {
- e.printStackTrace();
} finally {
- if (testJSON != null) {
+ if (testFile != null) {
try {
- testJSON.delete();
+ testFile.delete();
} catch (Exception e) {
// Ignore
}
@@ -125,34 +174,59 @@ public class SimpleDescriptorFactoryTest {
}
}
- @Test
- public void testParseYAMLSimpleDescriptor() throws Exception {
+ private void testParseSimpleDescriptorWithApplications(FileType type) throws Exception {
final String discoveryType = "AMBARI";
final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
- final String discoveryUser = "joeblow";
+ final String discoveryUser = "admin";
final String providerConfig = "ambari-cluster-policy.xml";
final String clusterName = "myCluster";
- final Map<String, List<String>> services = new HashMap<>();
- services.put("NODEMANAGER", null);
- services.put("JOBTRACKER", null);
- services.put("RESOURCEMANAGER", null);
- services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
- services.put("AMBARIUI", Arrays.asList("http://c6401.ambari.apache.org:8080"));
-
- String fileName = "test-topology.yml";
- File testYAML = null;
+ final Map<String, List<String>> apps = new HashMap<>();
+ apps.put("app-one", null);
+ apps.put("appTwo", null);
+ apps.put("thirdApps", null);
+ apps.put("appfour", Arrays.asList("http://host1:1234", "http://host2:5678", "http://host1:1357"));
+ apps.put("AppFive", Collections.singletonList("http://host5:8080"));
+
+ final Map<String, Map<String, String>> appParams = new HashMap<>();
+ Map<String, String> oneParams = new HashMap<>();
+ oneParams.put("appone.cookie.secure.only", "true");
+ oneParams.put("appone.token.ttl", "100000");
+ appParams.put("app-one", oneParams);
+ Map<String, String> fiveParams = new HashMap<>();
+ fiveParams.put("myproperty", "true");
+ fiveParams.put("anotherparam", "100000");
+ appParams.put("AppFive", fiveParams);
+
+ String fileName = "test-topology." + getFileExtensionForType(type);
+ File testFile = null;
try {
- testYAML = writeYAML(fileName, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testYAML.getAbsolutePath());
- validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services);
- } catch (Exception e) {
- e.printStackTrace();
+ testFile = writeDescriptorFile(type,
+ fileName,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ null,
+ null,
+ apps,
+ appParams);
+ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
+ validateSimpleDescriptor(sd,
+ discoveryType,
+ discoveryAddress,
+ providerConfig,
+ clusterName,
+ null,
+ null,
+ apps,
+ appParams);
} finally {
- if (testYAML != null) {
+ if (testFile != null) {
try {
- testYAML.delete();
+ testFile.delete();
} catch (Exception e) {
// Ignore
}
@@ -160,13 +234,11 @@ public class SimpleDescriptorFactoryTest {
}
}
-
- @Test
- public void testParseYAMLSimpleDescriptorWithServiceParams() throws Exception {
+ private void testParseSimpleDescriptorWithServicesAndApplications(FileType type) throws Exception {
final String discoveryType = "AMBARI";
final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
- final String discoveryUser = "joeblow";
+ final String discoveryUser = "admin";
final String providerConfig = "ambari-cluster-policy.xml";
final String clusterName = "myCluster";
@@ -175,7 +247,7 @@ public class SimpleDescriptorFactoryTest {
services.put("JOBTRACKER", null);
services.put("RESOURCEMANAGER", null);
services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
- services.put("AMBARIUI", Arrays.asList("http://c6401.ambari.apache.org:8080"));
+ services.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
services.put("KNOXSSO", null);
services.put("KNOXTOKEN", null);
services.put("CustomRole", Collections.singletonList("http://c6402.ambari.apache.org:1234"));
@@ -197,18 +269,51 @@ public class SimpleDescriptorFactoryTest {
customRoleParams.put("custom.param.2", "value2");
serviceParams.put("CustomRole", customRoleParams);
- String fileName = "test-topology.yml";
- File testYAML = null;
+ final Map<String, List<String>> apps = new HashMap<>();
+ apps.put("app-one", null);
+ apps.put("appTwo", null);
+ apps.put("thirdApps", null);
+ apps.put("appfour", Arrays.asList("http://host1:1234", "http://host2:5678", "http://host1:1357"));
+ apps.put("AppFive", Collections.singletonList("http://host5:8080"));
+
+ final Map<String, Map<String, String>> appParams = new HashMap<>();
+ Map<String, String> oneParams = new HashMap<>();
+ oneParams.put("appone.cookie.secure.only", "true");
+ oneParams.put("appone.token.ttl", "100000");
+ appParams.put("app-one", oneParams);
+ Map<String, String> fiveParams = new HashMap<>();
+ fiveParams.put("myproperty", "true");
+ fiveParams.put("anotherparam", "100000");
+ appParams.put("AppFive", fiveParams);
+
+ String fileName = "test-topology." + getFileExtensionForType(type);
+ File testFile = null;
try {
- testYAML = writeYAML(fileName, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services, serviceParams);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testYAML.getAbsolutePath());
- validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services, serviceParams);
- } catch (Exception e) {
- e.printStackTrace();
+ testFile = writeDescriptorFile(type,
+ fileName,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services,
+ serviceParams,
+ apps,
+ appParams);
+ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
+ validateSimpleDescriptor(sd,
+ discoveryType,
+ discoveryAddress,
+ providerConfig,
+ clusterName,
+ services,
+ serviceParams,
+ apps,
+ appParams);
} finally {
- if (testYAML != null) {
+ if (testFile != null) {
try {
- testYAML.delete();
+ testFile.delete();
} catch (Exception e) {
// Ignore
}
@@ -216,82 +321,103 @@ public class SimpleDescriptorFactoryTest {
}
}
-
- private void validateSimpleDescriptor(SimpleDescriptor sd,
- String discoveryType,
- String discoveryAddress,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> expectedServices) {
- validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, expectedServices, null);
- }
-
-
- private void validateSimpleDescriptor(SimpleDescriptor sd,
- String discoveryType,
- String discoveryAddress,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> expectedServices,
- Map<String, Map<String, String>> expectedServiceParameters) {
- assertNotNull(sd);
- assertEquals(discoveryType, sd.getDiscoveryType());
- assertEquals(discoveryAddress, sd.getDiscoveryAddress());
- assertEquals(providerConfig, sd.getProviderConfig());
- assertEquals(clusterName, sd.getClusterName());
-
- List<SimpleDescriptor.Service> actualServices = sd.getServices();
-
- assertEquals(expectedServices.size(), actualServices.size());
-
- for (SimpleDescriptor.Service actualService : actualServices) {
- assertTrue(expectedServices.containsKey(actualService.getName()));
- assertEquals(expectedServices.get(actualService.getName()), actualService.getURLs());
-
- // Validate service parameters
- if (expectedServiceParameters != null) {
- if (expectedServiceParameters.containsKey(actualService.getName())) {
- Map<String, String> expectedParams = expectedServiceParameters.get(actualService.getName());
-
- Map<String, String> actualServiceParams = actualService.getParams();
- assertNotNull(actualServiceParams);
-
- // Validate the size of the service parameter set
- assertEquals(expectedParams.size(), actualServiceParams.size());
-
- // Validate the parameter contents
- for (String paramName : actualServiceParams.keySet()) {
- assertTrue(expectedParams.containsKey(paramName));
- assertEquals(expectedParams.get(paramName), actualServiceParams.get(paramName));
- }
- }
- }
+ private String getFileExtensionForType(FileType type) {
+ String extension = null;
+ switch (type) {
+ case JSON:
+ extension = "json";
+ break;
+ case YAML:
+ extension = "yml";
+ break;
}
+ return extension;
}
+ private File writeDescriptorFile(FileType type,
+ String path,
+ String discoveryType,
+ String discoveryAddress,
+ String discoveryUser,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> services) throws Exception {
+ return writeDescriptorFile(type,
+ path,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services,
+ null);
+ }
- private File writeJSON(String path, String content) throws Exception {
- File f = new File(path);
-
- Writer fw = new FileWriter(f);
- fw.write(content);
- fw.flush();
- fw.close();
-
- return f;
+ private File writeDescriptorFile(FileType type,
+ String path,
+ String discoveryType,
+ String discoveryAddress,
+ String discoveryUser,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> services,
+ Map<String, Map<String, String>> serviceParams) throws Exception {
+ return writeDescriptorFile(type,
+ path,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services,
+ serviceParams,
+ null,
+ null);
}
- private File writeJSON(String path,
- String discoveryType,
- String discoveryAddress,
- String discoveryUser,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> services) throws Exception {
- return writeJSON(path, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services, null);
+ private File writeDescriptorFile(FileType type,
+ String path,
+ String discoveryType,
+ String discoveryAddress,
+ String discoveryUser,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> services,
+ Map<String, Map<String, String>> serviceParams,
+ Map<String, List<String>> apps,
+ Map<String, Map<String, String>> appParams) throws Exception {
+ File result = null;
+ switch (type) {
+ case JSON:
+ result = writeJSON(path,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services,
+ serviceParams,
+ apps,
+ appParams);
+ break;
+ case YAML:
+ result = writeYAML(path,
+ discoveryType,
+ discoveryAddress,
+ discoveryUser,
+ providerConfig,
+ clusterName,
+ services,
+ serviceParams,
+ apps,
+ appParams);
+ break;
+ }
+ return result;
}
+
private File writeJSON(String path,
String discoveryType,
String discoveryAddress,
@@ -299,7 +425,9 @@ public class SimpleDescriptorFactoryTest {
String providerConfig,
String clusterName,
Map<String, List<String>> services,
- Map<String, Map<String, String>> serviceParams) throws Exception {
+ Map<String, Map<String, String>> serviceParams,
+ Map<String, List<String>> apps,
+ Map<String, Map<String, String>> appParams) throws Exception {
File f = new File(path);
Writer fw = new FileWriter(f);
@@ -308,50 +436,20 @@ public class SimpleDescriptorFactoryTest {
fw.write("\"discovery-address\":\"" + discoveryAddress + "\",\n");
fw.write("\"discovery-user\":\"" + discoveryUser + "\",\n");
fw.write("\"provider-config-ref\":\"" + providerConfig + "\",\n");
- fw.write("\"cluster\":\"" + clusterName + "\",\n");
- fw.write("\"services\":[\n");
-
- int i = 0;
- for (String name : services.keySet()) {
- fw.write("{\"name\":\"" + name + "\"");
-
- // Service params
- if (serviceParams != null && !serviceParams.isEmpty()) {
- Map<String, String> params = serviceParams.get(name);
- if (params != null && !params.isEmpty()) {
- fw.write(",\n\"params\":{\n");
- Iterator<String> paramNames = params.keySet().iterator();
- while (paramNames.hasNext()) {
- String paramName = paramNames.next();
- String paramValue = params.get(paramName);
- fw.write("\"" + paramName + "\":\"" + paramValue + "\"");
- fw.write(paramNames.hasNext() ? ",\n" : "");
- }
- fw.write("\n}");
- }
- }
+ fw.write("\"cluster\":\"" + clusterName + "\"");
- // Service URLs
- List<String> urls = services.get(name);
- if (urls != null) {
- fw.write(",\n\"urls\":[");
- Iterator<String> urlIter = urls.iterator();
- while (urlIter.hasNext()) {
- fw.write("\"" + urlIter.next() + "\"");
- if (urlIter.hasNext()) {
- fw.write(", ");
- }
- }
- fw.write("]\n");
- }
+ if (services != null && !services.isEmpty()) {
+ fw.write(",\n\"services\":[\n");
+ writeServiceOrApplicationJSON(fw, services, serviceParams);
+ fw.write("]\n");
+ }
- fw.write("}");
- if (i++ < services.size() - 1) {
- fw.write(",");
- }
- fw.write("\n");
+ if (apps != null && !apps.isEmpty()) {
+ fw.write(",\n\"applications\":[\n");
+ writeServiceOrApplicationJSON(fw, apps, appParams);
+ fw.write("]\n");
}
- fw.write("]\n");
+
fw.write("}\n");
fw.flush();
fw.close();
@@ -359,17 +457,52 @@ public class SimpleDescriptorFactoryTest {
return f;
}
+ private void writeServiceOrApplicationJSON(Writer fw,
+ Map<String, List<String>> elementURLs,
+ Map<String, Map<String, String>> elementParams) throws Exception {
+ if (elementURLs != null) {
+ int i = 0;
+ for (String name : elementURLs.keySet()) {
+ fw.write("{\"name\":\"" + name + "\"");
+
+ // Service params
+ if (elementParams != null && !elementParams.isEmpty()) {
+ Map<String, String> params = elementParams.get(name);
+ if (params != null && !params.isEmpty()) {
+ fw.write(",\n\"params\":{\n");
+ Iterator<String> paramNames = params.keySet().iterator();
+ while (paramNames.hasNext()) {
+ String paramName = paramNames.next();
+ String paramValue = params.get(paramName);
+ fw.write("\"" + paramName + "\":\"" + paramValue + "\"");
+ fw.write(paramNames.hasNext() ? ",\n" : "");
+ }
+ fw.write("\n}");
+ }
+ }
- private File writeYAML(String path,
- String discoveryType,
- String discoveryAddress,
- String discoveryUser,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> services) throws Exception {
- return writeYAML(path, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services, null);
- }
+ // Service URLs
+ List<String> urls = elementURLs.get(name);
+ if (urls != null) {
+ fw.write(",\n\"urls\":[");
+ Iterator<String> urlIter = urls.iterator();
+ while (urlIter.hasNext()) {
+ fw.write("\"" + urlIter.next() + "\"");
+ if (urlIter.hasNext()) {
+ fw.write(", ");
+ }
+ }
+ fw.write("]\n");
+ }
+ fw.write("}");
+ if (i++ < elementURLs.size() - 1) {
+ fw.write(",");
+ }
+ fw.write("\n");
+ }
+ }
+ }
private File writeYAML(String path,
String discoveryType,
@@ -378,7 +511,10 @@ public class SimpleDescriptorFactoryTest {
String providerConfig,
String clusterName,
Map<String, List<String>> services,
- Map<String, Map<String, String>> serviceParams) throws Exception {
+ Map<String, Map<String, String>> serviceParams,
+ Map<String, List<String>> apps,
+ Map<String, Map<String, String>> appParams) throws Exception {
+
File f = new File(path);
Writer fw = new FileWriter(f);
@@ -388,14 +524,33 @@ public class SimpleDescriptorFactoryTest {
fw.write("discovery-user: " + discoveryUser + "\n");
fw.write("provider-config-ref: " + providerConfig + "\n");
fw.write("cluster: " + clusterName+ "\n");
- fw.write("services:\n");
- for (String name : services.keySet()) {
+
+ if (services != null && !services.isEmpty()) {
+ fw.write("services:\n");
+ writeServiceOrApplicationYAML(fw, services, serviceParams);
+ }
+
+ if (apps != null && !apps.isEmpty()) {
+ fw.write("applications:\n");
+ writeServiceOrApplicationYAML(fw, apps, appParams);
+ }
+
+ fw.flush();
+ fw.close();
+
+ return f;
+ }
+
+ private void writeServiceOrApplicationYAML(Writer fw,
+ Map<String, List<String>> elementURLs,
+ Map<String, Map<String, String>> elementParams) throws Exception {
+ for (String name : elementURLs.keySet()) {
fw.write(" - name: " + name + "\n");
// Service params
- if (serviceParams != null && !serviceParams.isEmpty()) {
- if (serviceParams.containsKey(name)) {
- Map<String, String> params = serviceParams.get(name);
+ if (elementParams != null && !elementParams.isEmpty()) {
+ if (elementParams.containsKey(name)) {
+ Map<String, String> params = elementParams.get(name);
fw.write(" params:\n");
for (String paramName : params.keySet()) {
fw.write(" " + paramName + ": " + params.get(paramName) + "\n");
@@ -404,7 +559,7 @@ public class SimpleDescriptorFactoryTest {
}
// Service URLs
- List<String> urls = services.get(name);
+ List<String> urls = elementURLs.get(name);
if (urls != null) {
fw.write(" urls:\n");
for (String url : urls) {
@@ -412,11 +567,115 @@ public class SimpleDescriptorFactoryTest {
}
}
}
- fw.flush();
- fw.close();
+ }
- return f;
+
+ private void validateSimpleDescriptor(SimpleDescriptor sd,
+ String discoveryType,
+ String discoveryAddress,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> expectedServices) {
+ validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, expectedServices, null);
+ }
+
+
+ private void validateSimpleDescriptor(SimpleDescriptor sd,
+ String discoveryType,
+ String discoveryAddress,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> expectedServices,
+ Map<String, Map<String, String>> expectedServiceParameters) {
+ validateSimpleDescriptor(sd,
+ discoveryType,
+ discoveryAddress,
+ providerConfig,
+ clusterName,
+ expectedServices,
+ expectedServiceParameters,
+ null,
+ null);
}
+ private void validateSimpleDescriptor(SimpleDescriptor sd,
+ String discoveryType,
+ String discoveryAddress,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> expectedServices,
+ Map<String, Map<String, String>> expectedServiceParameters,
+ Map<String, List<String>> expectedApps,
+ Map<String, Map<String, String>> expectedAppParameters) {
+ assertNotNull(sd);
+ assertEquals(discoveryType, sd.getDiscoveryType());
+ assertEquals(discoveryAddress, sd.getDiscoveryAddress());
+ assertEquals(providerConfig, sd.getProviderConfig());
+ assertEquals(clusterName, sd.getClusterName());
+
+ List<SimpleDescriptor.Service> actualServices = sd.getServices();
+
+ if (expectedServices == null) {
+ assertTrue(actualServices.isEmpty());
+ } else {
+ assertEquals(expectedServices.size(), actualServices.size());
+
+ for (SimpleDescriptor.Service actualService : actualServices) {
+ assertTrue(expectedServices.containsKey(actualService.getName()));
+ assertEquals(expectedServices.get(actualService.getName()), actualService.getURLs());
+
+ // Validate service parameters
+ if (expectedServiceParameters != null) {
+ if (expectedServiceParameters.containsKey(actualService.getName())) {
+ Map<String, String> expectedParams = expectedServiceParameters.get(actualService.getName());
+
+ Map<String, String> actualServiceParams = actualService.getParams();
+ assertNotNull(actualServiceParams);
+
+ // Validate the size of the service parameter set
+ assertEquals(expectedParams.size(), actualServiceParams.size());
+
+ // Validate the parameter contents
+ for (String paramName : actualServiceParams.keySet()) {
+ assertTrue(expectedParams.containsKey(paramName));
+ assertEquals(expectedParams.get(paramName), actualServiceParams.get(paramName));
+ }
+ }
+ }
+ }
+ }
+
+ List<SimpleDescriptor.Application> actualApps = sd.getApplications();
+
+ if (expectedApps == null) {
+ assertTrue(actualApps.isEmpty());
+ } else {
+ assertEquals(expectedApps.size(), actualApps.size());
+
+ for (SimpleDescriptor.Application actualApp : actualApps) {
+ assertTrue(expectedApps.containsKey(actualApp.getName()));
+ assertEquals(expectedApps.get(actualApp.getName()), actualApp.getURLs());
+
+ // Validate service parameters
+ if (expectedServiceParameters != null) {
+ if (expectedAppParameters.containsKey(actualApp.getName())) {
+ Map<String, String> expectedParams = expectedAppParameters.get(actualApp.getName());
+
+ Map<String, String> actualAppParams = actualApp.getParams();
+ assertNotNull(actualAppParams);
+
+ // Validate the size of the service parameter set
+ assertEquals(expectedParams.size(), actualAppParams.size());
+
+ // Validate the parameter contents
+ for (String paramName : actualAppParams.keySet()) {
+ assertTrue(expectedParams.containsKey(paramName));
+ assertEquals(expectedParams.get(paramName), actualAppParams.get(paramName));
+ }
+ }
+ }
+ }
+ }
+ }
}
[11/16] knox git commit: Updated build version to 1.0.0-SNAPSHOT
Posted by mo...@apache.org.
Updated build version to 1.0.0-SNAPSHOT
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/d4b0dc60
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/d4b0dc60
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/d4b0dc60
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: d4b0dc608f886dd30ea17767e24e5f3179fffa0d
Parents: 898827c
Author: Larry McCay <lm...@hortonworks.com>
Authored: Wed Nov 8 21:29:47 2017 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Wed Nov 8 21:29:47 2017 -0500
----------------------------------------------------------------------
build.xml | 2 +-
gateway-applications/pom.xml | 2 +-
gateway-demo-ldap-launcher/pom.xml | 2 +-
gateway-demo-ldap/pom.xml | 2 +-
gateway-discovery-ambari/pom.xml | 2 +-
gateway-i18n-logging-log4j/pom.xml | 2 +-
gateway-i18n-logging-sl4j/pom.xml | 2 +-
gateway-i18n/pom.xml | 2 +-
gateway-provider-ha/pom.xml | 2 +-
gateway-provider-identity-assertion-common/pom.xml | 2 +-
gateway-provider-identity-assertion-concat/pom.xml | 2 +-
gateway-provider-identity-assertion-hadoop-groups/pom.xml | 2 +-
gateway-provider-identity-assertion-pseudo/pom.xml | 2 +-
gateway-provider-identity-assertion-regex/pom.xml | 2 +-
gateway-provider-identity-assertion-switchcase/pom.xml | 2 +-
gateway-provider-jersey/pom.xml | 2 +-
gateway-provider-rewrite-func-hostmap-static/pom.xml | 2 +-
gateway-provider-rewrite-func-inbound-query-param/pom.xml | 2 +-
gateway-provider-rewrite-func-service-registry/pom.xml | 2 +-
gateway-provider-rewrite-step-encrypt-uri/pom.xml | 2 +-
gateway-provider-rewrite-step-secure-query/pom.xml | 2 +-
gateway-provider-rewrite/pom.xml | 2 +-
gateway-provider-security-authc-anon/pom.xml | 2 +-
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-pac4j/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/pom.xml | 2 +-
gateway-server-launcher/pom.xml | 2 +-
gateway-server-xforwarded-filter/pom.xml | 2 +-
gateway-server/pom.xml | 2 +-
gateway-service-admin/pom.xml | 4 ++--
gateway-service-as/pom.xml | 2 +-
gateway-service-definitions/pom.xml | 2 +-
gateway-service-hbase/pom.xml | 2 +-
gateway-service-health/pom.xml | 4 ++--
gateway-service-hive/pom.xml | 2 +-
gateway-service-knoxsso/pom.xml | 4 ++--
gateway-service-knoxssout/pom.xml | 4 ++--
gateway-service-knoxtoken/pom.xml | 4 ++--
gateway-service-nifi/pom.xml | 2 +-
gateway-service-rm/pom.xml | 2 +-
gateway-service-storm/pom.xml | 2 +-
gateway-service-test/pom.xml | 4 ++--
gateway-service-tgs/pom.xml | 2 +-
gateway-service-vault/pom.xml | 4 ++--
gateway-service-webhdfs/pom.xml | 2 +-
gateway-shell-launcher/pom.xml | 2 +-
gateway-shell-release/pom.xml | 2 +-
gateway-shell-samples/pom.xml | 2 +-
gateway-shell/pom.xml | 2 +-
gateway-spi/pom.xml | 2 +-
gateway-test-release-utils/pom.xml | 2 +-
gateway-test-release/pom.xml | 2 +-
gateway-test-release/webhdfs-kerb-test/pom.xml | 4 ++--
gateway-test-release/webhdfs-test/pom.xml | 4 ++--
gateway-test-utils/pom.xml | 2 +-
gateway-test/pom.xml | 2 +-
gateway-util-common/pom.xml | 2 +-
gateway-util-configinjector/pom.xml | 2 +-
gateway-util-launcher/pom.xml | 2 +-
gateway-util-urltemplate/pom.xml | 2 +-
hadoop-examples/pom.xml | 2 +-
knox-cli-launcher/pom.xml | 2 +-
pom.xml | 4 ++--
68 files changed, 78 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index b499ab7..e99937d 100644
--- a/build.xml
+++ b/build.xml
@@ -25,7 +25,7 @@ Release build file for the Apache Knox Gateway
<property name="gateway-project" value="knox"/>
<property name="gateway-artifact" value="knox"/>
<property name="knoxshell-artifact" value="knoxshell"/>
- <property name="gateway-version" value="0.14.0-SNAPSHOT"/>
+ <property name="gateway-version" value="1.0.0-SNAPSHOT"/>
<property name="release-manager" value="kminder"/>
<property name="gateway-home" value="${gateway-artifact}-${gateway-version}"/>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-applications/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-applications/pom.xml b/gateway-applications/pom.xml
index 4d88364..ef18945 100644
--- a/gateway-applications/pom.xml
+++ b/gateway-applications/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-applications</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-demo-ldap-launcher/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-demo-ldap-launcher/pom.xml b/gateway-demo-ldap-launcher/pom.xml
index b5723d3..97e4c39 100644
--- a/gateway-demo-ldap-launcher/pom.xml
+++ b/gateway-demo-ldap-launcher/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-demo-ldap-launcher</artifactId>
<name>gateway-demo-ldap-launcher</name>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-demo-ldap/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-demo-ldap/pom.xml b/gateway-demo-ldap/pom.xml
index 55ab2b8..3b11303 100644
--- a/gateway-demo-ldap/pom.xml
+++ b/gateway-demo-ldap/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-demo-ldap</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-discovery-ambari/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-discovery-ambari/pom.xml b/gateway-discovery-ambari/pom.xml
index 924e89c..a11962f 100644
--- a/gateway-discovery-ambari/pom.xml
+++ b/gateway-discovery-ambari/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-discovery-ambari</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-i18n-logging-log4j/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-i18n-logging-log4j/pom.xml b/gateway-i18n-logging-log4j/pom.xml
index 0d869cd..f841205 100644
--- a/gateway-i18n-logging-log4j/pom.xml
+++ b/gateway-i18n-logging-log4j/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-i18n-logging-log4j</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-i18n-logging-sl4j/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-i18n-logging-sl4j/pom.xml b/gateway-i18n-logging-sl4j/pom.xml
index 4490704..80568df 100644
--- a/gateway-i18n-logging-sl4j/pom.xml
+++ b/gateway-i18n-logging-sl4j/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-i18n-logging-sl4j</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-i18n/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-i18n/pom.xml b/gateway-i18n/pom.xml
index 3c09f62..f02fb10 100644
--- a/gateway-i18n/pom.xml
+++ b/gateway-i18n/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-i18n</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-ha/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-ha/pom.xml b/gateway-provider-ha/pom.xml
index 23a0f1d..00a5b77 100644
--- a/gateway-provider-ha/pom.xml
+++ b/gateway-provider-ha/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-ha</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-identity-assertion-common/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/pom.xml b/gateway-provider-identity-assertion-common/pom.xml
index 4c8171c..e093ef2 100644
--- a/gateway-provider-identity-assertion-common/pom.xml
+++ b/gateway-provider-identity-assertion-common/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-identity-assertion-common</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-identity-assertion-concat/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/pom.xml b/gateway-provider-identity-assertion-concat/pom.xml
index b367ce0..d003305 100644
--- a/gateway-provider-identity-assertion-concat/pom.xml
+++ b/gateway-provider-identity-assertion-concat/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-identity-assertion-concat</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-identity-assertion-hadoop-groups/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-hadoop-groups/pom.xml b/gateway-provider-identity-assertion-hadoop-groups/pom.xml
index 4d316f1..c42016a5 100644
--- a/gateway-provider-identity-assertion-hadoop-groups/pom.xml
+++ b/gateway-provider-identity-assertion-hadoop-groups/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-identity-assertion-hadoop-groups</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-identity-assertion-pseudo/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-pseudo/pom.xml b/gateway-provider-identity-assertion-pseudo/pom.xml
index e3188b2..574db76 100644
--- a/gateway-provider-identity-assertion-pseudo/pom.xml
+++ b/gateway-provider-identity-assertion-pseudo/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-identity-assertion-pseudo</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-identity-assertion-regex/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-regex/pom.xml b/gateway-provider-identity-assertion-regex/pom.xml
index 7172930..09ff576 100644
--- a/gateway-provider-identity-assertion-regex/pom.xml
+++ b/gateway-provider-identity-assertion-regex/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-identity-assertion-regex</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-identity-assertion-switchcase/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-switchcase/pom.xml b/gateway-provider-identity-assertion-switchcase/pom.xml
index 13acf41..95521aa 100644
--- a/gateway-provider-identity-assertion-switchcase/pom.xml
+++ b/gateway-provider-identity-assertion-switchcase/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-identity-assertion-switchcase</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-jersey/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-jersey/pom.xml b/gateway-provider-jersey/pom.xml
index fcbdc2b..0feb080 100644
--- a/gateway-provider-jersey/pom.xml
+++ b/gateway-provider-jersey/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/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 fd9e1fe..e5aae5b 100644
--- a/gateway-provider-rewrite-func-hostmap-static/pom.xml
+++ b/gateway-provider-rewrite-func-hostmap-static/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-rewrite-func-hostmap-static</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-rewrite-func-inbound-query-param/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-func-inbound-query-param/pom.xml b/gateway-provider-rewrite-func-inbound-query-param/pom.xml
index edab1f6..3f4253a 100644
--- a/gateway-provider-rewrite-func-inbound-query-param/pom.xml
+++ b/gateway-provider-rewrite-func-inbound-query-param/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-rewrite-func-inbound-query-param</artifactId>
<name>gateway-provider-rewrite-func-inbound-url</name>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/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 935c875..288131a 100644
--- a/gateway-provider-rewrite-func-service-registry/pom.xml
+++ b/gateway-provider-rewrite-func-service-registry/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-rewrite-func-service-registry</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/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 9b074a7..874356a 100644
--- a/gateway-provider-rewrite-step-encrypt-uri/pom.xml
+++ b/gateway-provider-rewrite-step-encrypt-uri/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-rewrite-step-encrypt-uri</artifactId>
<name>gateway-provider-rewrite-step-encrypt-uri</name>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-rewrite-step-secure-query/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/pom.xml b/gateway-provider-rewrite-step-secure-query/pom.xml
index eca8b1c..e16e8c8 100644
--- a/gateway-provider-rewrite-step-secure-query/pom.xml
+++ b/gateway-provider-rewrite-step-secure-query/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-rewrite-step-secure-query</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-rewrite/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/pom.xml b/gateway-provider-rewrite/pom.xml
index 6177f4f..2e026e8 100644
--- a/gateway-provider-rewrite/pom.xml
+++ b/gateway-provider-rewrite/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-rewrite</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/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 881aee8..d0307b4 100755
--- a/gateway-provider-security-authc-anon/pom.xml
+++ b/gateway-provider-security-authc-anon/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-authc-anon</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/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 2a6f7b3..7228dc6 100644
--- a/gateway-provider-security-authz-acls/pom.xml
+++ b/gateway-provider-security-authz-acls/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-authz-acls</artifactId>
<name>gateway-provider-security-authz-acls</name>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-security-hadoopauth/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-hadoopauth/pom.xml b/gateway-provider-security-hadoopauth/pom.xml
index 96048bf..a7417ec 100755
--- a/gateway-provider-security-hadoopauth/pom.xml
+++ b/gateway-provider-security-hadoopauth/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-hadoopauth</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-security-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/pom.xml b/gateway-provider-security-jwt/pom.xml
index cb754b6..ac4c6c6 100644
--- a/gateway-provider-security-jwt/pom.xml
+++ b/gateway-provider-security-jwt/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-jwt</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-security-pac4j/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-pac4j/pom.xml b/gateway-provider-security-pac4j/pom.xml
index c8684e2..15d1a93 100644
--- a/gateway-provider-security-pac4j/pom.xml
+++ b/gateway-provider-security-pac4j/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-pac4j</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-security-preauth/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-preauth/pom.xml b/gateway-provider-security-preauth/pom.xml
index 6d2cff1..d467dff 100644
--- a/gateway-provider-security-preauth/pom.xml
+++ b/gateway-provider-security-preauth/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-preauth</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-security-shiro/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-shiro/pom.xml b/gateway-provider-security-shiro/pom.xml
index bb5aa56..c7b082e 100644
--- a/gateway-provider-security-shiro/pom.xml
+++ b/gateway-provider-security-shiro/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-shiro</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-provider-security-webappsec/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-webappsec/pom.xml b/gateway-provider-security-webappsec/pom.xml
index 75db5cc..77b6cc8 100644
--- a/gateway-provider-security-webappsec/pom.xml
+++ b/gateway-provider-security-webappsec/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-provider-security-webappsec</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index cf85f8b..ae6275a 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-release</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-server-launcher/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-server-launcher/pom.xml b/gateway-server-launcher/pom.xml
index 9ff77fe..45f1f37 100644
--- a/gateway-server-launcher/pom.xml
+++ b/gateway-server-launcher/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-server-launcher</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-server-xforwarded-filter/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-server-xforwarded-filter/pom.xml b/gateway-server-xforwarded-filter/pom.xml
index 9dea023..88fc0ef 100644
--- a/gateway-server-xforwarded-filter/pom.xml
+++ b/gateway-server-xforwarded-filter/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-server-xforwarded-filter</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-server/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml
index 5ebf793..0c05625 100644
--- a/gateway-server/pom.xml
+++ b/gateway-server/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-server</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-admin/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-admin/pom.xml b/gateway-service-admin/pom.xml
index 6884683..94ca6c6 100644
--- a/gateway-service-admin/pom.xml
+++ b/gateway-service-admin/pom.xml
@@ -22,11 +22,11 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-service-admin</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-admin</name>
<url>http://maven.apache.org</url>
<properties>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-as/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-as/pom.xml b/gateway-service-as/pom.xml
index 12f1551..e639b0a 100644
--- a/gateway-service-as/pom.xml
+++ b/gateway-service-as/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-as</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-definitions/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/pom.xml b/gateway-service-definitions/pom.xml
index 52dde1e..e2ae0a7 100644
--- a/gateway-service-definitions/pom.xml
+++ b/gateway-service-definitions/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-definitions</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-hbase/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-hbase/pom.xml b/gateway-service-hbase/pom.xml
index 9638d8a..e30fcc0 100644
--- a/gateway-service-hbase/pom.xml
+++ b/gateway-service-hbase/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-hbase</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-health/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-health/pom.xml b/gateway-service-health/pom.xml
index 85e1fb8..c75d264 100644
--- a/gateway-service-health/pom.xml
+++ b/gateway-service-health/pom.xml
@@ -22,11 +22,11 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-service-health</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-health</name>
<url>http://maven.apache.org</url>
<properties>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-hive/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-hive/pom.xml b/gateway-service-hive/pom.xml
index cc74912..6a8e3c5 100644
--- a/gateway-service-hive/pom.xml
+++ b/gateway-service-hive/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-hive</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-knoxsso/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-knoxsso/pom.xml b/gateway-service-knoxsso/pom.xml
index e6b6ca5..dde32b5 100644
--- a/gateway-service-knoxsso/pom.xml
+++ b/gateway-service-knoxsso/pom.xml
@@ -22,11 +22,11 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-service-knoxsso</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-knoxsso</name>
<url>http://maven.apache.org</url>
<properties>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-knoxssout/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-knoxssout/pom.xml b/gateway-service-knoxssout/pom.xml
index 6b240f0..c99aff1 100644
--- a/gateway-service-knoxssout/pom.xml
+++ b/gateway-service-knoxssout/pom.xml
@@ -22,11 +22,11 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-service-knoxssout</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-knoxssout</name>
<licenses>
<license>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-knoxtoken/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-knoxtoken/pom.xml b/gateway-service-knoxtoken/pom.xml
index e27b7b0..a3e2f28 100644
--- a/gateway-service-knoxtoken/pom.xml
+++ b/gateway-service-knoxtoken/pom.xml
@@ -22,11 +22,11 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-service-knoxtoken</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-knoxtoken</name>
<licenses>
<license>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-nifi/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-nifi/pom.xml b/gateway-service-nifi/pom.xml
index 41d50fb..fbe1c76 100644
--- a/gateway-service-nifi/pom.xml
+++ b/gateway-service-nifi/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-rm/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-rm/pom.xml b/gateway-service-rm/pom.xml
index 3a1f563..6ef52ac 100644
--- a/gateway-service-rm/pom.xml
+++ b/gateway-service-rm/pom.xml
@@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-rm</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-storm/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-storm/pom.xml b/gateway-service-storm/pom.xml
index fde9f00..b683986 100644
--- a/gateway-service-storm/pom.xml
+++ b/gateway-service-storm/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-storm</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-test/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-test/pom.xml b/gateway-service-test/pom.xml
index ba229f9..2e54f8f 100644
--- a/gateway-service-test/pom.xml
+++ b/gateway-service-test/pom.xml
@@ -21,11 +21,11 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway-service-test</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-test</name>
<dependencies>
<dependency>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-tgs/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-tgs/pom.xml b/gateway-service-tgs/pom.xml
index d067674..9010226 100644
--- a/gateway-service-tgs/pom.xml
+++ b/gateway-service-tgs/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-tgs</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-vault/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-vault/pom.xml b/gateway-service-vault/pom.xml
index f181928..af6e7cf 100644
--- a/gateway-service-vault/pom.xml
+++ b/gateway-service-vault/pom.xml
@@ -22,11 +22,11 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway-service-vault</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<name>gateway-service-vault</name>
<url>http://maven.apache.org</url>
<properties>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-service-webhdfs/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-webhdfs/pom.xml b/gateway-service-webhdfs/pom.xml
index 1c018a1..3202aac 100644
--- a/gateway-service-webhdfs/pom.xml
+++ b/gateway-service-webhdfs/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-service-webhdfs</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-shell-launcher/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-shell-launcher/pom.xml b/gateway-shell-launcher/pom.xml
index d577f7b..2fd182f 100644
--- a/gateway-shell-launcher/pom.xml
+++ b/gateway-shell-launcher/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-shell-launcher</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-shell-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-shell-release/pom.xml b/gateway-shell-release/pom.xml
index 1e6c5f8..bbecbe5 100644
--- a/gateway-shell-release/pom.xml
+++ b/gateway-shell-release/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-shell-release</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-shell-samples/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-shell-samples/pom.xml b/gateway-shell-samples/pom.xml
index f667610..6319b95 100644
--- a/gateway-shell-samples/pom.xml
+++ b/gateway-shell-samples/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-shell/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-shell/pom.xml b/gateway-shell/pom.xml
index 101ac32..fff8d63 100644
--- a/gateway-shell/pom.xml
+++ b/gateway-shell/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-shell</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-spi/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-spi/pom.xml b/gateway-spi/pom.xml
index ce7f504..3b77342 100644
--- a/gateway-spi/pom.xml
+++ b/gateway-spi/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-spi</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-test-release-utils/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test-release-utils/pom.xml b/gateway-test-release-utils/pom.xml
index b011e81..24a9996 100644
--- a/gateway-test-release-utils/pom.xml
+++ b/gateway-test-release-utils/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-test-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test-release/pom.xml b/gateway-test-release/pom.xml
index 81ccbe1..e61e0c8 100644
--- a/gateway-test-release/pom.xml
+++ b/gateway-test-release/pom.xml
@@ -22,7 +22,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-test-release</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-test-release/webhdfs-kerb-test/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test-release/webhdfs-kerb-test/pom.xml b/gateway-test-release/webhdfs-kerb-test/pom.xml
index e0126e4..0a30a24 100644
--- a/gateway-test-release/webhdfs-kerb-test/pom.xml
+++ b/gateway-test-release/webhdfs-kerb-test/pom.xml
@@ -22,12 +22,12 @@
<parent>
<artifactId>gateway-test-release</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>webhdfs-kerb-test</artifactId>
<name>webhdfs-kerb-test</name>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<description>Tests for WebHDFS integration with Knox and Kerberos enabled</description>
<build>
<plugins>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-test-release/webhdfs-test/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test-release/webhdfs-test/pom.xml b/gateway-test-release/webhdfs-test/pom.xml
index b55da3a..b8654d5 100644
--- a/gateway-test-release/webhdfs-test/pom.xml
+++ b/gateway-test-release/webhdfs-test/pom.xml
@@ -22,12 +22,12 @@
<parent>
<artifactId>gateway-test-release</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>webhdfs-test</artifactId>
<name>webhdfs-test</name>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<description>Tests for WebHDFS integration with Knox</description>
<build>
<plugins>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-test-utils/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test-utils/pom.xml b/gateway-test-utils/pom.xml
index 4192a35..56b307b 100644
--- a/gateway-test-utils/pom.xml
+++ b/gateway-test-utils/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-test-utils</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-test/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test/pom.xml b/gateway-test/pom.xml
index f8576e6..3b622aa 100644
--- a/gateway-test/pom.xml
+++ b/gateway-test/pom.xml
@@ -22,7 +22,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-test</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-util-common/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-util-common/pom.xml b/gateway-util-common/pom.xml
index f2fb8bf..773384a 100644
--- a/gateway-util-common/pom.xml
+++ b/gateway-util-common/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-util-common</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-util-configinjector/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/pom.xml b/gateway-util-configinjector/pom.xml
index ad46520..7c84d7e 100755
--- a/gateway-util-configinjector/pom.xml
+++ b/gateway-util-configinjector/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-util-configinjector</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-util-launcher/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-util-launcher/pom.xml b/gateway-util-launcher/pom.xml
index 40ae137..2e56153 100644
--- a/gateway-util-launcher/pom.xml
+++ b/gateway-util-launcher/pom.xml
@@ -22,7 +22,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-util-launcher</artifactId>
<name>gateway-util-launcher</name>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/gateway-util-urltemplate/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-util-urltemplate/pom.xml b/gateway-util-urltemplate/pom.xml
index 543313f..b6d56c2 100644
--- a/gateway-util-urltemplate/pom.xml
+++ b/gateway-util-urltemplate/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>gateway-util-urltemplate</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/hadoop-examples/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-examples/pom.xml b/hadoop-examples/pom.xml
index fa0a4cb..fd4c579 100644
--- a/hadoop-examples/pom.xml
+++ b/hadoop-examples/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>hadoop-examples</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/knox-cli-launcher/pom.xml
----------------------------------------------------------------------
diff --git a/knox-cli-launcher/pom.xml b/knox-cli-launcher/pom.xml
index 5d53ea3..2fbef4e 100644
--- a/knox-cli-launcher/pom.xml
+++ b/knox-cli-launcher/pom.xml
@@ -23,7 +23,7 @@
<parent>
<artifactId>gateway</artifactId>
<groupId>org.apache.knox</groupId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>knox-cli-launcher</artifactId>
http://git-wip-us.apache.org/repos/asf/knox/blob/d4b0dc60/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 69c8115..51ff1a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
</parent>
<groupId>org.apache.knox</groupId>
<artifactId>gateway</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>gateway</name>
@@ -108,7 +108,7 @@
<gateway-name>Apache Knox</gateway-name>
<gateway-project>knox</gateway-project>
<gateway-artifact>knox</gateway-artifact>
- <gateway-version>0.14.0-SNAPSHOT</gateway-version>
+ <gateway-version>1.0.0-SNAPSHOT</gateway-version>
<gateway-group>org.apache.knox</gateway-group>
<groovy-version>2.4.6</groovy-version>
<hadoop-version>2.7.3</hadoop-version>
[06/16] knox git commit: KNOX-970 - add NiFi HA dispatch to service
def (Jeff Storck via lmccay)
Posted by mo...@apache.org.
KNOX-970 - add NiFi HA dispatch to service def (Jeff Storck via lmccay)
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/6b250b19
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/6b250b19
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/6b250b19
Branch: refs/heads/KNOX-998-Package_Restructuring
Commit: 6b250b1930235e0eff526c1c787a2680207ae150
Parents: 89dd778
Author: Larry McCay <lm...@hortonworks.com>
Authored: Mon Nov 6 17:47:17 2017 -0500
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Mon Nov 6 17:59:49 2017 -0500
----------------------------------------------------------------------
.../src/main/resources/services/nifi/1.4.0/service.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/6b250b19/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
----------------------------------------------------------------------
diff --git a/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
index fb24598..2ccc10d 100644
--- a/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
+++ b/gateway-service-definitions/src/main/resources/services/nifi/1.4.0/service.xml
@@ -26,5 +26,5 @@
<rewrite apply="NIFI/nifi/inbound/path/query-other" to="request.url"/>
</route>
</routes>
- <dispatch classname="org.apache.hadoop.gateway.dispatch.NiFiDispatch" use-two-way-ssl="false"/>
+ <dispatch classname="org.apache.hadoop.gateway.dispatch.NiFiDispatch" ha-classname="org.apache.hadoop.gateway.dispatch.NiFiHaDispatch" />
</service>
[13/16] knox git commit: Merge branch 'master' into
KNOX-998-Package_Restructuring
Posted by mo...@apache.org.
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
----------------------------------------------------------------------
diff --cc gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
index a0035fc,0000000..9ecd7fc
mode 100644,000000..100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
@@@ -1,657 -1,0 +1,674 @@@
+/**
+ * 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.knox.gateway.service.admin;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.knox.gateway.i18n.GatewaySpiMessages;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.service.admin.beans.BeanConverter;
+import org.apache.knox.gateway.service.admin.beans.Topology;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.topology.TopologyService;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+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 java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
+
+import static javax.ws.rs.core.Response.ok;
+import static javax.ws.rs.core.Response.created;
+import static javax.ws.rs.core.Response.notModified;
+import static javax.ws.rs.core.Response.status;
+
+
+@Path("/api/v1")
+public class TopologiesResource {
+
+ private static final String XML_EXT = ".xml";
+ private static final String JSON_EXT = ".json";
+
+ private static final String TOPOLOGIES_API_PATH = "topologies";
+ private static final String SINGLE_TOPOLOGY_API_PATH = TOPOLOGIES_API_PATH + "/{id}";
+ private static final String PROVIDERCONFIG_API_PATH = "providerconfig";
+ private static final String SINGLE_PROVIDERCONFIG_API_PATH = PROVIDERCONFIG_API_PATH + "/{name}";
+ private static final String DESCRIPTORS_API_PATH = "descriptors";
+ private static final String SINGLE_DESCRIPTOR_API_PATH = DESCRIPTORS_API_PATH + "/{name}";
+
+ private static GatewaySpiMessages log = MessagesFactory.get(GatewaySpiMessages.class);
+
+ @Context
+ private HttpServletRequest request;
+
+ @GET
+ @Produces({APPLICATION_JSON, APPLICATION_XML})
+ @Path(SINGLE_TOPOLOGY_API_PATH)
+ public Topology getTopology(@PathParam("id") String id) {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ for (org.apache.knox.gateway.topology.Topology t : ts.getTopologies()) {
+ if(t.getName().equals(id)) {
+ try {
+ t.setUri(new URI( buildURI(t, config, request) ));
+ } catch (URISyntaxException se) {
+ t.setUri(null);
+ }
+ return BeanConverter.getTopology(t);
+ }
+ }
+ return null;
+ }
+
+ @GET
+ @Produces({APPLICATION_JSON, APPLICATION_XML})
+ @Path(TOPOLOGIES_API_PATH)
+ public SimpleTopologyWrapper getTopologies() {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ ArrayList<SimpleTopology> st = new ArrayList<SimpleTopology>();
+ GatewayConfig conf = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+
+ for (org.apache.knox.gateway.topology.Topology t : ts.getTopologies()) {
+ st.add(getSimpleTopology(t, conf));
+ }
+
+ Collections.sort(st, new TopologyComparator());
+ SimpleTopologyWrapper stw = new SimpleTopologyWrapper();
+
+ for(SimpleTopology t : st){
+ stw.topologies.add(t);
+ }
+
+ return stw;
+
+ }
+
+ @PUT
+ @Consumes({APPLICATION_JSON, APPLICATION_XML})
+ @Path(SINGLE_TOPOLOGY_API_PATH)
+ public Topology uploadTopology(@PathParam("id") String id, Topology t) {
++ Topology result = null;
+
- GatewayServices gs = (GatewayServices) request.getServletContext()
- .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
++ GatewayServices gs =
++ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ t.setName(id);
+ TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
+
- ts.deployTopology(BeanConverter.getTopology(t));
++ // Check for existing topology with the same name, to see if it had been generated
++ boolean existingGenerated = false;
++ for (org.apache.hadoop.gateway.topology.Topology existingTopology : ts.getTopologies()) {
++ if(existingTopology.getName().equals(id)) {
++ existingGenerated = existingTopology.isGenerated();
++ break;
++ }
++ }
++
++ // If a topology with the same ID exists, which had been generated, then DO NOT overwrite it because it will be
++ // out of sync with the source descriptor. Otherwise, deploy the updated version.
++ if (!existingGenerated) {
++ ts.deployTopology(BeanConverter.getTopology(t));
++ result = getTopology(id);
++ } else {
++ log.disallowedOverwritingGeneratedTopology(id);
++ }
+
- return getTopology(id);
++ return result;
+ }
+
+ @DELETE
+ @Produces(APPLICATION_JSON)
+ @Path(SINGLE_TOPOLOGY_API_PATH)
+ public Response deleteTopology(@PathParam("id") String id) {
+ boolean deleted = false;
+ if(!"admin".equals(id)) {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ for (org.apache.knox.gateway.topology.Topology t : ts.getTopologies()) {
+ if(t.getName().equals(id)) {
+ ts.deleteTopology(t);
+ deleted = true;
+ }
+ }
+ }else{
+ deleted = false;
+ }
+ return ok().entity("{ \"deleted\" : " + deleted + " }").build();
+ }
+
+ @GET
+ @Produces({APPLICATION_JSON})
+ @Path(PROVIDERCONFIG_API_PATH)
+ public HrefListing getProviderConfigurations() {
+ HrefListing listing = new HrefListing();
+ listing.setHref(buildHref(request));
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ List<HrefListItem> configs = new ArrayList<>();
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ // Get all the simple descriptor file names
+ for (File providerConfig : ts.getProviderConfigurations()){
+ String id = FilenameUtils.getBaseName(providerConfig.getName());
+ configs.add(new HrefListItem(buildHref(id, request), providerConfig.getName()));
+ }
+
+ listing.setItems(configs);
+ return listing;
+ }
+
+ @GET
+ @Produces({APPLICATION_XML})
+ @Path(SINGLE_PROVIDERCONFIG_API_PATH)
+ public Response getProviderConfiguration(@PathParam("name") String name) {
+ Response response;
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ File providerConfigFile = null;
+
+ for (File pc : ts.getProviderConfigurations()){
+ // If the file name matches the specified id
+ if (FilenameUtils.getBaseName(pc.getName()).equals(name)) {
+ providerConfigFile = pc;
+ break;
+ }
+ }
+
+ if (providerConfigFile != null) {
+ byte[] content = null;
+ try {
+ content = FileUtils.readFileToByteArray(providerConfigFile);
+ response = ok().entity(content).build();
+ } catch (IOException e) {
+ log.failedToReadConfigurationFile(providerConfigFile.getAbsolutePath(), e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+ }
+
+ } else {
+ response = Response.status(Response.Status.NOT_FOUND).build();
+ }
+ return response;
+ }
+
+ @DELETE
+ @Produces(APPLICATION_JSON)
+ @Path(SINGLE_PROVIDERCONFIG_API_PATH)
+ public Response deleteProviderConfiguration(@PathParam("name") String name) {
+ Response response;
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ if (ts.deleteProviderConfiguration(name)) {
+ response = ok().entity("{ \"deleted\" : \"provider config " + name + "\" }").build();
+ } else {
+ response = notModified().build();
+ }
+ return response;
+ }
+
+
+ @DELETE
+ @Produces(APPLICATION_JSON)
+ @Path(SINGLE_DESCRIPTOR_API_PATH)
+ public Response deleteSimpleDescriptor(@PathParam("name") String name) {
+ Response response = null;
+ if(!"admin".equals(name)) {
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ if (ts.deleteDescriptor(name)) {
+ response = ok().entity("{ \"deleted\" : \"descriptor " + name + "\" }").build();
+ }
+ }
+
+ if (response == null) {
+ response = notModified().build();
+ }
+
+ return response;
+ }
+
+
+ @PUT
+ @Consumes({APPLICATION_XML})
+ @Path(SINGLE_PROVIDERCONFIG_API_PATH)
+ public Response uploadProviderConfiguration(@PathParam("name") String name, String content) {
+ Response response = null;
+
+ GatewayServices gs =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ boolean isUpdate = configFileExists(ts.getProviderConfigurations(), name);
+
+ String filename = name.endsWith(XML_EXT) ? name : name + XML_EXT;
+ if (ts.deployProviderConfiguration(filename, content)) {
+ try {
+ if (isUpdate) {
+ response = Response.noContent().build();
+ } else{
+ response = created(new URI(buildHref(request))).build();
+ }
+ } catch (URISyntaxException e) {
+ log.invalidResourceURI(e.getInput(), e.getReason(), e);
+ response = status(Response.Status.BAD_REQUEST).entity("{ \"error\" : \"Failed to deploy provider configuration " + name + "\" }").build();
+ }
+ }
+
+ return response;
+ }
+
+
+ private boolean configFileExists(Collection<File> existing, String candidateName) {
+ boolean result = false;
+ for (File exists : existing) {
+ if (FilenameUtils.getBaseName(exists.getName()).equals(candidateName)) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+
+ @PUT
+ @Consumes({APPLICATION_JSON})
+ @Path(SINGLE_DESCRIPTOR_API_PATH)
+ public Response uploadSimpleDescriptor(@PathParam("name") String name, String content) {
+ Response response = null;
+
+ GatewayServices gs =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ boolean isUpdate = configFileExists(ts.getDescriptors(), name);
+
+ String filename = name.endsWith(JSON_EXT) ? name : name + JSON_EXT;
+ if (ts.deployDescriptor(filename, content)) {
+ try {
+ if (isUpdate) {
+ response = Response.noContent().build();
+ } else {
+ response = created(new URI(buildHref(request))).build();
+ }
+ } catch (URISyntaxException e) {
+ log.invalidResourceURI(e.getInput(), e.getReason(), e);
+ response = status(Response.Status.BAD_REQUEST).entity("{ \"error\" : \"Failed to deploy descriptor " + name + "\" }").build();
+ }
+ }
+
+ return response;
+ }
+
+
+ @GET
+ @Produces({APPLICATION_JSON})
+ @Path(DESCRIPTORS_API_PATH)
+ public HrefListing getSimpleDescriptors() {
+ HrefListing listing = new HrefListing();
+ listing.setHref(buildHref(request));
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ List<HrefListItem> descriptors = new ArrayList<>();
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ for (File descriptor : ts.getDescriptors()){
+ String id = FilenameUtils.getBaseName(descriptor.getName());
+ descriptors.add(new HrefListItem(buildHref(id, request), descriptor.getName()));
+ }
+
+ listing.setItems(descriptors);
+ return listing;
+ }
+
+
+ @GET
+ @Produces({APPLICATION_JSON, TEXT_PLAIN})
+ @Path(SINGLE_DESCRIPTOR_API_PATH)
+ public Response getSimpleDescriptor(@PathParam("name") String name) {
+ Response response;
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ File descriptorFile = null;
+
+ for (File sd : ts.getDescriptors()){
+ // If the file name matches the specified id
+ if (FilenameUtils.getBaseName(sd.getName()).equals(name)) {
+ descriptorFile = sd;
+ break;
+ }
+ }
+
+ if (descriptorFile != null) {
+ String mediaType = APPLICATION_JSON;
+
+ byte[] content = null;
+ try {
+ if ("yml".equals(FilenameUtils.getExtension(descriptorFile.getName()))) {
+ mediaType = TEXT_PLAIN;
+ }
+ content = FileUtils.readFileToByteArray(descriptorFile);
+ response = ok().type(mediaType).entity(content).build();
+ } catch (IOException e) {
+ log.failedToReadConfigurationFile(descriptorFile.getAbsolutePath(), e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+ }
+ } else {
+ response = Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ return response;
+ }
+
+
+ private static class TopologyComparator implements Comparator<SimpleTopology> {
+ @Override
+ public int compare(SimpleTopology t1, SimpleTopology t2) {
+ return t1.getName().compareTo(t2.getName());
+ }
+ }
+
+
+ String buildURI(org.apache.knox.gateway.topology.Topology topology, GatewayConfig config, HttpServletRequest req){
+ String uri = buildXForwardBaseURL(req);
+
+ // Strip extra context
+ uri = uri.replace(req.getContextPath(), "");
+
+ // Add the gateway path
+ String gatewayPath;
+ if(config.getGatewayPath() != null){
+ gatewayPath = config.getGatewayPath();
+ }else{
+ gatewayPath = "gateway";
+ }
+ uri += "/" + gatewayPath;
+
+ uri += "/" + topology.getName();
+ return uri;
+ }
+
+ String buildHref(HttpServletRequest req) {
+ return buildHref((String)null, req);
+ }
+
+ String buildHref(String id, HttpServletRequest req) {
+ String href = buildXForwardBaseURL(req);
+ // Make sure that the pathInfo doesn't have any '/' chars at the end.
+ String pathInfo = req.getPathInfo();
+ while(pathInfo.endsWith("/")) {
+ pathInfo = pathInfo.substring(0, pathInfo.length() - 1);
+ }
+
+ href += pathInfo;
+
+ if (id != null) {
+ href += "/" + id;
+ }
+
+ return href;
+ }
+
+ String buildHref(org.apache.knox.gateway.topology.Topology t, HttpServletRequest req) {
+ return buildHref(t.getName(), req);
+ }
+
+ private SimpleTopology getSimpleTopology(org.apache.knox.gateway.topology.Topology t, GatewayConfig config) {
+ String uri = buildURI(t, config, request);
+ String href = buildHref(t, request);
+ return new SimpleTopology(t, uri, href);
+ }
+
+ private String buildXForwardBaseURL(HttpServletRequest req){
+ final String X_Forwarded = "X-Forwarded-";
+ final String X_Forwarded_Context = X_Forwarded + "Context";
+ final String X_Forwarded_Proto = X_Forwarded + "Proto";
+ final String X_Forwarded_Host = X_Forwarded + "Host";
+ final String X_Forwarded_Port = X_Forwarded + "Port";
+ final String X_Forwarded_Server = X_Forwarded + "Server";
+
+ String baseURL = "";
+
+ // Get Protocol
+ if(req.getHeader(X_Forwarded_Proto) != null){
+ baseURL += req.getHeader(X_Forwarded_Proto) + "://";
+ } else {
+ baseURL += req.getProtocol() + "://";
+ }
+
+ // Handle Server/Host and Port Here
+ if (req.getHeader(X_Forwarded_Host) != null && req.getHeader(X_Forwarded_Port) != null){
+ // Double check to see if host has port
+ if(req.getHeader(X_Forwarded_Host).contains(req.getHeader(X_Forwarded_Port))){
+ baseURL += req.getHeader(X_Forwarded_Host);
+ } else {
+ // If there's no port, add the host and port together;
+ baseURL += req.getHeader(X_Forwarded_Host) + ":" + req.getHeader(X_Forwarded_Port);
+ }
+ } else if(req.getHeader(X_Forwarded_Server) != null && req.getHeader(X_Forwarded_Port) != null){
+ // Tack on the server and port if they're available. Try host if server not available
+ baseURL += req.getHeader(X_Forwarded_Server) + ":" + req.getHeader(X_Forwarded_Port);
+ } else if(req.getHeader(X_Forwarded_Port) != null) {
+ // if we at least have a port, we can use it.
+ baseURL += req.getServerName() + ":" + req.getHeader(X_Forwarded_Port);
+ } else {
+ // Resort to request members
+ baseURL += req.getServerName() + ":" + req.getLocalPort();
+ }
+
+ // Handle Server context
+ if( req.getHeader(X_Forwarded_Context) != null ) {
+ baseURL += req.getHeader( X_Forwarded_Context );
+ } else {
+ baseURL += req.getContextPath();
+ }
+
+ return baseURL;
+ }
+
+
+ static class HrefListing {
+ @JsonProperty
+ String href;
+
+ @JsonProperty
+ List<HrefListItem> items;
+
+ HrefListing() {}
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setItems(List<HrefListItem> items) {
+ this.items = items;
+ }
+
+ public List<HrefListItem> getItems() {
+ return items;
+ }
+ }
+
+ static class HrefListItem {
+ @JsonProperty
+ String href;
+
+ @JsonProperty
+ String name;
+
+ HrefListItem() {}
+
+ HrefListItem(String href, String name) {
+ this.href = href;
+ this.name = name;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getName() {
+ return name;
+ }
+ }
+
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ public static class SimpleTopology {
+
+ @XmlElement
+ private String name;
+ @XmlElement
+ private String timestamp;
+ @XmlElement
+ private String defaultServicePath;
+ @XmlElement
+ private String uri;
+ @XmlElement
+ private String href;
+
+ public SimpleTopology() {}
+
+ public SimpleTopology(org.apache.knox.gateway.topology.Topology t, String uri, String href) {
+ this.name = t.getName();
+ this.timestamp = Long.toString(t.getTimestamp());
+ this.defaultServicePath = t.getDefaultServicePath();
+ this.uri = uri;
+ this.href = href;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String n) {
+ name = n;
+ }
+
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setDefaultService(String defaultServicePath) {
+ this.defaultServicePath = defaultServicePath;
+ }
+
+ public String getDefaultService() {
+ return defaultServicePath;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class SimpleTopologyWrapper{
+
+ @XmlElement(name="topology")
+ @XmlElementWrapper(name="topologies")
+ private List<SimpleTopology> topologies = new ArrayList<SimpleTopology>();
+
+ public List<SimpleTopology> getTopologies(){
+ return topologies;
+ }
+
+ public void setTopologies(List<SimpleTopology> ts){
+ this.topologies = ts;
+ }
+
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
----------------------------------------------------------------------
diff --cc gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
index e8d6915,0000000..e916568
mode 100644,000000..100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
@@@ -1,170 -1,0 +1,172 @@@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.service.admin.beans;
+
+import org.apache.knox.gateway.topology.Version;
+
+import java.util.Collection;
+
+public class BeanConverter {
+
+ public static Topology getTopology(
+ org.apache.knox.gateway.topology.Topology topology) {
+ Topology topologyResource = new Topology();
+ topologyResource.setName(topology.getName());
+ topologyResource.setTimestamp(topology.getTimestamp());
+ topologyResource.setPath(topology.getDefaultServicePath());
+ topologyResource.setUri(topology.getUri());
++ topologyResource.setGenerated(topology.isGenerated());
+ for ( org.apache.knox.gateway.topology.Provider provider : topology.getProviders() ) {
+ topologyResource.getProviders().add( getProvider(provider) );
+ }
+ for ( org.apache.knox.gateway.topology.Service service : topology.getServices() ) {
+ topologyResource.getServices().add( getService(service) );
+ }
+ for ( org.apache.knox.gateway.topology.Application application : topology.getApplications() ) {
+ topologyResource.getApplications().add( getApplication(application) );
+ }
+ return topologyResource;
+ }
+
+ public static org.apache.knox.gateway.topology.Topology getTopology(Topology topology) {
+ org.apache.knox.gateway.topology.Topology deploymentTopology = new org.apache.knox.gateway.topology.Topology();
+ deploymentTopology.setName(topology.getName());
+ deploymentTopology.setTimestamp(topology.getTimestamp());
+ deploymentTopology.setDefaultServicePath(topology.getPath());
+ deploymentTopology.setUri(topology.getUri());
++ deploymentTopology.setGenerated(topology.isGenerated());
+ for ( Provider provider : topology.getProviders() ) {
+ deploymentTopology.addProvider( getProvider(provider) );
+ }
+ for ( Service service : topology.getServices() ) {
+ deploymentTopology.addService( getService(service) );
+ }
+ for ( Application application : topology.getApplications() ) {
+ deploymentTopology.addApplication( getApplication(application) );
+ }
+ return deploymentTopology;
+ }
+
+ private static Provider getProvider(
+ org.apache.knox.gateway.topology.Provider provider) {
+ Provider providerResource = new Provider();
+ providerResource.setName(provider.getName());
+ providerResource.setEnabled(provider.isEnabled());
+ providerResource.setRole(provider.getRole());
+ Collection<org.apache.knox.gateway.topology.Param> paramsList = provider.getParamsList();
+ if (paramsList != null && !paramsList.isEmpty()) {
+ for ( org.apache.knox.gateway.topology.Param param : paramsList ) {
+ providerResource.getParams().add(getParam(param));
+ }
+ }
+ return providerResource;
+ }
+
+ private static org.apache.knox.gateway.topology.Provider getProvider(Provider provider) {
+ org.apache.knox.gateway.topology.Provider deploymentProvider = new org.apache.knox.gateway.topology.Provider();
+ deploymentProvider.setName(provider.getName());
+ deploymentProvider.setEnabled(provider.isEnabled());
+ deploymentProvider.setRole(provider.getRole());
+ for ( Param param : provider.getParams() ) {
+ deploymentProvider.addParam( getParam(param) );
+ }
+ return deploymentProvider;
+ }
+
+ private static Service getService(
+ org.apache.knox.gateway.topology.Service service) {
+ Service serviceResource = new Service();
+ serviceResource.setRole(service.getRole());
+ serviceResource.setName(service.getName());
+ Version version = service.getVersion();
+ if (version != null) {
+ serviceResource.setVersion(version.toString());
+ }
+ Collection<org.apache.knox.gateway.topology.Param> paramsList = service.getParamsList();
+ if (paramsList != null && !paramsList.isEmpty()) {
+ for ( org.apache.knox.gateway.topology.Param param : paramsList ) {
+ serviceResource.getParams().add(getParam(param));
+ }
+ }
+ for ( String url : service.getUrls() ) {
+ serviceResource.getUrls().add( url );
+ }
+ return serviceResource;
+ }
+
+ private static org.apache.knox.gateway.topology.Service getService(Service service) {
+ org.apache.knox.gateway.topology.Service deploymentService = new org.apache.knox.gateway.topology.Service();
+ deploymentService.setRole(service.getRole());
+ deploymentService.setName(service.getName());
+ if (service.getVersion() != null) {
+ deploymentService.setVersion(new Version(service.getVersion()));
+ }
+ for ( Param param : service.getParams() ) {
+ deploymentService.addParam( getParam(param) );
+ }
+ for ( String url : service.getUrls() ) {
+ deploymentService.addUrl( url );
+ }
+ return deploymentService;
+ }
+
+ private static Application getApplication(
+ org.apache.knox.gateway.topology.Application application) {
+ Application applicationResource = new Application();
+ applicationResource.setRole(application.getRole());
+ applicationResource.setName(application.getName());
+ Version version = application.getVersion();
+ if (version != null) {
+ applicationResource.setVersion(version.toString());
+ }
+ Collection<org.apache.knox.gateway.topology.Param> paramsList = application.getParamsList();
+ if (paramsList != null && !paramsList.isEmpty()) {
+ for ( org.apache.knox.gateway.topology.Param param : paramsList ) {
+ applicationResource.getParams().add(getParam(param));
+ }
+ }
+ for ( String url : application.getUrls() ) {
+ applicationResource.getUrls().add( url );
+ }
+ return applicationResource;
+ }
+
+ private static org.apache.knox.gateway.topology.Application getApplication(Application application) {
+ org.apache.knox.gateway.topology.Application applicationResource = new org.apache.knox.gateway.topology.Application();
+ applicationResource.setRole(application.getRole());
+ applicationResource.setName(application.getName());
+ if (application.getVersion() != null) {
+ applicationResource.setVersion(new Version(application.getVersion()));
+ }
+ for ( Param param : application.getParams() ) {
+ applicationResource.addParam( getParam(param) );
+ }
+ for ( String url : application.getUrls() ) {
+ applicationResource.getUrls().add( url );
+ }
+ return applicationResource;
+ }
+
+ private static Param getParam(org.apache.knox.gateway.topology.Param param) {
+ return new Param(param.getName(), param.getValue());
+ }
+
+ private static org.apache.knox.gateway.topology.Param getParam(Param param) {
+ return new org.apache.knox.gateway.topology.Param(param.getName(), param.getValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
----------------------------------------------------------------------
diff --cc gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
index 2d2eab8,0000000..e1a8279
mode 100644,000000..100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
@@@ -1,119 -1,0 +1,130 @@@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.knox.gateway.service.admin.beans;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+@XmlRootElement(name="topology")
+public class Topology {
+
+ @XmlElement
+ private URI uri;
+
+ @XmlElement
+ private String name;
+
+ @XmlElement
+ private String path;
+
+ @XmlElement
+ private long timestamp;
+
++ @XmlElement(name="generated")
++ private boolean isGenerated;
++
+ @XmlElement(name="provider")
+ @XmlElementWrapper(name="gateway")
+ public List<Provider> providers;
+
+ @XmlElement(name="service")
+ public List<Service> services;
+
+ @XmlElement(name="application")
+ private List<Application> applications;
+
+ public Topology() {
+ }
+
+ public URI getUri() {
+ return uri;
+ }
+
+ public void setUri( URI uri ) {
+ this.uri = uri;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setPath( String defaultServicePath ) {
+ this.path = defaultServicePath;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setTimestamp( long timestamp ) {
+ this.timestamp = timestamp;
+ }
+
++ public boolean isGenerated() {
++ return isGenerated;
++ }
++
++ public void setGenerated(boolean isGenerated) {
++ this.isGenerated = isGenerated;
++ }
++
+ public List<Service> getServices() {
+ if (services == null) {
+ services = new ArrayList<>();
+ }
+ return services;
+ }
+
+ public List<Application> getApplications() {
+ if (applications == null) {
+ applications = new ArrayList<>();
+ }
+ return applications;
+ }
+
+ public List<Provider> getProviders() {
+ if (providers == null) {
+ providers = new ArrayList<>();
+ }
+ return providers;
+ }
+
+ public void setProviders(List<Provider> providers) {
+ this.providers = providers;
+ }
+
+ public void setServices(List<Service> services) {
+ this.services = services;
+ }
+
+ public void setApplications(List<Application> applications) {
+ this.applications = applications;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
----------------------------------------------------------------------
diff --cc gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
index 3fe81e8,0000000..ac82b39
mode 100644,000000..100644
--- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
+++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
@@@ -1,80 -1,0 +1,91 @@@
+/**
+ * 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.knox.gateway.service.definition;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType(name = "dispatch")
+public class CustomDispatch {
+
+ private String contributorName;
+
+ private String haContributorName;
+
+ private String className;
+
+ private String haClassName;
+
+ private String httpClientFactory;
+
++ private boolean useTwoWaySsl = false;
++
+ @XmlAttribute(name = "contributor-name")
+ public String getContributorName() {
+ return contributorName;
+ }
+
+ public void setContributorName(String contributorName) {
+ this.contributorName = contributorName;
+ }
+
+ @XmlAttribute(name = "ha-contributor-name")
+ public String getHaContributorName() {
+ return haContributorName;
+ }
+
+ public void setHaContributorName(String haContributorName) {
+ this.haContributorName = haContributorName;
+ }
+
+ @XmlAttribute(name = "classname")
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ @XmlAttribute(name = "ha-classname")
+ public String getHaClassName() {
+ return haClassName;
+ }
+
+ public void setHaClassName(String haContributorClassName) {
+ this.haClassName = haContributorClassName;
+ }
+
+ @XmlAttribute(name = "http-client-factory")
+ public String getHttpClientFactory() {
+ return httpClientFactory;
+ }
+
+ public void setHttpClientFactory(String httpClientFactory) {
+ this.httpClientFactory = httpClientFactory;
+ }
++
++ @XmlAttribute(name = "use-two-way-ssl")
++ public boolean getUseTwoWaySsl() {
++ return useTwoWaySsl;
++ }
++
++ public void setUseTwoWaySsl(boolean useTwoWaySsl) {
++ this.useTwoWaySsl = useTwoWaySsl;
++ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-shell-launcher/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-shell-release/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
index e822364,0000000..dcb7465
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
@@@ -1,233 -1,0 +1,270 @@@
+/**
+ * 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.knox.gateway.dispatch;
+
++import java.io.IOException;
++import java.security.KeyStore;
++import java.security.Principal;
++import java.util.Collections;
++import java.util.Date;
++import java.util.List;
++
++import javax.net.ssl.SSLContext;
++import javax.servlet.FilterConfig;
++
++import org.apache.knox.gateway.services.security.AliasService;
++import org.apache.knox.gateway.services.security.AliasServiceException;
++import org.apache.knox.gateway.services.security.KeystoreService;
++import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.metrics.MetricsService;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.ProtocolException;
+import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.RedirectStrategy;
+import org.apache.http.client.config.AuthSchemes;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
++import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
++import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.protocol.HttpContext;
++import org.apache.http.ssl.SSLContexts;
+import org.joda.time.Period;
+import org.joda.time.format.PeriodFormatter;
+import org.joda.time.format.PeriodFormatterBuilder;
+
- import javax.servlet.FilterConfig;
- import java.io.IOException;
- import java.security.Principal;
- import java.util.Collections;
- import java.util.Date;
- import java.util.List;
-
+public class DefaultHttpClientFactory implements HttpClientFactory {
+
+ @Override
+ public HttpClient createHttpClient(FilterConfig filterConfig) {
+ HttpClientBuilder builder = null;
+ GatewayConfig gatewayConfig = (GatewayConfig) filterConfig.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
++ GatewayServices services = (GatewayServices) filterConfig.getServletContext()
++ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ if (gatewayConfig != null && gatewayConfig.isMetricsEnabled()) {
- GatewayServices services = (GatewayServices) filterConfig.getServletContext()
- .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ MetricsService metricsService = services.getService(GatewayServices.METRICS_SERVICE);
+ builder = metricsService.getInstrumented(HttpClientBuilder.class);
+ } else {
+ builder = HttpClients.custom();
+ }
++ if (Boolean.parseBoolean(filterConfig.getInitParameter("useTwoWaySsl"))) {
++ char[] keypass = null;
++ MasterService ms = services.getService("MasterService");
++ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
++ try {
++ keypass = as.getGatewayIdentityPassphrase();
++ } catch (AliasServiceException e) {
++ // nop - default passphrase will be used
++ }
++ if (keypass == null) {
++ // there has been no alias created for the key - let's assume it is the same as the keystore password
++ keypass = ms.getMasterSecret();
++ }
++
++ KeystoreService ks = services.getService(GatewayServices.KEYSTORE_SERVICE);
++ final SSLContext sslcontext;
++ try {
++ KeyStore keystoreForGateway = ks.getKeystoreForGateway();
++ sslcontext = SSLContexts.custom()
++ .loadTrustMaterial(keystoreForGateway, new TrustSelfSignedStrategy())
++ .loadKeyMaterial(keystoreForGateway, keypass)
++ .build();
++ } catch (Exception e) {
++ throw new IllegalArgumentException("Unable to create SSLContext", e);
++ }
++ builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext));
++ }
+ if ( "true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED)) ) {
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(AuthScope.ANY, new UseJaasCredentials());
+
+ Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
+ .register(AuthSchemes.SPNEGO, new KnoxSpnegoAuthSchemeFactory(true))
+ .build();
+
+ builder = builder.setDefaultAuthSchemeRegistry(authSchemeRegistry)
+ .setDefaultCookieStore(new HadoopAuthCookieStore())
+ .setDefaultCredentialsProvider(credentialsProvider);
+ } else {
+ builder = builder.setDefaultCookieStore(new NoCookieStore());
+ }
+
+ builder.setKeepAliveStrategy( DefaultConnectionKeepAliveStrategy.INSTANCE );
+ builder.setConnectionReuseStrategy( DefaultConnectionReuseStrategy.INSTANCE );
+ builder.setRedirectStrategy( new NeverRedirectStrategy() );
+ builder.setRetryHandler( new NeverRetryHandler() );
+
+ int maxConnections = getMaxConnections( filterConfig );
+ builder.setMaxConnTotal( maxConnections );
+ builder.setMaxConnPerRoute( maxConnections );
+
+ builder.setDefaultRequestConfig( getRequestConfig( filterConfig ) );
+
+ HttpClient client = builder.build();
+ return client;
+ }
+
+ private static RequestConfig getRequestConfig( FilterConfig config ) {
+ RequestConfig.Builder builder = RequestConfig.custom();
+ int connectionTimeout = getConnectionTimeout( config );
+ if ( connectionTimeout != -1 ) {
+ builder.setConnectTimeout( connectionTimeout );
+ builder.setConnectionRequestTimeout( connectionTimeout );
+ }
+ int socketTimeout = getSocketTimeout( config );
+ if( socketTimeout != -1 ) {
+ builder.setSocketTimeout( socketTimeout );
+ }
+ return builder.build();
+ }
+
+ private static class NoCookieStore implements CookieStore {
+ @Override
+ public void addCookie(Cookie cookie) {
+ //no op
+ }
+
+ @Override
+ public List<Cookie> getCookies() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean clearExpired(Date date) {
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ //no op
+ }
+ }
+
+ private static class NeverRedirectStrategy implements RedirectStrategy {
+ @Override
+ public boolean isRedirected( HttpRequest request, HttpResponse response, HttpContext context )
+ throws ProtocolException {
+ return false;
+ }
+
+ @Override
+ public HttpUriRequest getRedirect( HttpRequest request, HttpResponse response, HttpContext context )
+ throws ProtocolException {
+ return null;
+ }
+ }
+
+ private static class NeverRetryHandler implements HttpRequestRetryHandler {
+ @Override
+ public boolean retryRequest( IOException exception, int executionCount, HttpContext context ) {
+ return false;
+ }
+ }
+
+ private static class UseJaasCredentials implements Credentials {
+
+ public String getPassword() {
+ return null;
+ }
+
+ public Principal getUserPrincipal() {
+ return null;
+ }
+
+ }
+
+ private int getMaxConnections( FilterConfig filterConfig ) {
+ int maxConnections = 32;
+ GatewayConfig config =
+ (GatewayConfig)filterConfig.getServletContext().getAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE );
+ if( config != null ) {
+ maxConnections = config.getHttpClientMaxConnections();
+ }
+ String str = filterConfig.getInitParameter( "httpclient.maxConnections" );
+ if( str != null ) {
+ try {
+ maxConnections = Integer.parseInt( str );
+ } catch ( NumberFormatException e ) {
+ // Ignore it and use the default.
+ }
+ }
+ return maxConnections;
+ }
+
+ private static int getConnectionTimeout( FilterConfig filterConfig ) {
+ int timeout = -1;
+ GatewayConfig globalConfig =
+ (GatewayConfig)filterConfig.getServletContext().getAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE );
+ if( globalConfig != null ) {
+ timeout = globalConfig.getHttpClientConnectionTimeout();
+ }
+ String str = filterConfig.getInitParameter( "httpclient.connectionTimeout" );
+ if( str != null ) {
+ try {
+ timeout = (int)parseTimeout( str );
+ } catch ( Exception e ) {
+ // Ignore it and use the default.
+ }
+ }
+ return timeout;
+ }
+
+ private static int getSocketTimeout( FilterConfig filterConfig ) {
+ int timeout = -1;
+ GatewayConfig globalConfig =
+ (GatewayConfig)filterConfig.getServletContext().getAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE );
+ if( globalConfig != null ) {
+ timeout = globalConfig.getHttpClientSocketTimeout();
+ }
+ String str = filterConfig.getInitParameter( "httpclient.socketTimeout" );
+ if( str != null ) {
+ try {
+ timeout = (int)parseTimeout( str );
+ } catch ( Exception e ) {
+ // Ignore it and use the default.
+ }
+ }
+ return timeout;
+ }
+
+ private static long parseTimeout( String s ) {
+ PeriodFormatter f = new PeriodFormatterBuilder()
+ .appendMinutes().appendSuffix("m"," min")
+ .appendSeconds().appendSuffix("s"," sec")
+ .appendMillis().toFormatter();
+ Period p = Period.parse( s, f );
+ return p.toStandardDuration().getMillis();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
index 27a1905,0000000..42d69d9
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
@@@ -1,91 -1,0 +1,94 @@@
+/**
+ * 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.knox.gateway.i18n;
+
+import org.apache.knox.gateway.i18n.messages.Message;
+import org.apache.knox.gateway.i18n.messages.MessageLevel;
+import org.apache.knox.gateway.i18n.messages.Messages;
+import org.apache.knox.gateway.i18n.messages.StackTrace;
+
+@Messages(logger="org.apache.knox.gateway")
+public interface GatewaySpiMessages {
+
+ @Message(level = MessageLevel.ERROR, text = "Failed to load the internal principal mapping table: {0}" )
+ void failedToLoadPrincipalMappingTable( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to execute filter: {0}" )
+ void failedToExecuteFilter( @StackTrace( level = MessageLevel.DEBUG ) Throwable t );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to encrypt passphrase: {0}" )
+ void failedToEncryptPassphrase( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to generate secret key from password: {0}" )
+ void failedToGenerateKeyFromPassword( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to create keystore [filename={0}, type={1}]: {2}" )
+ void failedToCreateKeystore( String fileName, String keyStoreType, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to load keystore [filename={0}, type={1}]: {2}" )
+ void failedToLoadKeystore( String fileName, String keyStoreType, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to add credential: {1}" )
+ void failedToAddCredential( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message(level = MessageLevel.ERROR, text = "Failed to remove credential: {1}")
+ void failedToRemoveCredential(@StackTrace(level = MessageLevel.DEBUG) Exception e);
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to get credential: {1}" )
+ void failedToGetCredential(@StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to persist master secret: {0}" )
+ void failedToPersistMasterSecret( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to encrypt master secret: {0}" )
+ void failedToEncryptMasterSecret( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to initialize master service from persistent master {0}: {1}" )
+ void failedToInitializeFromPersistentMaster( String masterFileName, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to add self signed certificate for Gateway {0}: {1}" )
+ void failedToAddSeflSignedCertForGateway( String alias, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to get key {0}: {1}" )
+ void failedToGetKey(String alias, @StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+ @Message( level = MessageLevel.DEBUG, text = "Loading from persistent master: {0}" )
+ void loadingFromPersistentMaster( String tag );
+
+ @Message( level = MessageLevel.DEBUG, text = "ALIAS: {0}" )
+ void printClusterAlias( String alias );
+
+ @Message( level = MessageLevel.DEBUG, text = "MASTER SERVICE == NULL: {0}" )
+ void printMasterServiceIsNull( boolean masterServiceIsNull );
+
+ @Message( level = MessageLevel.ERROR, text = "Gateway has failed to start. Unable to prompt user for master secret setup. Please consider using knoxcli.sh create-master" )
+ void unableToPromptForMasterUseKnoxCLI();
+
+ @Message( level = MessageLevel.ERROR, text = "Error in generating certificate: {0}" )
+ void failedToGenerateCertificate( @StackTrace( level = MessageLevel.ERROR ) Exception e );
+
+ @Message(level = MessageLevel.ERROR, text = "Failed to read configuration: {0}")
+ void failedToReadConfigurationFile(final String filePath, @StackTrace(level = MessageLevel.DEBUG) Exception e );
+
+ @Message(level = MessageLevel.ERROR, text = "Invalid resource URI {0} : {1}")
+ void invalidResourceURI(final String uri, final String reason, @StackTrace(level = MessageLevel.DEBUG) Exception e );
+
++ @Message( level = MessageLevel.ERROR, text = "Topology {0} cannot be manually overwritten because it was generated from a simple descriptor." )
++ void disallowedOverwritingGeneratedTopology(final String topologyName);
++
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
index 815c218,0000000..e46197d
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
@@@ -1,151 -1,0 +1,160 @@@
+/**
+ * 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.knox.gateway.topology;
+
+import org.apache.commons.collections.map.HashedMap;
+import org.apache.commons.collections.map.MultiKeyMap;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Topology {
+
+ private URI uri;
+ private String name;
+ private String defaultServicePath = null;
+ private long timestamp;
++ private boolean isGenerated;
+ public List<Provider> providerList = new ArrayList<Provider>();
+ private Map<String,Map<String,Provider>> providerMap = new HashMap<>();
+ public List<Service> services = new ArrayList<Service>();
+ private MultiKeyMap serviceMap;
+ private List<Application> applications = new ArrayList<Application>();
+ private Map<String,Application> applicationMap = new HashMap<>();
+
+ public Topology() {
+ serviceMap = MultiKeyMap.decorate(new HashedMap());
+ }
+
+ public URI getUri() {
+ return uri;
+ }
+
+ public void setUri( URI uri ) {
+ this.uri = uri;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp( long timestamp ) {
+ this.timestamp = timestamp;
+ }
+
+ public String getDefaultServicePath() {
+ return defaultServicePath;
+ }
+
+ public void setDefaultServicePath(String servicePath) {
+ defaultServicePath = servicePath;
+ }
+
++ public void setGenerated(boolean isGenerated) {
++ this.isGenerated = isGenerated;
++ }
++
++ public boolean isGenerated() {
++ return isGenerated;
++ }
++
+ public Collection<Service> getServices() {
+ return services;
+ }
+
+ public Service getService( String role, String name, Version version) {
+ return (Service)serviceMap.get(role, name, version);
+ }
+
+ public void addService( Service service ) {
+ services.add( service );
+ 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;
+ }
+
+ public Provider getProvider( String role, String name ) {
+ Provider provider = null;
+ Map<String,Provider> nameMap = providerMap.get( role );
+ if( nameMap != null) {
+ if( name != null ) {
+ provider = nameMap.get( name );
+ }
+ else {
+ provider = (Provider) nameMap.values().toArray()[0];
+ }
+ }
+ return provider;
+ }
+
+ public void addProvider( Provider provider ) {
+ providerList.add( provider );
+ String role = provider.getRole();
+ Map<String,Provider> nameMap = providerMap.get( role );
+ if( nameMap == null ) {
+ nameMap = new HashMap<>();
+ providerMap.put( role, nameMap );
+ }
+ nameMap.put( provider.getName(), provider );
+ }
+
+}
[14/16] knox git commit: Merge branch 'master' into
KNOX-998-Package_Restructuring
Posted by mo...@apache.org.
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorImpl.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorImpl.java
index 4eb1954,0000000..f3288fd
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorImpl.java
@@@ -1,123 -1,0 +1,163 @@@
+/**
+ * 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.knox.gateway.topology.simple;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+class SimpleDescriptorImpl implements SimpleDescriptor {
+
+ @JsonProperty("discovery-type")
+ private String discoveryType;
+
+ @JsonProperty("discovery-address")
+ private String discoveryAddress;
+
+ @JsonProperty("discovery-user")
+ private String discoveryUser;
+
+ @JsonProperty("discovery-pwd-alias")
+ private String discoveryPasswordAlias;
+
+ @JsonProperty("provider-config-ref")
+ private String providerConfig;
+
+ @JsonProperty("cluster")
+ private String cluster;
+
+ @JsonProperty("services")
+ private List<ServiceImpl> services;
+
++ @JsonProperty("applications")
++ private List<ApplicationImpl> applications;
++
+ private String name = null;
+
+ void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getDiscoveryType() {
+ return discoveryType;
+ }
+
+ @Override
+ public String getDiscoveryAddress() {
+ return discoveryAddress;
+ }
+
+ @Override
+ public String getDiscoveryUser() {
+ return discoveryUser;
+ }
+
+ @Override
+ public String getDiscoveryPasswordAlias() {
+ return discoveryPasswordAlias;
+ }
+
+ @Override
+ public String getClusterName() {
+ return cluster;
+ }
+
+ @Override
+ public String getProviderConfig() {
+ return providerConfig;
+ }
+
+ @Override
+ public List<Service> getServices() {
+ List<Service> result = new ArrayList<>();
- result.addAll(services);
++ if (services != null) {
++ result.addAll(services);
++ }
++ return result;
++ }
++
++ @Override
++ public List<Application> getApplications() {
++ List<Application> result = new ArrayList<>();
++ if (applications != null) {
++ result.addAll(applications);
++ }
+ return result;
+ }
+
+ public static class ServiceImpl implements Service {
+ @JsonProperty("name")
+ private String name;
+
+ @JsonProperty("params")
+ private Map<String, String> params;
+
+ @JsonProperty("urls")
+ private List<String> urls;
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Map<String, String> getParams() {
+ return params;
+ }
+
+ @Override
+ public List<String> getURLs() {
+ return urls;
+ }
+ }
+
++ public static class ApplicationImpl implements Application {
++ @JsonProperty("name")
++ private String name;
++
++ @JsonProperty("params")
++ private Map<String, String> params;
++
++ @JsonProperty("urls")
++ private List<String> urls;
++
++ @Override
++ public String getName() {
++ return name;
++ }
++
++ @Override
++ public Map<String, String> getParams() {
++ return params;
++ }
++
++ @Override
++ public List<String> getURLs() {
++ return urls;
++ }
++ }
++
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/main/java/org/apache/knox/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
----------------------------------------------------------------------
diff --cc gateway-server/src/main/java/org/apache/knox/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
index 81aedec,0000000..a1fcb6d
mode 100644,000000..100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/topology/xml/KnoxFormatXmlTopologyRules.java
@@@ -1,95 -1,0 +1,97 @@@
+/**
+ * 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.knox.gateway.topology.xml;
+
+import org.apache.commons.digester3.Rule;
+import org.apache.commons.digester3.binder.AbstractRulesModule;
+import org.apache.knox.gateway.topology.Application;
+import org.apache.knox.gateway.topology.Param;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Service;
+import org.apache.knox.gateway.topology.Version;
+import org.apache.knox.gateway.topology.builder.BeanPropertyTopologyBuilder;
+import org.xml.sax.Attributes;
+
+public class KnoxFormatXmlTopologyRules extends AbstractRulesModule {
+
+ private static final String ROOT_TAG = "topology";
+ private static final String NAME_TAG = "name";
+ private static final String VERSION_TAG = "version";
+ private static final String DEFAULT_SERVICE_TAG = "path";
++ private static final String GENERATED_TAG = "generated";
+ private static final String APPLICATION_TAG = "application";
+ private static final String SERVICE_TAG = "service";
+ private static final String ROLE_TAG = "role";
+ private static final String URL_TAG = "url";
+ private static final String PROVIDER_TAG = "gateway/provider";
+ private static final String ENABLED_TAG = "enabled";
+ private static final String PARAM_TAG = "param";
+ private static final String VALUE_TAG = "value";
+
+ private static final Rule paramRule = new ParamRule();
+
+ @Override
+ protected void configure() {
+ forPattern( ROOT_TAG ).createObject().ofType( BeanPropertyTopologyBuilder.class );
+ forPattern( ROOT_TAG + "/" + NAME_TAG ).callMethod("name").usingElementBodyAsArgument();
+ forPattern( ROOT_TAG + "/" + VERSION_TAG ).callMethod("version").usingElementBodyAsArgument();
+ forPattern( ROOT_TAG + "/" + DEFAULT_SERVICE_TAG ).callMethod("defaultService").usingElementBodyAsArgument();
++ forPattern( ROOT_TAG + "/" + GENERATED_TAG ).callMethod("generated").usingElementBodyAsArgument();
+
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG ).createObject().ofType( Application.class ).then().setNext( "addApplication" );
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + ROLE_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + NAME_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + VERSION_TAG ).createObject().ofType(Version.class).then().setBeanProperty().then().setNext("setVersion");
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + URL_TAG ).callMethod( "addUrl" ).usingElementBodyAsArgument();
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + PARAM_TAG ).createObject().ofType( Param.class ).then().addRule( paramRule ).then().setNext( "addParam" );
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + PARAM_TAG + "/" + NAME_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + APPLICATION_TAG + "/" + PARAM_TAG + "/" + VALUE_TAG ).setBeanProperty();
+
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG ).createObject().ofType( Service.class ).then().setNext( "addService" );
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + ROLE_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + NAME_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + VERSION_TAG ).createObject().ofType(Version.class).then().setBeanProperty().then().setNext("setVersion");
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + URL_TAG ).callMethod( "addUrl" ).usingElementBodyAsArgument();
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + PARAM_TAG ).createObject().ofType( Param.class ).then().addRule( paramRule ).then().setNext( "addParam" );
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + PARAM_TAG + "/" + NAME_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + SERVICE_TAG + "/" + PARAM_TAG + "/" + VALUE_TAG ).setBeanProperty();
+
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG ).createObject().ofType( Provider.class ).then().setNext( "addProvider" );
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG + "/" + ROLE_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG + "/" + ENABLED_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG + "/" + NAME_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG + "/" + PARAM_TAG ).createObject().ofType( Param.class ).then().addRule( paramRule ).then().setNext( "addParam" );
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG + "/" + PARAM_TAG + "/" + NAME_TAG ).setBeanProperty();
+ forPattern( ROOT_TAG + "/" + PROVIDER_TAG + "/" + PARAM_TAG + "/" + VALUE_TAG ).setBeanProperty();
+ }
+
+ private static class ParamRule extends Rule {
+
+ @Override
+ public void begin( String namespace, String name, Attributes attributes ) {
+ Param param = getDigester().peek();
+ String paramName = attributes.getValue( "name" );
+ if( paramName != null ) {
+ param.setName( paramName );
+ param.setValue( attributes.getValue( "value" ) );
+ }
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorFactoryTest.java
----------------------------------------------------------------------
diff --cc gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorFactoryTest.java
index 41a7c10,0000000..df31f3d
mode 100644,000000..100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorFactoryTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorFactoryTest.java
@@@ -1,422 -1,0 +1,681 @@@
+/**
+ * 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.knox.gateway.topology.simple;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.*;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+
+public class SimpleDescriptorFactoryTest {
+
++ private enum FileType {
++ JSON,
++ YAML
++ }
+
+ @Test
+ public void testParseJSONSimpleDescriptor() throws Exception {
++ testParseSimpleDescriptor(FileType.JSON);
++ }
++
++ @Test
++ public void testParseYAMLSimpleDescriptor() throws Exception {
++ testParseSimpleDescriptor(FileType.YAML);
++ }
++
++ @Test
++ public void testParseJSONSimpleDescriptorWithServiceParams() throws Exception {
++ testParseSimpleDescriptorWithServiceParams(FileType.JSON);
++ }
++
++ @Test
++ public void testParseYAMLSimpleDescriptorWithServiceParams() throws Exception {
++ testParseSimpleDescriptorWithServiceParams(FileType.YAML);
++ }
++
++ @Test
++ public void testParseJSONSimpleDescriptorWithApplications() throws Exception {
++ testParseSimpleDescriptorWithApplications(FileType.JSON);
++ }
++
++ @Test
++ public void testParseYAMLSimpleDescriptorApplications() throws Exception {
++ testParseSimpleDescriptorWithApplications(FileType.YAML);
++ }
++
++
++ @Test
++ public void testParseJSONSimpleDescriptorWithServicesAndApplications() throws Exception {
++ testParseSimpleDescriptorWithServicesAndApplications(FileType.JSON);
++ }
++
++ @Test
++ public void testParseYAMLSimpleDescriptorWithServicesAndApplications() throws Exception {
++ testParseSimpleDescriptorWithServicesAndApplications(FileType.YAML);
++ }
++
+
++ private void testParseSimpleDescriptor(FileType type) throws Exception {
+ final String discoveryType = "AMBARI";
+ final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
- final String discoveryUser = "admin";
++ final String discoveryUser = "joeblow";
+ final String providerConfig = "ambari-cluster-policy.xml";
+ final String clusterName = "myCluster";
+
+ final Map<String, List<String>> services = new HashMap<>();
+ services.put("NODEMANAGER", null);
+ services.put("JOBTRACKER", null);
+ services.put("RESOURCEMANAGER", null);
+ services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
- services.put("AMBARIUI", Arrays.asList("http://c6401.ambari.apache.org:8080"));
++ services.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
+
- String fileName = "test-topology.json";
- File testJSON = null;
++ String fileName = "test-topology." + getFileExtensionForType(type);
++ File testFile = null;
+ try {
- testJSON = writeJSON(fileName, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testJSON.getAbsolutePath());
++ testFile = writeDescriptorFile(type,
++ fileName,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services);
++ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
+ validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
- if (testJSON != null) {
++ if (testFile != null) {
+ try {
- testJSON.delete();
++ testFile.delete();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
- @Test
- public void testParseJSONSimpleDescriptorWithServiceParams() throws Exception {
++ private void testParseSimpleDescriptorWithServiceParams(FileType type) throws Exception {
+
+ final String discoveryType = "AMBARI";
+ final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
+ final String discoveryUser = "admin";
+ final String providerConfig = "ambari-cluster-policy.xml";
+ final String clusterName = "myCluster";
+
+ final Map<String, List<String>> services = new HashMap<>();
+ services.put("NODEMANAGER", null);
+ services.put("JOBTRACKER", null);
+ services.put("RESOURCEMANAGER", null);
+ services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
+ services.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
+ services.put("KNOXSSO", null);
+ services.put("KNOXTOKEN", null);
+ services.put("CustomRole", Collections.singletonList("http://c6402.ambari.apache.org:1234"));
+
+ final Map<String, Map<String, String>> serviceParams = new HashMap<>();
+ Map<String, String> knoxSSOParams = new HashMap<>();
+ knoxSSOParams.put("knoxsso.cookie.secure.only", "true");
+ knoxSSOParams.put("knoxsso.token.ttl", "100000");
+ serviceParams.put("KNOXSSO", knoxSSOParams);
+
+ Map<String, String> knoxTokenParams = new HashMap<>();
+ knoxTokenParams.put("knox.token.ttl", "36000000");
+ knoxTokenParams.put("knox.token.audiences", "tokenbased");
+ knoxTokenParams.put("knox.token.target.url", "https://localhost:8443/gateway/tokenbased");
+ serviceParams.put("KNOXTOKEN", knoxTokenParams);
+
+ Map<String, String> customRoleParams = new HashMap<>();
+ customRoleParams.put("custom.param.1", "value1");
+ customRoleParams.put("custom.param.2", "value2");
+ serviceParams.put("CustomRole", customRoleParams);
+
- String fileName = "test-topology.json";
- File testJSON = null;
++ String fileName = "test-topology." + getFileExtensionForType(type);
++ File testFile = null;
+ try {
- testJSON = writeJSON(fileName,
- discoveryType,
- discoveryAddress,
- discoveryUser,
- providerConfig,
- clusterName,
- services,
- serviceParams);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testJSON.getAbsolutePath());
++ testFile = writeDescriptorFile(type,
++ fileName,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services,
++ serviceParams);
++ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
+ validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services, serviceParams);
- } catch (Exception e) {
- e.printStackTrace();
+ } finally {
- if (testJSON != null) {
++ if (testFile != null) {
+ try {
- testJSON.delete();
++ testFile.delete();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
- @Test
- public void testParseYAMLSimpleDescriptor() throws Exception {
++ private void testParseSimpleDescriptorWithApplications(FileType type) throws Exception {
+
+ final String discoveryType = "AMBARI";
+ final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
- final String discoveryUser = "joeblow";
++ final String discoveryUser = "admin";
+ final String providerConfig = "ambari-cluster-policy.xml";
+ final String clusterName = "myCluster";
+
- final Map<String, List<String>> services = new HashMap<>();
- services.put("NODEMANAGER", null);
- services.put("JOBTRACKER", null);
- services.put("RESOURCEMANAGER", null);
- services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
- services.put("AMBARIUI", Arrays.asList("http://c6401.ambari.apache.org:8080"));
-
- String fileName = "test-topology.yml";
- File testYAML = null;
++ final Map<String, List<String>> apps = new HashMap<>();
++ apps.put("app-one", null);
++ apps.put("appTwo", null);
++ apps.put("thirdApps", null);
++ apps.put("appfour", Arrays.asList("http://host1:1234", "http://host2:5678", "http://host1:1357"));
++ apps.put("AppFive", Collections.singletonList("http://host5:8080"));
++
++ final Map<String, Map<String, String>> appParams = new HashMap<>();
++ Map<String, String> oneParams = new HashMap<>();
++ oneParams.put("appone.cookie.secure.only", "true");
++ oneParams.put("appone.token.ttl", "100000");
++ appParams.put("app-one", oneParams);
++ Map<String, String> fiveParams = new HashMap<>();
++ fiveParams.put("myproperty", "true");
++ fiveParams.put("anotherparam", "100000");
++ appParams.put("AppFive", fiveParams);
++
++ String fileName = "test-topology." + getFileExtensionForType(type);
++ File testFile = null;
+ try {
- testYAML = writeYAML(fileName, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testYAML.getAbsolutePath());
- validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services);
- } catch (Exception e) {
- e.printStackTrace();
++ testFile = writeDescriptorFile(type,
++ fileName,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ null,
++ null,
++ apps,
++ appParams);
++ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
++ validateSimpleDescriptor(sd,
++ discoveryType,
++ discoveryAddress,
++ providerConfig,
++ clusterName,
++ null,
++ null,
++ apps,
++ appParams);
+ } finally {
- if (testYAML != null) {
++ if (testFile != null) {
+ try {
- testYAML.delete();
++ testFile.delete();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
-
- @Test
- public void testParseYAMLSimpleDescriptorWithServiceParams() throws Exception {
++ private void testParseSimpleDescriptorWithServicesAndApplications(FileType type) throws Exception {
+
+ final String discoveryType = "AMBARI";
+ final String discoveryAddress = "http://c6401.ambari.apache.org:8080";
- final String discoveryUser = "joeblow";
++ final String discoveryUser = "admin";
+ final String providerConfig = "ambari-cluster-policy.xml";
+ final String clusterName = "myCluster";
+
+ final Map<String, List<String>> services = new HashMap<>();
+ services.put("NODEMANAGER", null);
+ services.put("JOBTRACKER", null);
+ services.put("RESOURCEMANAGER", null);
+ services.put("HIVE", Arrays.asList("http://c6401.ambari.apache.org", "http://c6402.ambari.apache.org", "http://c6403.ambari.apache.org"));
- services.put("AMBARIUI", Arrays.asList("http://c6401.ambari.apache.org:8080"));
++ services.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
+ services.put("KNOXSSO", null);
+ services.put("KNOXTOKEN", null);
+ services.put("CustomRole", Collections.singletonList("http://c6402.ambari.apache.org:1234"));
+
+ final Map<String, Map<String, String>> serviceParams = new HashMap<>();
+ Map<String, String> knoxSSOParams = new HashMap<>();
+ knoxSSOParams.put("knoxsso.cookie.secure.only", "true");
+ knoxSSOParams.put("knoxsso.token.ttl", "100000");
+ serviceParams.put("KNOXSSO", knoxSSOParams);
+
+ Map<String, String> knoxTokenParams = new HashMap<>();
+ knoxTokenParams.put("knox.token.ttl", "36000000");
+ knoxTokenParams.put("knox.token.audiences", "tokenbased");
+ knoxTokenParams.put("knox.token.target.url", "https://localhost:8443/gateway/tokenbased");
+ serviceParams.put("KNOXTOKEN", knoxTokenParams);
+
+ Map<String, String> customRoleParams = new HashMap<>();
+ customRoleParams.put("custom.param.1", "value1");
+ customRoleParams.put("custom.param.2", "value2");
+ serviceParams.put("CustomRole", customRoleParams);
+
- String fileName = "test-topology.yml";
- File testYAML = null;
++ final Map<String, List<String>> apps = new HashMap<>();
++ apps.put("app-one", null);
++ apps.put("appTwo", null);
++ apps.put("thirdApps", null);
++ apps.put("appfour", Arrays.asList("http://host1:1234", "http://host2:5678", "http://host1:1357"));
++ apps.put("AppFive", Collections.singletonList("http://host5:8080"));
++
++ final Map<String, Map<String, String>> appParams = new HashMap<>();
++ Map<String, String> oneParams = new HashMap<>();
++ oneParams.put("appone.cookie.secure.only", "true");
++ oneParams.put("appone.token.ttl", "100000");
++ appParams.put("app-one", oneParams);
++ Map<String, String> fiveParams = new HashMap<>();
++ fiveParams.put("myproperty", "true");
++ fiveParams.put("anotherparam", "100000");
++ appParams.put("AppFive", fiveParams);
++
++ String fileName = "test-topology." + getFileExtensionForType(type);
++ File testFile = null;
+ try {
- testYAML = writeYAML(fileName, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services, serviceParams);
- SimpleDescriptor sd = SimpleDescriptorFactory.parse(testYAML.getAbsolutePath());
- validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, services, serviceParams);
- } catch (Exception e) {
- e.printStackTrace();
++ testFile = writeDescriptorFile(type,
++ fileName,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services,
++ serviceParams,
++ apps,
++ appParams);
++ SimpleDescriptor sd = SimpleDescriptorFactory.parse(testFile.getAbsolutePath());
++ validateSimpleDescriptor(sd,
++ discoveryType,
++ discoveryAddress,
++ providerConfig,
++ clusterName,
++ services,
++ serviceParams,
++ apps,
++ appParams);
+ } finally {
- if (testYAML != null) {
++ if (testFile != null) {
+ try {
- testYAML.delete();
++ testFile.delete();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
-
- private void validateSimpleDescriptor(SimpleDescriptor sd,
- String discoveryType,
- String discoveryAddress,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> expectedServices) {
- validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, expectedServices, null);
- }
-
-
- private void validateSimpleDescriptor(SimpleDescriptor sd,
- String discoveryType,
- String discoveryAddress,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> expectedServices,
- Map<String, Map<String, String>> expectedServiceParameters) {
- assertNotNull(sd);
- assertEquals(discoveryType, sd.getDiscoveryType());
- assertEquals(discoveryAddress, sd.getDiscoveryAddress());
- assertEquals(providerConfig, sd.getProviderConfig());
- assertEquals(clusterName, sd.getClusterName());
-
- List<SimpleDescriptor.Service> actualServices = sd.getServices();
-
- assertEquals(expectedServices.size(), actualServices.size());
-
- for (SimpleDescriptor.Service actualService : actualServices) {
- assertTrue(expectedServices.containsKey(actualService.getName()));
- assertEquals(expectedServices.get(actualService.getName()), actualService.getURLs());
-
- // Validate service parameters
- if (expectedServiceParameters != null) {
- if (expectedServiceParameters.containsKey(actualService.getName())) {
- Map<String, String> expectedParams = expectedServiceParameters.get(actualService.getName());
-
- Map<String, String> actualServiceParams = actualService.getParams();
- assertNotNull(actualServiceParams);
-
- // Validate the size of the service parameter set
- assertEquals(expectedParams.size(), actualServiceParams.size());
-
- // Validate the parameter contents
- for (String paramName : actualServiceParams.keySet()) {
- assertTrue(expectedParams.containsKey(paramName));
- assertEquals(expectedParams.get(paramName), actualServiceParams.get(paramName));
- }
- }
- }
++ private String getFileExtensionForType(FileType type) {
++ String extension = null;
++ switch (type) {
++ case JSON:
++ extension = "json";
++ break;
++ case YAML:
++ extension = "yml";
++ break;
+ }
++ return extension;
+ }
+
++ private File writeDescriptorFile(FileType type,
++ String path,
++ String discoveryType,
++ String discoveryAddress,
++ String discoveryUser,
++ String providerConfig,
++ String clusterName,
++ Map<String, List<String>> services) throws Exception {
++ return writeDescriptorFile(type,
++ path,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services,
++ null);
++ }
+
- private File writeJSON(String path, String content) throws Exception {
- File f = new File(path);
-
- Writer fw = new FileWriter(f);
- fw.write(content);
- fw.flush();
- fw.close();
-
- return f;
++ private File writeDescriptorFile(FileType type,
++ String path,
++ String discoveryType,
++ String discoveryAddress,
++ String discoveryUser,
++ String providerConfig,
++ String clusterName,
++ Map<String, List<String>> services,
++ Map<String, Map<String, String>> serviceParams) throws Exception {
++ return writeDescriptorFile(type,
++ path,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services,
++ serviceParams,
++ null,
++ null);
+ }
+
+
- private File writeJSON(String path,
- String discoveryType,
- String discoveryAddress,
- String discoveryUser,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> services) throws Exception {
- return writeJSON(path, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services, null);
++ private File writeDescriptorFile(FileType type,
++ String path,
++ String discoveryType,
++ String discoveryAddress,
++ String discoveryUser,
++ String providerConfig,
++ String clusterName,
++ Map<String, List<String>> services,
++ Map<String, Map<String, String>> serviceParams,
++ Map<String, List<String>> apps,
++ Map<String, Map<String, String>> appParams) throws Exception {
++ File result = null;
++ switch (type) {
++ case JSON:
++ result = writeJSON(path,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services,
++ serviceParams,
++ apps,
++ appParams);
++ break;
++ case YAML:
++ result = writeYAML(path,
++ discoveryType,
++ discoveryAddress,
++ discoveryUser,
++ providerConfig,
++ clusterName,
++ services,
++ serviceParams,
++ apps,
++ appParams);
++ break;
++ }
++ return result;
+ }
+
++
+ private File writeJSON(String path,
+ String discoveryType,
+ String discoveryAddress,
+ String discoveryUser,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> services,
- Map<String, Map<String, String>> serviceParams) throws Exception {
++ Map<String, Map<String, String>> serviceParams,
++ Map<String, List<String>> apps,
++ Map<String, Map<String, String>> appParams) throws Exception {
+ File f = new File(path);
+
+ Writer fw = new FileWriter(f);
+ fw.write("{" + "\n");
+ fw.write("\"discovery-type\":\"" + discoveryType + "\",\n");
+ fw.write("\"discovery-address\":\"" + discoveryAddress + "\",\n");
+ fw.write("\"discovery-user\":\"" + discoveryUser + "\",\n");
+ fw.write("\"provider-config-ref\":\"" + providerConfig + "\",\n");
- fw.write("\"cluster\":\"" + clusterName + "\",\n");
- fw.write("\"services\":[\n");
-
- int i = 0;
- for (String name : services.keySet()) {
- fw.write("{\"name\":\"" + name + "\"");
-
- // Service params
- if (serviceParams != null && !serviceParams.isEmpty()) {
- Map<String, String> params = serviceParams.get(name);
- if (params != null && !params.isEmpty()) {
- fw.write(",\n\"params\":{\n");
- Iterator<String> paramNames = params.keySet().iterator();
- while (paramNames.hasNext()) {
- String paramName = paramNames.next();
- String paramValue = params.get(paramName);
- fw.write("\"" + paramName + "\":\"" + paramValue + "\"");
- fw.write(paramNames.hasNext() ? ",\n" : "");
- }
- fw.write("\n}");
- }
- }
++ fw.write("\"cluster\":\"" + clusterName + "\"");
+
- // Service URLs
- List<String> urls = services.get(name);
- if (urls != null) {
- fw.write(",\n\"urls\":[");
- Iterator<String> urlIter = urls.iterator();
- while (urlIter.hasNext()) {
- fw.write("\"" + urlIter.next() + "\"");
- if (urlIter.hasNext()) {
- fw.write(", ");
- }
- }
- fw.write("]\n");
- }
++ if (services != null && !services.isEmpty()) {
++ fw.write(",\n\"services\":[\n");
++ writeServiceOrApplicationJSON(fw, services, serviceParams);
++ fw.write("]\n");
++ }
+
- fw.write("}");
- if (i++ < services.size() - 1) {
- fw.write(",");
- }
- fw.write("\n");
++ if (apps != null && !apps.isEmpty()) {
++ fw.write(",\n\"applications\":[\n");
++ writeServiceOrApplicationJSON(fw, apps, appParams);
++ fw.write("]\n");
+ }
- fw.write("]\n");
++
+ fw.write("}\n");
+ fw.flush();
+ fw.close();
+
+ return f;
+ }
+
++ private void writeServiceOrApplicationJSON(Writer fw,
++ Map<String, List<String>> elementURLs,
++ Map<String, Map<String, String>> elementParams) throws Exception {
++ if (elementURLs != null) {
++ int i = 0;
++ for (String name : elementURLs.keySet()) {
++ fw.write("{\"name\":\"" + name + "\"");
++
++ // Service params
++ if (elementParams != null && !elementParams.isEmpty()) {
++ Map<String, String> params = elementParams.get(name);
++ if (params != null && !params.isEmpty()) {
++ fw.write(",\n\"params\":{\n");
++ Iterator<String> paramNames = params.keySet().iterator();
++ while (paramNames.hasNext()) {
++ String paramName = paramNames.next();
++ String paramValue = params.get(paramName);
++ fw.write("\"" + paramName + "\":\"" + paramValue + "\"");
++ fw.write(paramNames.hasNext() ? ",\n" : "");
++ }
++ fw.write("\n}");
++ }
++ }
+
- private File writeYAML(String path,
- String discoveryType,
- String discoveryAddress,
- String discoveryUser,
- String providerConfig,
- String clusterName,
- Map<String, List<String>> services) throws Exception {
- return writeYAML(path, discoveryType, discoveryAddress, discoveryUser, providerConfig, clusterName, services, null);
- }
++ // Service URLs
++ List<String> urls = elementURLs.get(name);
++ if (urls != null) {
++ fw.write(",\n\"urls\":[");
++ Iterator<String> urlIter = urls.iterator();
++ while (urlIter.hasNext()) {
++ fw.write("\"" + urlIter.next() + "\"");
++ if (urlIter.hasNext()) {
++ fw.write(", ");
++ }
++ }
++ fw.write("]\n");
++ }
+
++ fw.write("}");
++ if (i++ < elementURLs.size() - 1) {
++ fw.write(",");
++ }
++ fw.write("\n");
++ }
++ }
++ }
+
+ private File writeYAML(String path,
+ String discoveryType,
+ String discoveryAddress,
+ String discoveryUser,
+ String providerConfig,
+ String clusterName,
+ Map<String, List<String>> services,
- Map<String, Map<String, String>> serviceParams) throws Exception {
++ Map<String, Map<String, String>> serviceParams,
++ Map<String, List<String>> apps,
++ Map<String, Map<String, String>> appParams) throws Exception {
++
+ File f = new File(path);
+
+ Writer fw = new FileWriter(f);
+ fw.write("---" + "\n");
+ fw.write("discovery-type: " + discoveryType + "\n");
+ fw.write("discovery-address: " + discoveryAddress + "\n");
+ fw.write("discovery-user: " + discoveryUser + "\n");
+ fw.write("provider-config-ref: " + providerConfig + "\n");
+ fw.write("cluster: " + clusterName+ "\n");
- fw.write("services:\n");
- for (String name : services.keySet()) {
++
++ if (services != null && !services.isEmpty()) {
++ fw.write("services:\n");
++ writeServiceOrApplicationYAML(fw, services, serviceParams);
++ }
++
++ if (apps != null && !apps.isEmpty()) {
++ fw.write("applications:\n");
++ writeServiceOrApplicationYAML(fw, apps, appParams);
++ }
++
++ fw.flush();
++ fw.close();
++
++ return f;
++ }
++
++ private void writeServiceOrApplicationYAML(Writer fw,
++ Map<String, List<String>> elementURLs,
++ Map<String, Map<String, String>> elementParams) throws Exception {
++ for (String name : elementURLs.keySet()) {
+ fw.write(" - name: " + name + "\n");
+
+ // Service params
- if (serviceParams != null && !serviceParams.isEmpty()) {
- if (serviceParams.containsKey(name)) {
- Map<String, String> params = serviceParams.get(name);
++ if (elementParams != null && !elementParams.isEmpty()) {
++ if (elementParams.containsKey(name)) {
++ Map<String, String> params = elementParams.get(name);
+ fw.write(" params:\n");
+ for (String paramName : params.keySet()) {
+ fw.write(" " + paramName + ": " + params.get(paramName) + "\n");
+ }
+ }
+ }
+
+ // Service URLs
- List<String> urls = services.get(name);
++ List<String> urls = elementURLs.get(name);
+ if (urls != null) {
+ fw.write(" urls:\n");
+ for (String url : urls) {
+ fw.write(" - " + url + "\n");
+ }
+ }
+ }
- fw.flush();
- fw.close();
++ }
+
- return f;
++
++ private void validateSimpleDescriptor(SimpleDescriptor sd,
++ String discoveryType,
++ String discoveryAddress,
++ String providerConfig,
++ String clusterName,
++ Map<String, List<String>> expectedServices) {
++ validateSimpleDescriptor(sd, discoveryType, discoveryAddress, providerConfig, clusterName, expectedServices, null);
++ }
++
++
++ private void validateSimpleDescriptor(SimpleDescriptor sd,
++ String discoveryType,
++ String discoveryAddress,
++ String providerConfig,
++ String clusterName,
++ Map<String, List<String>> expectedServices,
++ Map<String, Map<String, String>> expectedServiceParameters) {
++ validateSimpleDescriptor(sd,
++ discoveryType,
++ discoveryAddress,
++ providerConfig,
++ clusterName,
++ expectedServices,
++ expectedServiceParameters,
++ null,
++ null);
+ }
+
++ private void validateSimpleDescriptor(SimpleDescriptor sd,
++ String discoveryType,
++ String discoveryAddress,
++ String providerConfig,
++ String clusterName,
++ Map<String, List<String>> expectedServices,
++ Map<String, Map<String, String>> expectedServiceParameters,
++ Map<String, List<String>> expectedApps,
++ Map<String, Map<String, String>> expectedAppParameters) {
++ assertNotNull(sd);
++ assertEquals(discoveryType, sd.getDiscoveryType());
++ assertEquals(discoveryAddress, sd.getDiscoveryAddress());
++ assertEquals(providerConfig, sd.getProviderConfig());
++ assertEquals(clusterName, sd.getClusterName());
++
++ List<SimpleDescriptor.Service> actualServices = sd.getServices();
++
++ if (expectedServices == null) {
++ assertTrue(actualServices.isEmpty());
++ } else {
++ assertEquals(expectedServices.size(), actualServices.size());
++
++ for (SimpleDescriptor.Service actualService : actualServices) {
++ assertTrue(expectedServices.containsKey(actualService.getName()));
++ assertEquals(expectedServices.get(actualService.getName()), actualService.getURLs());
++
++ // Validate service parameters
++ if (expectedServiceParameters != null) {
++ if (expectedServiceParameters.containsKey(actualService.getName())) {
++ Map<String, String> expectedParams = expectedServiceParameters.get(actualService.getName());
++
++ Map<String, String> actualServiceParams = actualService.getParams();
++ assertNotNull(actualServiceParams);
++
++ // Validate the size of the service parameter set
++ assertEquals(expectedParams.size(), actualServiceParams.size());
++
++ // Validate the parameter contents
++ for (String paramName : actualServiceParams.keySet()) {
++ assertTrue(expectedParams.containsKey(paramName));
++ assertEquals(expectedParams.get(paramName), actualServiceParams.get(paramName));
++ }
++ }
++ }
++ }
++ }
++
++ List<SimpleDescriptor.Application> actualApps = sd.getApplications();
++
++ if (expectedApps == null) {
++ assertTrue(actualApps.isEmpty());
++ } else {
++ assertEquals(expectedApps.size(), actualApps.size());
++
++ for (SimpleDescriptor.Application actualApp : actualApps) {
++ assertTrue(expectedApps.containsKey(actualApp.getName()));
++ assertEquals(expectedApps.get(actualApp.getName()), actualApp.getURLs());
++
++ // Validate service parameters
++ if (expectedServiceParameters != null) {
++ if (expectedAppParameters.containsKey(actualApp.getName())) {
++ Map<String, String> expectedParams = expectedAppParameters.get(actualApp.getName());
++
++ Map<String, String> actualAppParams = actualApp.getParams();
++ assertNotNull(actualAppParams);
++
++ // Validate the size of the service parameter set
++ assertEquals(expectedParams.size(), actualAppParams.size());
++
++ // Validate the parameter contents
++ for (String paramName : actualAppParams.keySet()) {
++ assertTrue(expectedParams.containsKey(paramName));
++ assertEquals(expectedParams.get(paramName), actualAppParams.get(paramName));
++ }
++ }
++ }
++ }
++ }
++ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandlerTest.java
----------------------------------------------------------------------
diff --cc gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandlerTest.java
index f40fad7,0000000..575b68a
mode 100644,000000..100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandlerTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/topology/simple/SimpleDescriptorHandlerTest.java
@@@ -1,447 -1,0 +1,455 @@@
+/**
+ * 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.knox.gateway.topology.simple;
+
+import org.apache.knox.gateway.topology.validation.TopologyValidator;
+import org.apache.knox.gateway.util.XmlUtils;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.io.FileUtils;
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
++import static org.hamcrest.Matchers.hasXPath;
++import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
++import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class SimpleDescriptorHandlerTest {
+
+ private static final String TEST_PROVIDER_CONFIG =
+ " <gateway>\n" +
+ " <provider>\n" +
+ " <role>authentication</role>\n" +
+ " <name>ShiroProvider</name>\n" +
+ " <enabled>true</enabled>\n" +
+ " <param>\n" +
+ " <!-- \n" +
+ " session timeout in minutes, this is really idle timeout,\n" +
+ " defaults to 30mins, if the property value is not defined,, \n" +
+ " current client authentication would expire if client idles contiuosly for more than this value\n" +
+ " -->\n" +
+ " <name>sessionTimeout</name>\n" +
+ " <value>30</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>main.ldapRealm</name>\n" +
+ " <value>org.apache.knox.gateway.shirorealm.KnoxLdapRealm</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>main.ldapContextFactory</name>\n" +
+ " <value>org.apache.knox.gateway.shirorealm.KnoxLdapContextFactory</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>main.ldapRealm.contextFactory</name>\n" +
+ " <value>$ldapContextFactory</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>main.ldapRealm.userDnTemplate</name>\n" +
+ " <value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>main.ldapRealm.contextFactory.url</name>\n" +
+ " <value>ldap://localhost:33389</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>main.ldapRealm.contextFactory.authenticationMechanism</name>\n" +
+ " <value>simple</value>\n" +
+ " </param>\n" +
+ " <param>\n" +
+ " <name>urls./**</name>\n" +
+ " <value>authcBasic</value>\n" +
+ " </param>\n" +
+ " </provider>\n" +
+ "\n" +
+ " <provider>\n" +
+ " <role>identity-assertion</role>\n" +
+ " <name>Default</name>\n" +
+ " <enabled>true</enabled>\n" +
+ " </provider>\n" +
+ "\n" +
+ " <!--\n" +
+ " Defines rules for mapping host names internal to a Hadoop cluster to externally accessible host names.\n" +
+ " For example, a hadoop service running in AWS may return a response that includes URLs containing the\n" +
+ " some AWS internal host name. If the client needs to make a subsequent request to the host identified\n" +
+ " in those URLs they need to be mapped to external host names that the client Knox can use to connect.\n" +
+ "\n" +
+ " If the external hostname and internal host names are same turn of this provider by setting the value of\n" +
+ " enabled parameter as false.\n" +
+ "\n" +
+ " The name parameter specifies the external host names in a comma separated list.\n" +
+ " The value parameter specifies corresponding internal host names in a comma separated list.\n" +
+ "\n" +
+ " Note that when you are using Sandbox, the external hostname needs to be localhost, as seen in out\n" +
+ " of box sandbox.xml. This is because Sandbox uses port mapping to allow clients to connect to the\n" +
+ " Hadoop services using localhost. In real clusters, external host names would almost never be localhost.\n" +
+ " -->\n" +
+ " <provider>\n" +
+ " <role>hostmap</role>\n" +
+ " <name>static</name>\n" +
+ " <enabled>true</enabled>\n" +
+ " <param><name>localhost</name><value>sandbox,sandbox.hortonworks.com</value></param>\n" +
+ " </provider>\n" +
+ " </gateway>\n";
+
+
+ /**
+ * KNOX-1006
+ *
+ * N.B. This test depends on the PropertiesFileServiceDiscovery extension being configured:
+ * org.apache.knox.gateway.topology.discovery.test.extension.PropertiesFileServiceDiscovery
+ */
+ @Test
+ public void testSimpleDescriptorHandler() throws Exception {
+
+ final String type = "PROPERTIES_FILE";
+ final String clusterName = "dummy";
+
+ // Create a properties file to be the source of service discovery details for this test
+ final File discoveryConfig = File.createTempFile(getClass().getName() + "_discovery-config", ".properties");
+
+ final String address = discoveryConfig.getAbsolutePath();
+
+ final Properties DISCOVERY_PROPERTIES = new Properties();
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".name", clusterName);
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".NAMENODE", "hdfs://namenodehost:8020");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".JOBTRACKER", "rpc://jobtrackerhostname:8050");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".WEBHDFS", "http://webhdfshost:1234");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".WEBHCAT", "http://webhcathost:50111/templeton");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".OOZIE", "http://ooziehost:11000/oozie");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".WEBHBASE", "http://webhbasehost:1234");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".HIVE", "http://hivehostname:10001/clipath");
+ DISCOVERY_PROPERTIES.setProperty(clusterName + ".RESOURCEMANAGER", "http://remanhost:8088/ws");
+
+ try {
+ DISCOVERY_PROPERTIES.store(new FileOutputStream(discoveryConfig), null);
+ } catch (FileNotFoundException e) {
+ fail(e.getMessage());
+ }
+
+ final Map<String, List<String>> serviceURLs = new HashMap<>();
+ serviceURLs.put("NAMENODE", null);
+ serviceURLs.put("JOBTRACKER", null);
+ serviceURLs.put("WEBHDFS", null);
+ serviceURLs.put("WEBHCAT", null);
+ serviceURLs.put("OOZIE", null);
+ serviceURLs.put("WEBHBASE", null);
+ serviceURLs.put("HIVE", null);
+ serviceURLs.put("RESOURCEMANAGER", null);
+ serviceURLs.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
+ serviceURLs.put("KNOXSSO", null);
+
+ // Write the externalized provider config to a temp file
+ File providerConfig = new File(System.getProperty("java.io.tmpdir"), "ambari-cluster-policy.xml");
+ FileUtils.write(providerConfig, TEST_PROVIDER_CONFIG);
+
+ File topologyFile = null;
+ try {
+ File destDir = new File(System.getProperty("java.io.tmpdir")).getCanonicalFile();
+
+ Map<String, Map<String, String>> serviceParameters = new HashMap<>();
+ Map<String, String> knoxssoParams = new HashMap<>();
+ knoxssoParams.put("knoxsso.cookie.secure.only", "true");
+ knoxssoParams.put("knoxsso.token.ttl", "100000");
+ serviceParameters.put("KNOXSSO", knoxssoParams);
+
+ // Mock out the simple descriptor
+ SimpleDescriptor testDescriptor = EasyMock.createNiceMock(SimpleDescriptor.class);
+ EasyMock.expect(testDescriptor.getName()).andReturn("mysimpledescriptor").anyTimes();
+ EasyMock.expect(testDescriptor.getDiscoveryAddress()).andReturn(address).anyTimes();
+ EasyMock.expect(testDescriptor.getDiscoveryType()).andReturn(type).anyTimes();
+ EasyMock.expect(testDescriptor.getDiscoveryUser()).andReturn(null).anyTimes();
+ EasyMock.expect(testDescriptor.getProviderConfig()).andReturn(providerConfig.getAbsolutePath()).anyTimes();
+ EasyMock.expect(testDescriptor.getClusterName()).andReturn(clusterName).anyTimes();
+ List<SimpleDescriptor.Service> serviceMocks = new ArrayList<>();
+ for (String serviceName : serviceURLs.keySet()) {
+ SimpleDescriptor.Service svc = EasyMock.createNiceMock(SimpleDescriptor.Service.class);
+ EasyMock.expect(svc.getName()).andReturn(serviceName).anyTimes();
+ EasyMock.expect(svc.getURLs()).andReturn(serviceURLs.get(serviceName)).anyTimes();
+ EasyMock.expect(svc.getParams()).andReturn(serviceParameters.get(serviceName)).anyTimes();
+ EasyMock.replay(svc);
+ serviceMocks.add(svc);
+ }
+ EasyMock.expect(testDescriptor.getServices()).andReturn(serviceMocks).anyTimes();
+ EasyMock.replay(testDescriptor);
+
+ // Invoke the simple descriptor handler
+ Map<String, File> files =
+ SimpleDescriptorHandler.handle(testDescriptor,
+ providerConfig.getParentFile(), // simple desc co-located with provider config
+ destDir);
+ topologyFile = files.get("topology");
+
+ // Validate the resulting topology descriptor
+ assertTrue(topologyFile.exists());
+
+ // Validate the topology descriptor's correctness
+ TopologyValidator validator = new TopologyValidator( topologyFile.getAbsolutePath() );
+ if( !validator.validateTopology() ){
+ throw new SAXException( validator.getErrorString() );
+ }
+
+ XPathFactory xPathfactory = XPathFactory.newInstance();
+ XPath xpath = xPathfactory.newXPath();
+
+ // Parse the topology descriptor
+ Document topologyXml = XmlUtils.readXml(topologyFile);
+
++ // KNOX-1105 Mark generated topology files
++ assertThat("Expected the \"generated\" marker element in the topology XML, with value of \"true\".",
++ topologyXml,
++ hasXPath("/topology/generated", is("true")));
++
+ // Validate the provider configuration
+ Document extProviderConf = XmlUtils.readXml(new ByteArrayInputStream(TEST_PROVIDER_CONFIG.getBytes()));
+ Node gatewayNode = (Node) xpath.compile("/topology/gateway").evaluate(topologyXml, XPathConstants.NODE);
+ assertTrue("Resulting provider config should be identical to the referenced content.",
+ extProviderConf.getDocumentElement().isEqualNode(gatewayNode));
+
+ // Validate the service declarations
+ Map<String, List<String>> topologyServiceURLs = new HashMap<>();
+ NodeList serviceNodes =
+ (NodeList) xpath.compile("/topology/service").evaluate(topologyXml, XPathConstants.NODESET);
+ for (int serviceNodeIndex=0; serviceNodeIndex < serviceNodes.getLength(); serviceNodeIndex++) {
+ Node serviceNode = serviceNodes.item(serviceNodeIndex);
+
+ // Validate the role
+ Node roleNode = (Node) xpath.compile("role/text()").evaluate(serviceNode, XPathConstants.NODE);
+ assertNotNull(roleNode);
+ String role = roleNode.getNodeValue();
+
+ // Validate the URLs
+ NodeList urlNodes = (NodeList) xpath.compile("url/text()").evaluate(serviceNode, XPathConstants.NODESET);
+ for(int urlNodeIndex = 0 ; urlNodeIndex < urlNodes.getLength(); urlNodeIndex++) {
+ Node urlNode = urlNodes.item(urlNodeIndex);
+ assertNotNull(urlNode);
+ String url = urlNode.getNodeValue();
+
+ // If the service should have a URL (some don't require it)
+ if (serviceURLs.containsKey(role)) {
+ assertNotNull("Declared service should have a URL.", url);
+ if (!topologyServiceURLs.containsKey(role)) {
+ topologyServiceURLs.put(role, new ArrayList<>());
+ }
+ topologyServiceURLs.get(role).add(url); // Add it for validation later
+ }
+ }
+
+ // If params were declared in the descriptor, then validate them in the resulting topology file
+ Map<String, String> params = serviceParameters.get(role);
+ if (params != null) {
+ NodeList paramNodes = (NodeList) xpath.compile("param").evaluate(serviceNode, XPathConstants.NODESET);
+ for (int paramNodeIndex = 0; paramNodeIndex < paramNodes.getLength(); paramNodeIndex++) {
+ Node paramNode = paramNodes.item(paramNodeIndex);
+ String paramName = (String) xpath.compile("name/text()").evaluate(paramNode, XPathConstants.STRING);
+ String paramValue = (String) xpath.compile("value/text()").evaluate(paramNode, XPathConstants.STRING);
+ assertTrue(params.keySet().contains(paramName));
+ assertEquals(params.get(paramName), paramValue);
+ }
+ }
+
+ }
+ assertEquals("Unexpected number of service declarations.", (serviceURLs.size() - 1), topologyServiceURLs.size());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } finally {
+ providerConfig.delete();
+ discoveryConfig.delete();
+ if (topologyFile != null) {
+ topologyFile.delete();
+ }
+ }
+ }
+
+
+ /**
+ * KNOX-1006
+ *
+ * Verify the behavior of the SimpleDescriptorHandler when service discovery fails to produce a valid URL for
+ * a service.
+ *
+ * N.B. This test depends on the PropertiesFileServiceDiscovery extension being configured:
+ * org.apache.knox.gateway.topology.discovery.test.extension.PropertiesFileServiceDiscovery
+ */
+ @Test
+ public void testInvalidServiceURLFromDiscovery() throws Exception {
+ final String CLUSTER_NAME = "myproperties";
+
+ // Configure the PropertiesFile Service Discovery implementation for this test
+ final String DEFAULT_VALID_SERVICE_URL = "http://localhost:9999/thiswillwork";
+ Properties serviceDiscoverySourceProps = new Properties();
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".NAMENODE",
+ DEFAULT_VALID_SERVICE_URL.replace("http", "hdfs"));
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".JOBTRACKER",
+ DEFAULT_VALID_SERVICE_URL.replace("http", "rpc"));
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".WEBHDFS", DEFAULT_VALID_SERVICE_URL);
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".WEBHCAT", DEFAULT_VALID_SERVICE_URL);
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".OOZIE", DEFAULT_VALID_SERVICE_URL);
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".WEBHBASE", DEFAULT_VALID_SERVICE_URL);
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".HIVE", "{SCHEME}://localhost:10000/");
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".RESOURCEMANAGER", DEFAULT_VALID_SERVICE_URL);
+ serviceDiscoverySourceProps.setProperty(CLUSTER_NAME + ".AMBARIUI", DEFAULT_VALID_SERVICE_URL);
+ File serviceDiscoverySource = File.createTempFile("service-discovery", ".properties");
+ serviceDiscoverySourceProps.store(new FileOutputStream(serviceDiscoverySource),
+ "Test Service Discovery Source");
+
+ // Prepare a mock SimpleDescriptor
+ final String type = "PROPERTIES_FILE";
+ final String address = serviceDiscoverySource.getAbsolutePath();
+ final Map<String, List<String>> serviceURLs = new HashMap<>();
+ serviceURLs.put("NAMENODE", null);
+ serviceURLs.put("JOBTRACKER", null);
+ serviceURLs.put("WEBHDFS", null);
+ serviceURLs.put("WEBHCAT", null);
+ serviceURLs.put("OOZIE", null);
+ serviceURLs.put("WEBHBASE", null);
+ serviceURLs.put("HIVE", null);
+ serviceURLs.put("RESOURCEMANAGER", null);
+ serviceURLs.put("AMBARIUI", Collections.singletonList("http://c6401.ambari.apache.org:8080"));
+
+ // Write the externalized provider config to a temp file
+ File providerConfig = writeProviderConfig("ambari-cluster-policy.xml", TEST_PROVIDER_CONFIG);
+
+ File topologyFile = null;
+ try {
+ File destDir = (new File(".")).getCanonicalFile();
+
+ // Mock out the simple descriptor
+ SimpleDescriptor testDescriptor = EasyMock.createNiceMock(SimpleDescriptor.class);
+ EasyMock.expect(testDescriptor.getName()).andReturn("mysimpledescriptor").anyTimes();
+ EasyMock.expect(testDescriptor.getDiscoveryAddress()).andReturn(address).anyTimes();
+ EasyMock.expect(testDescriptor.getDiscoveryType()).andReturn(type).anyTimes();
+ EasyMock.expect(testDescriptor.getDiscoveryUser()).andReturn(null).anyTimes();
+ EasyMock.expect(testDescriptor.getProviderConfig()).andReturn(providerConfig.getAbsolutePath()).anyTimes();
+ EasyMock.expect(testDescriptor.getClusterName()).andReturn(CLUSTER_NAME).anyTimes();
+ List<SimpleDescriptor.Service> serviceMocks = new ArrayList<>();
+ for (String serviceName : serviceURLs.keySet()) {
+ SimpleDescriptor.Service svc = EasyMock.createNiceMock(SimpleDescriptor.Service.class);
+ EasyMock.expect(svc.getName()).andReturn(serviceName).anyTimes();
+ EasyMock.expect(svc.getURLs()).andReturn(serviceURLs.get(serviceName)).anyTimes();
+ EasyMock.replay(svc);
+ serviceMocks.add(svc);
+ }
+ EasyMock.expect(testDescriptor.getServices()).andReturn(serviceMocks).anyTimes();
+ EasyMock.replay(testDescriptor);
+
+ // Invoke the simple descriptor handler
+ Map<String, File> files =
+ SimpleDescriptorHandler.handle(testDescriptor,
+ providerConfig.getParentFile(), // simple desc co-located with provider config
+ destDir);
+
+ topologyFile = files.get("topology");
+
+ // Validate the resulting topology descriptor
+ assertTrue(topologyFile.exists());
+
+ // Validate the topology descriptor's correctness
+ TopologyValidator validator = new TopologyValidator( topologyFile.getAbsolutePath() );
+ if( !validator.validateTopology() ){
+ throw new SAXException( validator.getErrorString() );
+ }
+
+ XPathFactory xPathfactory = XPathFactory.newInstance();
+ XPath xpath = xPathfactory.newXPath();
+
+ // Parse the topology descriptor
+ Document topologyXml = XmlUtils.readXml(topologyFile);
+
+ // Validate the provider configuration
+ Document extProviderConf = XmlUtils.readXml(new ByteArrayInputStream(TEST_PROVIDER_CONFIG.getBytes()));
+ Node gatewayNode = (Node) xpath.compile("/topology/gateway").evaluate(topologyXml, XPathConstants.NODE);
+ assertTrue("Resulting provider config should be identical to the referenced content.",
+ extProviderConf.getDocumentElement().isEqualNode(gatewayNode));
+
+ // Validate the service declarations
+ List<String> topologyServices = new ArrayList<>();
+ Map<String, List<String>> topologyServiceURLs = new HashMap<>();
+ NodeList serviceNodes =
+ (NodeList) xpath.compile("/topology/service").evaluate(topologyXml, XPathConstants.NODESET);
+ for (int serviceNodeIndex=0; serviceNodeIndex < serviceNodes.getLength(); serviceNodeIndex++) {
+ Node serviceNode = serviceNodes.item(serviceNodeIndex);
+ Node roleNode = (Node) xpath.compile("role/text()").evaluate(serviceNode, XPathConstants.NODE);
+ assertNotNull(roleNode);
+ String role = roleNode.getNodeValue();
+ topologyServices.add(role);
+ NodeList urlNodes = (NodeList) xpath.compile("url/text()").evaluate(serviceNode, XPathConstants.NODESET);
+ for(int urlNodeIndex = 0 ; urlNodeIndex < urlNodes.getLength(); urlNodeIndex++) {
+ Node urlNode = urlNodes.item(urlNodeIndex);
+ assertNotNull(urlNode);
+ String url = urlNode.getNodeValue();
+ assertNotNull("Every declared service should have a URL.", url);
+ if (!topologyServiceURLs.containsKey(role)) {
+ topologyServiceURLs.put(role, new ArrayList<>());
+ }
+ topologyServiceURLs.get(role).add(url);
+ }
+ }
+
+ // There should not be a service element for HIVE, since it had no valid URLs
+ assertEquals("Unexpected number of service declarations.", serviceURLs.size() - 1, topologyServices.size());
+ assertFalse("The HIVE service should have been omitted from the generated topology.", topologyServices.contains("HIVE"));
+
+ assertEquals("Unexpected number of service URLs.", serviceURLs.size() - 1, topologyServiceURLs.size());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } finally {
+ serviceDiscoverySource.delete();
+ providerConfig.delete();
+ if (topologyFile != null) {
+ topologyFile.delete();
+ }
+ }
+ }
+
+
+ private File writeProviderConfig(String path, String content) throws IOException {
+ File f = new File(path);
+ FileUtils.write(f, content);
+ return f;
+ }
+
+}