You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2014/06/19 16:44:19 UTC
git commit: KNOX-395 POC for Jersey Topology Service from Knox
Repository: knox
Updated Branches:
refs/heads/master 10de69b67 -> 4ca54c5a1
KNOX-395 POC for Jersey Topology Service from Knox
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/4ca54c5a
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/4ca54c5a
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/4ca54c5a
Branch: refs/heads/master
Commit: 4ca54c5a13e7bbf600a483cdebd653e8adcbc2a9
Parents: 10de69b
Author: Larry McCay <lm...@hortonworks.com>
Authored: Thu Jun 19 10:44:01 2014 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Thu Jun 19 10:44:01 2014 -0400
----------------------------------------------------------------------
.../JerseyServiceDeploymentContributorBase.java | 6 +-
gateway-service-vault/pom.xml | 59 ++
.../service/vault/CredentialResource.java | 128 +++
.../VaultServiceDeploymentContributor.java | 60 ++
....gateway.deploy.ServiceDeploymentContributor | 19 +
gateway-test/pom.xml | 5 +
.../util/urltemplate/MatcherTest.java.orig | 839 +++++++++++++++++++
pom.xml | 10 +-
8 files changed, 1123 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-provider-jersey/src/main/java/org/apache/hadoop/gateway/jersey/JerseyServiceDeploymentContributorBase.java
----------------------------------------------------------------------
diff --git a/gateway-provider-jersey/src/main/java/org/apache/hadoop/gateway/jersey/JerseyServiceDeploymentContributorBase.java b/gateway-provider-jersey/src/main/java/org/apache/hadoop/gateway/jersey/JerseyServiceDeploymentContributorBase.java
index fb7ac39..dc8a340 100644
--- a/gateway-provider-jersey/src/main/java/org/apache/hadoop/gateway/jersey/JerseyServiceDeploymentContributorBase.java
+++ b/gateway-provider-jersey/src/main/java/org/apache/hadoop/gateway/jersey/JerseyServiceDeploymentContributorBase.java
@@ -30,6 +30,7 @@ import java.util.List;
public abstract class JerseyServiceDeploymentContributorBase extends ServiceDeploymentContributorBase {
private static final String PACKAGES_PARAM = "jersey.config.server.provider.packages";
+ private static final String TRACE_LOGGING_PARAM = "jersey.config.server.tracing";
protected abstract String[] getPackages();
@@ -50,8 +51,11 @@ public abstract class JerseyServiceDeploymentContributorBase extends ServiceDepl
param.name( PACKAGES_PARAM );
param.value( packages );
params.add( param );
+// FilterParamDescriptor trace = resource.createFilterParam();
+// param.name( TRACE_LOGGING_PARAM );
+// param.value( "ALL" );
+// params.add( trace );
context.contributeFilter( service, resource, "pivot", "jersey", params );
}
}
-
}
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-service-vault/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-vault/pom.xml b/gateway-service-vault/pom.xml
new file mode 100644
index 0000000..9dab0dd
--- /dev/null
+++ b/gateway-service-vault/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.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.
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>gateway</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>gateway-service-vault</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <name>gateway-service-vault</name>
+ <url>http://maven.apache.org</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-provider-rewrite</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-provider-jersey</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.owlike</groupId>
+ <artifactId>genson</artifactId>
+ <version>0.99</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/CredentialResource.java
----------------------------------------------------------------------
diff --git a/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/CredentialResource.java b/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/CredentialResource.java
new file mode 100644
index 0000000..9f60624
--- /dev/null
+++ b/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/CredentialResource.java
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.service.vault;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.AliasService;
+
+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_TYPE;
+import static javax.ws.rs.core.Response.created;
+import static javax.ws.rs.core.Response.ok;
+import static javax.ws.rs.core.Response.serverError;
+import static javax.ws.rs.core.Response.status;
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+
+@Path( "/vault/credentials" )
+public class CredentialResource {
+ @Context
+ private HttpServletRequest request;
+
+ @GET
+ @Path("{alias}")
+ @Produces({APPLICATION_JSON, APPLICATION_XML})
+ public Response getCredential(@PathParam("alias") String alias) {
+ if (alias != null && !alias.isEmpty()) {
+ CredentialValue value = getCredentialValueForAlias(alias);
+ if (value != null) {
+ return ok(value).build();
+ } else {
+ return status(NOT_FOUND).build();
+ }
+ } else {
+ return status(BAD_REQUEST).
+ entity("Please provide a credential alias in the path").
+ type(TEXT_PLAIN_TYPE).build();
+ }
+ }
+
+ @GET
+ @Produces({APPLICATION_JSON, APPLICATION_XML})
+ public Response getCredentials() {
+ List<String> aliases = getCredentialsList();
+ if (aliases != null) {
+ return ok(aliases).build();
+ } else {
+ return status(NOT_FOUND).build();
+ }
+ }
+
+ /**
+ * @return
+ */
+ private List<String> getCredentialsList() {
+ GatewayServices services = (GatewayServices)request.getServletContext().
+ getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ String clusterName = (String) request.getServletContext().getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE);
+ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
+ List<String> aliases = as.getAliasesForCluster(clusterName);
+ return aliases;
+ }
+
+ /**
+ * @param alias
+ * @return
+ */
+ private CredentialValue getCredentialValueForAlias(String alias) {
+ GatewayServices services = (GatewayServices)request.getServletContext().
+ getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ String clusterName = (String) request.getServletContext().getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE);
+ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
+ char[] credential = as.getPasswordFromAliasForCluster(clusterName, alias);
+ if (credential != null) {
+ return new CredentialValue(alias, new String(credential));
+ }
+ return null;
+ }
+
+ public static class CredentialValue {
+ private String alias;
+ private String credential;
+
+ public CredentialValue(String alias, String credential) {
+ super();
+ this.alias = alias;
+ this.credential = credential;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+ public void setAlias(String alias) {
+ this.alias = alias;
+ }
+ public String getCredential() {
+ return credential;
+ }
+ public void setCredential(String credential) {
+ this.credential = credential;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/deploy/VaultServiceDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/deploy/VaultServiceDeploymentContributor.java b/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/deploy/VaultServiceDeploymentContributor.java
new file mode 100644
index 0000000..b834cb4
--- /dev/null
+++ b/gateway-service-vault/src/main/java/org/apache/hadoop/gateway/service/vault/deploy/VaultServiceDeploymentContributor.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.gateway.service.vault.deploy;
+
+import org.apache.hadoop.gateway.jersey.JerseyServiceDeploymentContributorBase;
+
+/**
+ *
+ */
+public class VaultServiceDeploymentContributor extends JerseyServiceDeploymentContributorBase {
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor#getRole()
+ */
+ @Override
+ public String getRole() {
+ // TODO Auto-generated method stub
+ return "VAULT";
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor#getName()
+ */
+ @Override
+ public String getName() {
+ return "KnoxVaultService";
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.jersey.JerseyServiceDeploymentContributorBase#getPackages()
+ */
+ @Override
+ protected String[] getPackages() {
+ return new String[]{ "org.apache.hadoop.gateway.service.vault" };
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.jersey.JerseyServiceDeploymentContributorBase#getPatterns()
+ */
+ @Override
+ protected String[] getPatterns() {
+ return new String[]{ "vault/**?**" };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-service-vault/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-service-vault/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor b/gateway-service-vault/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
new file mode 100644
index 0000000..fc73269
--- /dev/null
+++ b/gateway-service-vault/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.hadoop.gateway.service.vault.deploy.VaultServiceDeploymentContributor
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-test/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-test/pom.xml b/gateway-test/pom.xml
index 736b66d..ba7d86d 100644
--- a/gateway-test/pom.xml
+++ b/gateway-test/pom.xml
@@ -40,6 +40,11 @@
<artifactId>gateway-provider-jersey</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
+ <artifactId>gateway-service-vault</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>${gateway-group}</groupId>
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java.orig
----------------------------------------------------------------------
diff --git a/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java.orig b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java.orig
new file mode 100644
index 0000000..6b6012b
--- /dev/null
+++ b/gateway-util-urltemplate/src/test/java/org/apache/hadoop/gateway/util/urltemplate/MatcherTest.java.orig
@@ -0,0 +1,839 @@
+/**
+ * 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.util.urltemplate;
+
+
+import org.apache.hadoop.test.category.FastTests;
+import org.apache.hadoop.test.category.UnitTests;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.net.URISyntaxException;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.hamcrest.core.IsCollectionContaining.hasItem;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+
+//TODO: Test to make sure that extra unmatched query parameters prevent a match.
+@Category( { UnitTests.class, FastTests.class } )
+public class MatcherTest {
+
+ private void addTemplate( Matcher<String> matcher, String template ) throws URISyntaxException {
+ matcher.add( Parser.parse( template ), template );
+ }
+
+ private void assertValidMatch( Matcher<String> matcher, String uri, String template ) throws URISyntaxException {
+ if( template == null ) {
+ assertThat( matcher.match( Parser.parse( uri ) ), nullValue() );
+ } else {
+ Template uriTemplate = Parser.parse( uri );
+ Matcher<String>.Match match = matcher.match( uriTemplate );
+ assertThat( "Expected to find a match.", match, notNullValue() );
+ assertThat( match.getValue(), equalTo( template ) );
+ }
+ }
+
+ @Test
+ public void testWildcardCharacterInInputTemplate() throws URISyntaxException {
+ Matcher<String> matcher;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ // First verify that if .../test_table/test_row/family1... works.
+ matcher = new Matcher<String>();
+ inputTemplate = Parser.parse( "https://localhost:8443/gateway/sandbox/hbase/test_table/test_row/family1:row2_col1,family2/0,9223372036854775807?v=1" );
+ patternTemplate = Parser.parse( "*://*:*/**/webhdfs/{version}/{path=**}?{**}" );
+ matcher.add( patternTemplate, "webhdfs" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+
+ // Then reproduce the issue with .../test_table/*/family1..
+ matcher = new Matcher<String>();
+ inputTemplate = Parser.parse( "https://localhost:8443/gateway/sandbox/hbase/test_table/*/family1:row2_col1,family2/0,9223372036854775807?v=1" );
+ patternTemplate = Parser.parse( "*://*:*/**/webhdfs/{version}/{path=**}?{**}" );
+ matcher.add( patternTemplate, "webhdfs" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+
+ // Reproduce the issue where the wrong match was picked when there was a "*" in the input URL template.
+ matcher = new Matcher<String>();
+ inputTemplate = Parser.parse( "https://localhost:8443/gateway/sandbox/hbase/test_table/*/family1:row2_col1,family2/0,9223372036854775807?v=1" );
+ patternTemplate = Parser.parse( "*://*:*/**/webhdfs/{version}/{path=**}?{**}" );
+ matcher.add( patternTemplate, "webhdfs" );
+ patternTemplate = Parser.parse( "*://*:*/**/hbase/{path=**}?{**}" );
+ matcher.add( patternTemplate, "hbase" );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getValue(), is( "hbase" ) );
+ }
+
+ @Test
+ public void testDefaultAppDeployment() throws Exception {
+ Matcher<String> matcher;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ matcher = new Matcher<String>();
+ inputTemplate = Parser.parse( "https://localhost:8443/webhdfs/v1/tmp?op=LISTSTATUS" );
+ patternTemplate = Parser.parse( "*://*:*/webhdfs/{version}/{path=**}?{**}" );
+ matcher.add( patternTemplate, "webhdfs" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+ }
+
+ @Test
+ public void testRootPathMatching() throws Exception {
+ Matcher<String> matcher;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ ///////
+ patternTemplate = Parser.parse( "*://*:*" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-match" );
+
+ inputTemplate = Parser.parse( "test-scheme://test-host:42" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/test-path" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+
+ ///////
+ patternTemplate = Parser.parse( "*://*:*/" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-match" );
+
+ inputTemplate = Parser.parse( "test-scheme://test-host:42" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/test-path" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+
+ ///////
+ patternTemplate = Parser.parse( "*://*:*/*" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-match" );
+
+ inputTemplate = Parser.parse( "test-scheme://test-host:42" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/test-path" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+
+ ///////
+ patternTemplate = Parser.parse( "*://*:*/**" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-match" );
+
+//KM: I'm not sure what the correct behavior is here.
+// inputTemplate = Parser.parse( "test-scheme://test-host:42" );
+// match = matcher.match( inputTemplate );
+// assertThat( match, ? );
+// inputTemplate = Parser.parse( "test-scheme://test-host:42/" );
+// match = matcher.match( inputTemplate );
+// assertThat( match, ? );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/test-path" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+
+ ///////
+ patternTemplate = Parser.parse( "*://*:*/{path=*}" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-match" );
+
+ inputTemplate = Parser.parse( "test-scheme://test-host:42" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/test-path" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+
+ ///////
+ patternTemplate = Parser.parse( "*://*:*/{path=**}" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-match" );
+
+//KM: I'm not sure what the correct behavior is here.
+// inputTemplate = Parser.parse( "test-scheme://test-host:42" );
+// match = matcher.match( inputTemplate );
+// assertThat( match, ? );
+// inputTemplate = Parser.parse( "test-scheme://test-host:42/" );
+// match = matcher.match( inputTemplate );
+// assertThat( match, ? );
+ inputTemplate = Parser.parse( "test-scheme://test-host:42/test-path" );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+ }
+
+ @Test
+ public void testTopLevelPathGlobMatch() throws Exception {
+ Matcher<String> matcher;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ patternTemplate = Parser.parse( "{*}://{host}:{*}/{**=**}?{**}" );
+ inputTemplate = Parser.parse( "test-scheme://test-input-host:42/test-path/test-file?test-name=test-value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-math" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because the path ** should include both test-path and test-file", match, notNullValue() );
+
+ patternTemplate = Parser.parse( "{*}://{host}:{*}/{**}?{**}" );
+ inputTemplate = Parser.parse( "test-scheme://test-input-host:42/test-path/test-file?test-name=test-value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "test-math" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because the path ** should include both test-path and test-file", match, notNullValue() );
+ }
+
+ @Test
+ public void testQueryHandling() throws Exception {
+ Matcher<String> matcher;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ patternTemplate = Parser.parse( "/path?{query}" );
+ inputTemplate = Parser.parse( "/path" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should not match because input does not contain the required query.", match, nullValue() );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/path?{query}" ), "T1" );
+ matcher.add( Parser.parse( "/path" ), "T2" );
+ inputTemplate = Parser.parse( "/path" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because there is an entry in the matcher without a query.", match, notNullValue() );
+ assertThat( match.getValue(), equalTo( "T2") );
+
+ patternTemplate = Parser.parse( "/path?{query}" );
+ inputTemplate = Parser.parse( "/path?query=value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because input does contain the required query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value" ) );
+ assertThat( match.getParams().resolve( "query" ).size(), equalTo( 1 ) );
+
+ patternTemplate = Parser.parse( "/path?{*}" );
+ inputTemplate = Parser.parse( "/path" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should not match because input does not contain the required query.", match, nullValue() );
+
+ patternTemplate = Parser.parse( "/path?*" );
+ inputTemplate = Parser.parse( "/path" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should not match because input does not contain the required query.", match, nullValue() );
+
+ patternTemplate = Parser.parse( "/path?*" );
+ inputTemplate = Parser.parse( "/path?query=value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat(
+ "Should match because the template has an extra query and the input has a query.",
+ match, notNullValue() );
+ assertThat(
+ "Should not have extracts any parameters since pattern template didn't contain {}",
+ match.getParams().resolve( "query" ), nullValue() );
+
+ patternTemplate = Parser.parse( "/path?{*}" );
+ inputTemplate = Parser.parse( "/path?query=value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because input does contain the required query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value" ) );
+
+ patternTemplate = Parser.parse( "/path?{**}" );
+ inputTemplate = Parser.parse( "/path" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because the template has an optional query.", match, notNullValue() );
+
+ patternTemplate = Parser.parse( "/path?**" );
+ inputTemplate = Parser.parse( "/path" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because the template has an optional extra query.", match, notNullValue() );
+
+ patternTemplate = Parser.parse( "/path?**" );
+ inputTemplate = Parser.parse( "/path?query=value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because the template has an optional extra query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), nullValue() );
+
+ patternTemplate = Parser.parse( "/path?{**}" );
+ inputTemplate = Parser.parse( "/path?query=value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because the template has an optional extra query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value" ) );
+ assertThat( match.getParams().resolve( "query" ).size(), equalTo( 1 ) );
+
+ patternTemplate = Parser.parse( "/path?{query}&{*}" );
+ inputTemplate = Parser.parse( "/path?query=value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should not match because input does not contain the required extra query.", match, nullValue() );
+
+ patternTemplate = Parser.parse( "/path?{query}&{*}" );
+ inputTemplate = Parser.parse( "/path?query=value&extra=extra-value" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because input does contain the required query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value" ) );
+ assertThat( match.getParams().resolve( "query" ).size(), equalTo( 1 ) );
+
+ patternTemplate = Parser.parse( "/path?{query=**}" );
+ inputTemplate = Parser.parse( "/path?query=value1&query=value2" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because input does contain the required query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value1" ) );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value2" ) );
+ assertThat( match.getParams().resolve( "query" ).size(), equalTo( 2 ) );
+
+ patternTemplate = Parser.parse( "/path?{query}" );
+ inputTemplate = Parser.parse( "/path?query=value1&query=value2" );
+ matcher = new Matcher<String>();
+ matcher.add( patternTemplate, "T" );
+ match = matcher.match( inputTemplate );
+ assertThat( "Should match because input does contain the required query.", match, notNullValue() );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value1" ) );
+ assertThat( match.getParams().resolve( "query" ), hasItem( "value2" ) );
+ assertThat( match.getParams().resolve( "query" ).size(), equalTo( 2 ) );
+ }
+
+ @Test
+ public void testMatchCompleteUrl() throws Exception {
+ Matcher<String> matcher;
+ String pattern, input;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ matcher = new Matcher<String>();
+ pattern = "foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+ matcher = new Matcher<String>();
+ pattern = "foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+
+ input = pattern;
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match, notNullValue() );
+
+ input = "not://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match, nullValue() );
+ }
+
+ @Test
+ public void testMatch() throws Exception {
+ Matcher<String> matcher;
+ String pattern, input;
+ Template patternTemplate, inputTemplate;
+ Matcher<String>.Match match;
+
+ matcher = new Matcher<String>();
+ pattern = "path";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ assertThat( matcher.get( patternTemplate ), is( pattern ) );
+ input = "path";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+
+ matcher = new Matcher<String>();
+ pattern = "/path";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "/path";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+ matcher = new Matcher<String>();
+ pattern = "path/path";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "path/path";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+ matcher = new Matcher<String>();
+ pattern = "*/path";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "pathA/path";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+ matcher = new Matcher<String>();
+ pattern = "**/path";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "pathA/pathB/path";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+ matcher = new Matcher<String>();
+ pattern = "path-1/{path=**}/path-4";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "path-1/path-2/path-3/path-4";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+ assertThat( match.getParams().resolve( "path" ).get( 0 ), equalTo( "path-2" ) );
+ assertThat( match.getParams().resolve( "path" ).get( 1 ), equalTo( "path-3" ) );
+
+ matcher = new Matcher<String>();
+ pattern = "/";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "/";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+
+ matcher = new Matcher<String>();
+ pattern = "";
+ patternTemplate = Parser.parse( pattern );
+ matcher.add( patternTemplate, pattern );
+ input = "";
+ inputTemplate = Parser.parse( input );
+ match = matcher.match( inputTemplate );
+ assertThat( match.getTemplate(), sameInstance( patternTemplate ) );
+ assertThat( match.getValue(), equalTo( pattern ) );
+ }
+
+ @Test
+ public void testVariousPatterns() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs" ), "/webhdfs" );
+ matcher.add( Parser.parse( "/webhdfs/dfshealth.jsp" ), "/webhdfs/dfshealth.jsp" );
+ matcher.add( Parser.parse( "/webhdfs/*.jsp" ), "/webhdfs/*.jsp" );
+ matcher.add( Parser.parse( "/webhdfs/other.jsp" ), "/webhdfs/other.jsp" );
+ matcher.add( Parser.parse( "/webhdfs/*" ), "/webhdfs/*" );
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ matcher.add( Parser.parse( "/webhdfs/v1/**" ), "/webhdfs/v1/**" );
+ matcher.add( Parser.parse( "/webhdfs/**/middle/*.xml" ), "/webhdfs/**/middle/*.xml" );
+
+ assertValidMatch( matcher, "/webhdfs", "/webhdfs" );
+ assertValidMatch( matcher, "/webhdfs/dfshealth.jsp", "/webhdfs/dfshealth.jsp" );
+ assertValidMatch( matcher, "/webhdfs/v1", "/webhdfs/*" ); // The star should be picked in preference to the glob.
+ assertValidMatch( matcher, "/webhdfs/some.jsp", "/webhdfs/*.jsp" );
+ assertValidMatch( matcher, "/webhdfs/other.jsp", "/webhdfs/other.jsp" );
+ assertValidMatch( matcher, "/webhdfs/path/some.jsp", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/path/middle/some.jsp", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/path/middle/some.xml", "/webhdfs/**/middle/*.xml" );
+ assertValidMatch( matcher, "/webhdfs/path/to/file", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/v1/path/to/file", "/webhdfs/v1/**" );
+ }
+
+ @Test
+ public void testStar() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/*" ), "/webhdfs/*" );
+ assertValidMatch( matcher, "/webhdfs/*", "/webhdfs/*" );
+ assertValidMatch( matcher, "/webhdfs/file", "/webhdfs/*" );
+ assertValidMatch( matcher, "/webhdfs/path/", "/webhdfs/*" );
+ assertValidMatch( matcher, "/webhdfs/path/file", null );
+ assertValidMatch( matcher, "/webhdfs/path/path/", null );
+ }
+
+ @Test
+ public void testGlob() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/file", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/path/", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/path/file", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/path/path/", "/webhdfs/**" );
+ }
+
+ @Test
+ public void testMatrixParam() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ matcher.add( Parser.parse( "/webhdfs/browseDirectory.jsp;dn=*" ), "/webhdfs/browseDirectory.jsp;dn=*" );
+ assertValidMatch( matcher, "/webhdfs/browseDirectory.jsp;dn=X", "/webhdfs/browseDirectory.jsp;dn=*" );
+ }
+
+ @Test
+ public void testTwoGlobsAtDifferentDepths() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ matcher.add( Parser.parse( "/webhdfs/v1/**" ), "/webhdfs/v1/**" );
+ assertValidMatch( matcher, "/webhdfs/file", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/v1/file", "/webhdfs/v1/**" );
+
+ // Reverse the put order.
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/v1/**" ), "/webhdfs/v1/**" );
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/file", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/v1/file", "/webhdfs/v1/**" );
+ }
+
+ @Test
+ public void testGlobsVsStarsAtSameDepth() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/*" ), "/webhdfs/*" );
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/file", "/webhdfs/*" ); // The star should be picked in preference to the glob.
+ assertValidMatch( matcher, "/webhdfs/path/file", "/webhdfs/**" );
+
+ // Reverse the put order.
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/webhdfs/**" ), "/webhdfs/**" );
+ matcher.add( Parser.parse( "/webhdfs/*" ), "/webhdfs/*" );
+ assertValidMatch( matcher, "/webhdfs/path/file", "/webhdfs/**" );
+ assertValidMatch( matcher, "/webhdfs/file", "/webhdfs/*" );
+ }
+
+ @Test
+ public void testMatchingPatternsWithinPathSegments() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/path/{file}" ), "default" );
+ assertValidMatch( matcher, "/path/file-name", "default" );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/path/{file=*}" ), "*" );
+ assertValidMatch( matcher, "/path/some-name", "*" );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/path/{more=**}" ), "**" );
+ assertValidMatch( matcher, "/path/some-path/some-name", "**" );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "/path/{regex=prefix*suffix}" ), "regex" );
+ assertValidMatch( matcher, "/path/prefix-middle-suffix", "regex" );
+ assertValidMatch( matcher, "/path/not-prefix-middle-suffix", null );
+ }
+
+ @Test
+ public void testMatchingPatternsWithinQuerySegments() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "?query={queryParam}" ), "default" );
+ assertValidMatch( matcher, "?query=value", "default" );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "?query={queryParam=*}" ), "*" );
+ assertValidMatch( matcher, "?query=some-value", "*" );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "?query={queryParam=**}" ), "**" );
+ assertValidMatch( matcher, "?query=some-value", "**" );
+
+ matcher = new Matcher<String>();
+ matcher.add( Parser.parse( "?query={queryParam=prefix*suffix}" ), "regex" );
+ assertValidMatch( matcher, "?query=prefix-middle-suffix", "regex" );
+ assertValidMatch( matcher, "?query=not-prefix-middle-suffix", null );
+ }
+
+ @Test
+ public void testMatchingForTemplatesThatVaryOnlyByQueryParams() throws URISyntaxException {
+ Matcher<String> matcher = new Matcher<String>();
+ addTemplate( matcher, "?one={queryParam}" );
+ addTemplate( matcher, "?two={queryParam}" );
+
+ assertValidMatch( matcher, "?one=value", "?one={queryParam}" );
+ assertValidMatch( matcher, "?two=value", "?two={queryParam}" );
+ assertValidMatch( matcher, "?three=value", null );
+ assertValidMatch( matcher, "?", null );
+ }
+
+ @Test
+ public void testFullUrlExtraction() throws URISyntaxException {
+ Template template;
+ Template input;
+ Matcher<?> matcher;
+ Matcher<?>.Match match;
+ Params params;
+
+ template = Parser.parse( "{scheme}://{username}:{password}@{host}:{port}/{root}/{path}/{file}?queryA={paramA}&queryB={paramB}#{fragment}" );
+ input = Parser.parse( "http://horton:hadoop@hortonworks.com:80/top/middle/end?queryA=valueA&queryB=valueB#section" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+
+ assertThat( params.getNames(), hasItem( "scheme" ) );
+ assertThat( params.resolve( "scheme" ), hasItem( "http" ) );
+ assertThat( params.getNames(), hasItem( "username" ) );
+ assertThat( params.resolve( "username" ), hasItem( "horton" ) );
+ assertThat( params.getNames(), hasItem( "password" ) );
+ assertThat( params.resolve( "password" ), hasItem( "hadoop" ) );
+ assertThat( params.getNames(), hasItem( "host" ) );
+ assertThat( params.resolve( "host" ), hasItem( "hortonworks.com" ) );
+ assertThat( params.getNames(), hasItem( "port" ) );
+ assertThat( params.resolve( "port" ), hasItem( "80" ) );
+ assertThat( params.getNames(), hasItem( "root" ) );
+ assertThat( params.resolve( "root" ), hasItem( "top" ) );
+ assertThat( params.getNames(), hasItem( "path" ) );
+ assertThat( params.resolve( "path" ), hasItem( "middle" ) );
+ assertThat( params.getNames(), hasItem( "file" ) );
+ assertThat( params.resolve( "file" ), hasItem( "end" ) );
+ assertThat( params.getNames(), hasItem( "paramA" ) );
+ assertThat( params.resolve( "paramA" ), hasItem( "valueA" ) );
+ assertThat( params.getNames(), hasItem( "paramB" ) );
+ assertThat( params.resolve( "paramB" ), hasItem( "valueB" ) );
+ assertThat( params.getNames(), hasItem( "fragment" ) );
+ assertThat( params.resolve( "fragment" ), hasItem( "section" ) );
+ assertThat( params.getNames().size(), equalTo( 11 ) );
+ }
+
+ @Test
+ public void testMultipleDoubleStarPathMatching() throws URISyntaxException {
+ Template template;
+ Template input;
+ Matcher<?> matcher;
+ Matcher<String> stringMatcher;
+ Matcher<?>.Match match;
+
+// template = Parser.parse( "*://*:*/**/webhdfs/v1/**?**" );
+// input = Parser.parse( "http://localhost:53221/gateway/cluster/webhdfs/v1/tmp/GatewayWebHdfsFuncTest/testBasicHdfsUseCase/dir?user.name=hdfs&op=MKDIRS" );
+// matcher = new Matcher<String>( template, "test-value" );
+// match = matcher.match( input );
+// assertThat( (String)match.getValue(), is( "test-value" ) );
+//
+// template = Parser.parse( "*://*:*/**/webhdfs/v1/{path=**}?{**=*}" );
+// input = Parser.parse( "http://localhost:53221/gateway/cluster/webhdfs/v1/tmp/GatewayWebHdfsFuncTest/testBasicHdfsUseCase/dir?user.name=hdfs&op=MKDIRS" );
+// matcher = new Matcher<String>( template, "test-value-2" );
+// match = matcher.match( input );
+// assertThat( (String)match.getValue(), is( "test-value-2" ) );
+//
+// stringMatcher = new Matcher<String>();
+// template = Parser.parse( "*://*:*/**/webhdfs/data/v1/{path=**}?host={host=*}&port={port=*}&{**=*}" );
+// stringMatcher.add( template, "test-value-C" );
+// template = Parser.parse( "*://*:*/**/webhdfs/v1/{path=**}?{**=*}" );
+// stringMatcher.add( template, "test-value-B" );
+// input = Parser.parse( "http://localhost:53221/gateway/cluster/webhdfs/v1/tmp/GatewayWebHdfsFuncTest/testBasicHdfsUseCase/dir?user.name=hdfs&op=MKDIRS" );
+// match = stringMatcher.match( input );
+// assertThat( match.getValue(), notNullValue() );
+// assertThat( (String)match.getValue(), is( "test-value-B" ) );
+
+ // This is just a reverse of the above. The order caused a bug.
+ stringMatcher = new Matcher<String>();
+ template = Parser.parse( "*://*:*/**/webhdfs/v1/{path=**}?{**=*}" );
+ stringMatcher.add( template, "test-value-B" );
+ template = Parser.parse( "*://*:*/**/webhdfs/data/v1/{path=**}?host={host=*}&port={port=*}&{**=*}" );
+ stringMatcher.add( template, "test-value-C" );
+ input = Parser.parse( "http://localhost:53221/gateway/cluster/webhdfs/v1/tmp/GatewayWebHdfsFuncTest/testBasicHdfsUseCase/dir?user.name=hdfs&op=MKDIRS" );
+ match = stringMatcher.match( input );
+ assertThat( match.getValue(), notNullValue() );
+ assertThat( (String)match.getValue(), is( "test-value-B" ) );
+
+ }
+
+ @Test
+ public void testPathExtraction() throws Exception {
+ Template template;
+ Template input;
+ Matcher<?> matcher;
+ Matcher<?>.Match match;
+ Params params;
+
+ template = Parser.parse( "{path-queryParam}" );
+ input = Parser.parse( "path-value" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "path-queryParam" ) );
+ assertThat( params.resolve( "path-queryParam" ).size(), equalTo( 1 ) );
+ assertThat( params.resolve( "path-queryParam" ), hasItem( "path-value" ) );
+
+ template = Parser.parse( "/some-path/{path-queryParam}" );
+ input = Parser.parse( "/some-path/path-value" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "path-queryParam" ) );
+ assertThat( params.resolve( "path-queryParam" ).size(), equalTo( 1 ) );
+ assertThat( params.resolve( "path-queryParam" ), hasItem( "path-value" ) );
+
+ template = Parser.parse( "/some-path/{path-queryParam}/some-other-path" );
+ input = Parser.parse( "/some-path/path-value/some-other-path" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "path-queryParam" ) );
+ assertThat( params.resolve( "path-queryParam" ).size(), equalTo( 1 ) );
+ assertThat( params.resolve( "path-queryParam" ), hasItem( "path-value" ) );
+
+ template = Parser.parse( "{path=**}" );
+ input = Parser.parse( "A/B" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "path" ) );
+ assertThat( params.resolve( "path" ).size(), equalTo( 2 ) );
+ assertThat( params.resolve( "path" ), hasItem( "A" ) );
+ assertThat( params.resolve( "path" ), hasItem( "B" ) );
+
+ template = Parser.parse( "/top/{mid=**}/end" );
+ input = Parser.parse( "/top/A/B/end" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "mid" ) );
+ assertThat( params.resolve( "mid" ).size(), equalTo( 2 ) );
+ assertThat( params.resolve( "mid" ), hasItem( "A" ) );
+ assertThat( params.resolve( "mid" ), hasItem( "B" ) );
+
+ template = Parser.parse( "*://*:*/{path=**}?{**}" );
+ input = Parser.parse( "http://host:port/pathA/pathB" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params.resolve( "path" ), hasItem( "pathA" ) );
+ assertThat( params.resolve( "path" ), hasItem( "pathB" ) );
+ assertThat( params.resolve( "path" ).size(), is( 2 ) );
+
+ template = Parser.parse( "*://*:*/{path=**}?{**}" );
+ input = Parser.parse( "http://host:port/pathA/pathB" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params.resolve( "path" ), hasItem( "pathA" ) );
+ assertThat( params.resolve( "path" ), hasItem( "pathB" ) );
+ assertThat( params.resolve( "path" ).size(), is( 2 ) );
+
+ template = Parser.parse( "*://*:*/{path=**}?{**}" );
+ input = Parser.parse( "http://host:port/pathA/pathB" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params.resolve( "path" ), hasItem( "pathA" ) );
+ assertThat( params.resolve( "path" ), hasItem( "pathB" ) );
+ assertThat( params.resolve( "path" ).size(), is( 2 ) );
+ }
+
+ @Test
+ public void testQueryExtraction() throws Exception {
+ Template template;
+ Template input;
+ Matcher<?> matcher;
+ Matcher<?>.Match match;
+ Params params;
+
+ template = Parser.parse( "?query-queryParam={queryParam-name}" );
+ input = Parser.parse( "?query-queryParam=queryParam-value" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "queryParam-name" ) );
+ assertThat( params.resolve( "queryParam-name" ).size(), equalTo( 1 ) );
+ assertThat( params.resolve( "queryParam-name" ), hasItem( "queryParam-value" ) );
+
+ template = Parser.parse( "?query-queryParam={queryParam-name}" );
+ input = Parser.parse( "?query-queryParam=queryParam-value" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 1 ) );
+ assertThat( params.getNames(), hasItem( "queryParam-name" ) );
+ assertThat( params.resolve( "queryParam-name" ).size(), equalTo( 1 ) );
+ assertThat( params.resolve( "queryParam-name" ), hasItem( "queryParam-value" ) );
+ }
+
+ @Test
+ public void testEdgeCaseExtraction() throws Exception {
+ Template template;
+ Template input;
+ Matcher<?> matcher;
+ Matcher<?>.Match match;
+ Params params;
+
+ template = Parser.parse( "" );
+ input = Parser.parse( "" );
+ matcher = new Matcher<Void>( template, null );
+ match = matcher.match( input );
+ params = match.getParams();
+ assertThat( params, notNullValue() );
+ assertThat( params.getNames().size(), equalTo( 0 ) );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/4ca54c5a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d99c952..d7281ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,6 +66,7 @@
<module>gateway-release</module>
<module>gateway-test</module>
<module>hsso-release</module>
+ <module>gateway-service-vault</module>
</modules>
<properties>
@@ -425,6 +426,11 @@
</dependency>
<dependency>
<groupId>${gateway-group}</groupId>
+ <artifactId>gateway-service-vault</artifactId>
+ <version>${gateway-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${gateway-group}</groupId>
<artifactId>gateway-service-as</artifactId>
<version>${gateway-version}</version>
</dependency>
@@ -497,12 +503,12 @@
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
- <version>2.4.1</version>
+ <version>2.6</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
- <version>2.4</version>
+ <version>2.6</version>
</dependency>
<dependency>