KNOX-711 Added the ability to scope rewrite rules
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessor.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessor.java
index a3f048c..1c97dc2 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessor.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessor.java
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.gateway.filter.rewrite.api;
+import org.apache.hadoop.gateway.filter.rewrite.ext.ScopedMatcher;
import org.apache.hadoop.gateway.filter.rewrite.i18n.UrlRewriteMessages;
import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteContextImpl;
import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteFunctionProcessorFactory;
@@ -32,6 +33,7 @@
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import static org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriter.Direction.IN;
@@ -44,8 +46,8 @@
UrlRewriteEnvironment environment;
UrlRewriteRulesDescriptor descriptor;
Map<String,UrlRewriteRuleProcessorHolder> rules = new HashMap<String,UrlRewriteRuleProcessorHolder>();
- Matcher<UrlRewriteRuleProcessorHolder> inbound = new Matcher<UrlRewriteRuleProcessorHolder>();
- Matcher<UrlRewriteRuleProcessorHolder> outbound = new Matcher<UrlRewriteRuleProcessorHolder>();
+ ScopedMatcher inbound = new ScopedMatcher();
+ ScopedMatcher outbound = new ScopedMatcher();
Map<String,UrlRewriteFunctionProcessor> functions = new HashMap<String,UrlRewriteFunctionProcessor>();
public UrlRewriteProcessor() {
@@ -124,6 +126,13 @@
@Override
public Template rewrite( Resolver resolver, Template inputUri, Direction direction, String ruleName ) {
Template outputUri = inputUri;
+ String serviceRole = null;
+ if (resolver != null) {
+ List<String> serviceRoles = resolver.resolve("service.role");
+ if ( serviceRoles != null && !serviceRoles.isEmpty() ) {
+ serviceRole = serviceRoles.get(0);
+ }
+ }
UrlRewriteStepProcessorHolder stepHolder = null;
String effectiveRuleName = null;
if( ruleName == null || "*".equals( ruleName ) ) {
@@ -131,10 +140,10 @@
Matcher<UrlRewriteRuleProcessorHolder>.Match match = null;
switch( direction ) {
case IN:
- match = inbound.match( outputUri );
+ match = inbound.match( outputUri, serviceRole );
break;
case OUT:
- match = outbound.match( outputUri );
+ match = outbound.match( outputUri, serviceRole );
break;
}
if( match != null ) {
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteRuleDescriptor.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteRuleDescriptor.java
index 1a6b7a5..86d0585 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteRuleDescriptor.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteRuleDescriptor.java
@@ -31,6 +31,10 @@
UrlRewriteStepDescriptor name( String name );
+ String scope();
+
+ UrlRewriteStepDescriptor scope( String scope );
+
EnumSet<UrlRewriter.Direction> directions();
UrlRewriteRuleDescriptor directions( String directions );
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/ScopedMatcher.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/ScopedMatcher.java
new file mode 100644
index 0000000..7f4ef63
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/ScopedMatcher.java
@@ -0,0 +1,129 @@
+/**
+ * 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.hadoop.gateway.filter.rewrite.ext;
+
+import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteRuleProcessorHolder;
+import org.apache.hadoop.gateway.util.urltemplate.Matcher;
+import org.apache.hadoop.gateway.util.urltemplate.Template;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A simple extension to the matcher that takes into account scopes for rules along with the templates themselves.
+ * This matcher maintains a list of matchers and delegates to an appropriate matcher based on scope information for the
+ * associated rules.
+ */
+public class ScopedMatcher extends Matcher<UrlRewriteRuleProcessorHolder> {
+
+ public static final String GLOBAL_SCOPE = "GLOBAL";
+
+ private List<Matcher<UrlRewriteRuleProcessorHolder>> matchers;
+
+ public ScopedMatcher() {
+ super();
+ matchers = new ArrayList<>();
+ matchers.add(new Matcher<UrlRewriteRuleProcessorHolder>());
+ }
+
+ @Override
+ public UrlRewriteRuleProcessorHolder get(Template template) {
+ return super.get(template);
+ }
+
+ @Override
+ public void add(Template template, UrlRewriteRuleProcessorHolder value) {
+ Matcher<UrlRewriteRuleProcessorHolder> matcher = getMatcher(template, value);
+ matcher.add( template, value );
+ }
+
+ @Override
+ public Match match(Template input) {
+ return match(input, null);
+ }
+
+ public Match match(Template input, String scope) {
+ List<Match> matches = new ArrayList<>();
+ for (Matcher<UrlRewriteRuleProcessorHolder> matcher : matchers) {
+ Match match = matcher.match(input);
+ if (match != null) {
+ matches.add(match);
+ }
+ }
+ if (matches.size() == 0) {
+ return null;
+ }
+ if (matches.size() == 1) {
+ return getMatch(matches, scope);
+ }
+ return findBestMatch(matches, scope);
+ }
+
+ private Match findBestMatch(List<Match> matches, String scope) {
+ if (scope != null) {
+ //when multiple matches are found, find the first one that matches in scope
+ for ( Match match : matches ) {
+ String matchedScope = match.getValue().getScope();
+ if ( matchedScope != null && matchedScope.equals(scope) ) {
+ return match;
+ }
+ }
+ }
+ //since no scope match was found return the first global scopeed match
+ for ( Match match : matches ) {
+ String matchedScope = match.getValue().getScope();
+ if ( matchedScope != null && matchedScope.equals(GLOBAL_SCOPE) ) {
+ return match;
+ }
+ }
+ //return the first match from the list
+ return getMatch(matches, scope);
+ }
+
+ private Match getMatch(List<Match> matches, String scope) {
+ Match match = matches.get(0);
+ String matchedScope = match.getValue().getScope();
+ if (matchedScope != null && scope != null && !matchedScope.equals(scope) && !matchedScope.equals(GLOBAL_SCOPE)) {
+ return null;
+ }
+ return match;
+ }
+
+ /**
+ * Returns a matcher for a given template and processor holder. This method takes into account different scopes in
+ * addition to template values. If a matcher exists for a template but the scope is different, a new matcher is
+ * created and returned.
+ * @param template the template for which a matcher is needed
+ * @param holder the rule holder that goes along with the template.
+ * @return a matcher
+ */
+ private Matcher<UrlRewriteRuleProcessorHolder> getMatcher(Template template, UrlRewriteRuleProcessorHolder holder) {
+ for (Matcher<UrlRewriteRuleProcessorHolder> matcher : matchers) {
+ UrlRewriteRuleProcessorHolder matchersHolder = matcher.get(template);
+ if (matchersHolder == null) {
+ return matcher;
+ } else if (holder.getScope() == null && matchersHolder.getScope() == null) {
+ return matcher;
+ }
+ }
+ Matcher<UrlRewriteRuleProcessorHolder> matcher = new Matcher<>();
+ matchers.add(matcher);
+ return matcher;
+ }
+
+}
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteDeploymentContributor.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteDeploymentContributor.java
index b6e0bc4..d48468c 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteDeploymentContributor.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteDeploymentContributor.java
@@ -19,6 +19,7 @@
import org.apache.hadoop.gateway.deploy.DeploymentContext;
import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase;
+import org.apache.hadoop.gateway.descriptor.FilterDescriptor;
import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
@@ -39,6 +40,7 @@
private static final String PROVIDER_ROLE_NAME = "rewrite";
private static final String PROVIDER_IMPL_NAME = "url-rewrite";
+ private static final String PARAM_SERVICE_ROLE = "service.role";
private static final UrlRewriteMessages LOG = MessagesFactory.get( UrlRewriteMessages.class );
@Override
@@ -90,7 +92,9 @@
Service service,
ResourceDescriptor resource,
List<FilterParamDescriptor> params ) {
- resource.addFilter().role( getRole() ).name( getName() ).impl( UrlRewriteServletFilter.class ).params( params );
+ FilterDescriptor filterDescriptor = resource.addFilter();
+ filterDescriptor.role( getRole() ).name( getName() ).impl( UrlRewriteServletFilter.class ).params( params );
+ filterDescriptor.param().name(PARAM_SERVICE_ROLE).value(service.getRole());
}
}
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRequest.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRequest.java
index 187965c..7ba91f4 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRequest.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRequest.java
@@ -42,7 +42,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
@@ -53,6 +53,7 @@
private static final UrlRewriteMessages LOG = MessagesFactory.get( UrlRewriteMessages.class );
private static final String[] EMPTY_STRING_ARRAY = new String[]{};
+ private FilterConfig config;
private UrlRewriter rewriter;
private String urlRuleName;
private String bodyFilterName;
@@ -68,6 +69,7 @@
*/
public UrlRewriteRequest( FilterConfig config, HttpServletRequest request ) throws IOException {
super( request );
+ this.config = config;
this.rewriter = UrlRewriteServletContextListener.getUrlRewriter( config.getServletContext() );
this.urlRuleName = config.getInitParameter( UrlRewriteServletFilter.REQUEST_URL_RULE_PARAM );
this.bodyFilterName = config.getInitParameter( UrlRewriteServletFilter.REQUEST_BODY_FILTER_PARAM );
@@ -184,7 +186,7 @@
@Override
public List<String> resolve( String name ) {
- return Collections.emptyList();
+ return Arrays.asList( config.getInitParameter( name ) );
}
private class EnumerationRewriter implements Enumeration<String> {
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleDescriptorImpl.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleDescriptorImpl.java
index af882df..0658c86 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleDescriptorImpl.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleDescriptorImpl.java
@@ -18,6 +18,7 @@
package org.apache.hadoop.gateway.filter.rewrite.impl;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRuleDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriter;
import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFlowDescriptorBase;
import org.apache.hadoop.gateway.util.urltemplate.Parser;
@@ -32,6 +33,7 @@
public class UrlRewriteRuleDescriptorImpl extends UrlRewriteFlowDescriptorBase<UrlRewriteRuleDescriptor> implements UrlRewriteRuleDescriptor {
private String name;
+ private String scope;
private String pattern;
private Template template;
private EnumSet<UrlRewriter.Direction> directions;
@@ -59,6 +61,25 @@
return name;
}
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ scope( scope );
+ }
+
+ @Override
+ public String scope() {
+ return scope;
+ }
+
+ @Override
+ public UrlRewriteStepDescriptor scope( String scope ) {
+ this.scope = scope;
+ return this;
+ }
+
@Override
public EnumSet<UrlRewriter.Direction> directions() {
return directions;
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleProcessorHolder.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleProcessorHolder.java
index 7c6a2e3..708fd8c 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleProcessorHolder.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleProcessorHolder.java
@@ -17,20 +17,49 @@
*/
package org.apache.hadoop.gateway.filter.rewrite.impl;
+import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRuleDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.ext.ScopedMatcher;
+
+import java.util.List;
public class UrlRewriteRuleProcessorHolder extends UrlRewriteStepProcessorHolder {
private String ruleName;
+ private String scope;
+
public void initialize( UrlRewriteEnvironment environment, UrlRewriteRuleDescriptor descriptor ) throws Exception {
super.initialize( environment, descriptor );
ruleName = descriptor.name();
+ //if a scope is set in the rewrite file, use that
+ if (descriptor.scope() != null) {
+ scope = descriptor.scope();
+ } else {
+ //by convention the name of the rules start with ROLENAME/servicename/direction
+ //use the first part of the name to determine the scope, therefore setting the scope of a rule to
+ //be local to that service
+ int slashIndex = ruleName.indexOf('/');
+ if (slashIndex > 0) {
+ scope = ruleName.substring( 0, slashIndex );
+ }
+ //check config to see if the is an override configuration for a given service to have all its rules set to global
+ GatewayConfig gatewayConfig = environment.getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+ if (gatewayConfig != null) {
+ List<String> globalRulesServices = gatewayConfig.getGlobalRulesServices();
+ if ( globalRulesServices.contains(scope) ) {
+ scope = ScopedMatcher.GLOBAL_SCOPE;
+ }
+ }
+ }
}
public String getRuleName() {
return ruleName;
}
+ public String getScope() {
+ return scope;
+ }
}
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest.java b/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest.java
index 44a4e77..37e2b1a 100644
--- a/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest.java
+++ b/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest.java
@@ -31,6 +31,7 @@
import java.io.Reader;
import java.net.URISyntaxException;
import java.net.URL;
+import java.util.ArrayList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
@@ -119,6 +120,66 @@
}
@Test
+ public void testIdenticalRewriteOutputRulesWithScopes() throws IOException, URISyntaxException {
+ UrlRewriteEnvironment environment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+ HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+ HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+ ArrayList<String> roles = new ArrayList<>();
+ roles.add("service-1");
+ EasyMock.expect(environment.resolve("service.role")).andReturn(roles).anyTimes();
+ EasyMock.replay( environment, request, response );
+
+ UrlRewriteProcessor processor = new UrlRewriteProcessor();
+ UrlRewriteRulesDescriptor config = UrlRewriteRulesDescriptorFactory.load(
+ "xml", getTestResourceReader( "rewrite-with-same-rules-different-scope.xml", "UTF-8" ) );
+ processor.initialize( environment, config );
+
+ Template inputUrl = Parser.parseLiteral( "scheme://input-mock-host:42/test-input-path" );
+ Template outputUrl = processor.rewrite( environment, inputUrl, UrlRewriter.Direction.OUT, null );
+
+ assertThat( "Expect rewrite to produce a new URL",
+ outputUrl, notNullValue() );
+ assertThat(
+ "Expect rewrite to contain the correct path.",
+ outputUrl.toString(), is( "output-mock-scheme-2://output-mock-host-2:42/test-input-path" ) );
+
+ inputUrl = Parser.parseLiteral( "mock-scheme://input-mock-host:42/no-query" );
+ outputUrl = processor.rewrite( environment, inputUrl, UrlRewriter.Direction.OUT, null );
+
+ roles.remove(0);
+ roles.add("service-2");
+
+ assertThat(
+ "Expect rewrite to contain the correct path.",
+ outputUrl.toString(), is( "mock-scheme://output-mock-host-5:42/no-query" ) );
+
+ outputUrl = processor.rewrite( environment, inputUrl, UrlRewriter.Direction.OUT, "service-2/test-rule-4" );
+
+ //no scope information should pick the first one
+ assertThat(
+ "Expect rewrite to contain the correct path.",
+ outputUrl.toString(), is( "mock-scheme://output-mock-host-4:42/no-query" ) );
+
+ outputUrl = processor.rewrite( null, inputUrl, UrlRewriter.Direction.OUT, "service-2/test-rule-4" );
+
+ assertThat(
+ "Expect rewrite to contain the correct path.",
+ outputUrl.toString(), is( "mock-scheme://output-mock-host-4:42/no-query" ) );
+
+ //Test the IN direction
+ inputUrl = Parser.parseLiteral( "scheme://input-mock-host:42/test-input-path" );
+ outputUrl = processor.rewrite( environment, inputUrl, UrlRewriter.Direction.IN, null );
+
+ assertThat( "Expect rewrite to produce a new URL",
+ outputUrl, notNullValue() );
+ assertThat(
+ "Expect rewrite to contain the correct path.",
+ outputUrl.toString(), is( "input-mock-scheme-2://input-mock-host-2:42/test-input-path" ) );
+
+ processor.destroy();
+ }
+
+ @Test
public void testRewriteViaRuleNameWithAmbiguousRules() throws IOException, URISyntaxException {
UrlRewriteEnvironment environment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlFilterReaderTest.java b/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlFilterReaderTest.java
index 1e8bb56..0894abe 100644
--- a/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlFilterReaderTest.java
+++ b/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlFilterReaderTest.java
@@ -17,15 +17,21 @@
*/
package org.apache.hadoop.gateway.filter.rewrite.impl.xml;
-import net.htmlparser.jericho.Attribute;
-import net.htmlparser.jericho.Segment;
-import net.htmlparser.jericho.StartTag;
-import net.htmlparser.jericho.StreamedSource;
import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.ExtendedBaseRules;
import org.apache.commons.digester3.binder.DigesterLoader;
import org.apache.commons.io.IOUtils;
-import org.apache.hadoop.gateway.filter.rewrite.api.*;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterApplyDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterBufferDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFilterDetectDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRuleDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRulesDescriptorFactory;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepFlow;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriter;
import org.apache.hadoop.gateway.filter.rewrite.ext.UrlRewriteCheckDescriptorExt;
import org.apache.hadoop.gateway.filter.rewrite.ext.UrlRewriteControlDescriptor;
import org.apache.hadoop.gateway.filter.rewrite.ext.UrlRewriteMatchDescriptor;
@@ -35,19 +41,13 @@
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xmlmatchers.namespace.SimpleNamespaceContext;
import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
@@ -57,14 +57,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
-import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -74,7 +71,7 @@
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.fail;
@@ -366,6 +363,28 @@
assertThat( rule.directions(), nullValue() );
assertThat( rule.flow(), nullValue() );
+ reader = new StringReader( "<rules><rule scope=\"test-scope\"></rule></rules>" );
+ config = digester.parse( reader );
+ assertThat( config.getRules().size(), is( 1 ) );
+ rule = config.getRules().get( 0 );
+ assertThat( rule, notNullValue() );
+ assertThat( rule.name(), nullValue() );
+ assertThat( rule.scope(), is( "test-scope" ) );
+ assertThat( rule.pattern(), nullValue() );
+ assertThat( rule.directions(), nullValue() );
+ assertThat( rule.flow(), nullValue() );
+
+ reader = new StringReader( "<rules><rule name=\"test-name\" scope=\"test-scope\"></rule></rules>" );
+ config = digester.parse( reader );
+ assertThat( config.getRules().size(), is( 1 ) );
+ rule = config.getRules().get( 0 );
+ assertThat( rule, notNullValue() );
+ assertThat( rule.name(), is( "test-name" ) );
+ assertThat( rule.scope(), is( "test-scope" ) );
+ assertThat( rule.pattern(), nullValue() );
+ assertThat( rule.directions(), nullValue() );
+ assertThat( rule.flow(), nullValue() );
+
reader = new StringReader( "<rules><rule pattern=\"test-pattern\"></rule></rules>" );
config = digester.parse( reader );
assertThat( config.getRules().size(), is( 1 ) );
diff --git a/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporterTest.java b/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporterTest.java
index bd52405..9ae5bd0 100644
--- a/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporterTest.java
+++ b/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporterTest.java
@@ -51,7 +51,7 @@
@Test
public void testSingleNamedRule() throws IOException {
UrlRewriteRulesDescriptor rules = UrlRewriteRulesDescriptorFactory.create();
- rules.addRule( "first" );
+ rules.addRule( "first" ).scope( "test-scope" );
StringWriter writer = new StringWriter();
UrlRewriteRulesDescriptorFactory.store( rules, "xml", writer );
@@ -63,6 +63,7 @@
assertThat( xml, XmlMatchers.hasXPath( "/rules/rule" ) );
assertThat( xml, XmlMatchers.hasXPath( "count(/rules/rule)", is( "1" ) ) );
assertThat( xml, XmlMatchers.hasXPath( "/rules/rule/@name", is( "first" ) ) );
+ assertThat( xml, XmlMatchers.hasXPath( "/rules/rule/@scope", is( "test-scope" ) ) );
}
@Test
diff --git a/gateway-provider-rewrite/src/test/resources/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest/rewrite-with-same-rules-different-scope.xml b/gateway-provider-rewrite/src/test/resources/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest/rewrite-with-same-rules-different-scope.xml
new file mode 100644
index 0000000..6c27476
--- /dev/null
+++ b/gateway-provider-rewrite/src/test/resources/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest/rewrite-with-same-rules-different-scope.xml
@@ -0,0 +1,54 @@
+<!--
+ 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="test-rule-1" dir="OUT" pattern="*://*:*/**?**">
+ <match pattern="*://{host}:{port}/{path=**}?{**}" />
+ <rewrite template="output-mock-scheme-1://output-mock-host-1:{port}/{path=**}" />
+ </rule>
+
+ <rule name="service-1/test-rule-2" dir="OUT" pattern="*://*:*/**?**">
+ <match pattern="*://{host}:{port}/{path=**}?{**}" />
+ <rewrite template="output-mock-scheme-2://output-mock-host-2:{port}/{path=**}" />
+ </rule>
+
+ <rule name="test-rule-3" dir="OUT" pattern="*://*:*/no-query">
+ <match pattern="{scheme}://{host}:{port}/{path=**}" />
+ <rewrite template="{scheme}://output-mock-host-3:{port}/{path=**}" />
+ </rule>
+
+ <rule name="service-2/test-rule-4" dir="OUT" pattern="*://*:*/no-query">
+ <match pattern="{scheme}://{host}:{port}/{path=**}" />
+ <rewrite template="{scheme}://output-mock-host-4:{port}/{path=**}" />
+ </rule>
+
+ <rule name="service-1/test-rule-5" dir="OUT" pattern="*://*:*/no-query">
+ <match pattern="{scheme}://{host}:{port}/{path=**}" />
+ <rewrite template="{scheme}://output-mock-host-5:{port}/{path=**}" />
+ </rule>
+
+ <rule name="test-rule-6" dir="IN" pattern="*://*:*/**?**">
+ <match pattern="*://{host}:{port}/{path=**}?{**}" />
+ <rewrite template="input-mock-scheme-1://input-mock-host-1:{port}/{path=**}" />
+ </rule>
+
+ <rule name="service-2/test-rule-7" dir="IN" pattern="*://*:*/**?**">
+ <match pattern="*://{host}:{port}/{path=**}?{**}" />
+ <rewrite template="input-mock-scheme-2://input-mock-host-2:{port}/{path=**}" />
+ </rule>
+
+</rules>
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
index 82a21ee..0bfe82f 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
@@ -31,6 +31,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -108,6 +109,7 @@
public static final String SECURITY_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".security.dir";
public static final String DATA_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".data.dir";
public static final String STACKS_SERVICES_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".services.dir";
+ public static final String GLOBAL_RULES_SERVICES = GATEWAY_CONFIG_FILE_PREFIX + ".global.rules.services";
public static final String APPLICATIONS_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".applications.dir";
public static final String HADOOP_CONF_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".hadoop.conf.dir";
public static final String FRONTEND_URL = GATEWAY_CONFIG_FILE_PREFIX + ".frontend.url";
@@ -144,7 +146,8 @@
public static final String DEFAULT_DEPLOYMENT_DIR = "deployments";
public static final String DEFAULT_SECURITY_DIR = "security";
public static final String DEFAULT_DATA_DIR = "data";
-
+ private static List<String> DEFAULT_GLOBAL_RULES_SERVICES;
+
public GatewayConfigImpl() {
init();
@@ -225,9 +228,24 @@
for( String fileName : GATEWAY_CONFIG_FILENAMES ) {
lastFileUrl = loadConfig( fileName, lastFileUrl );
}
+ //set default services list
+ setDefaultGlobalRulesServices();
+
initGatewayHomeDir( lastFileUrl );
}
+ private void setDefaultGlobalRulesServices() {
+ DEFAULT_GLOBAL_RULES_SERVICES = new ArrayList<>();
+ DEFAULT_GLOBAL_RULES_SERVICES.add("NAMENODE");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("JOBTRACKER");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("WEBHDFS");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("WEBHCAT");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("OOZIE");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("WEBHBASE");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("HIVE");
+ DEFAULT_GLOBAL_RULES_SERVICES.add("RESOURCEMANAGER");
+ }
+
private void initGatewayHomeDir( URL lastFileUrl ) {
String home = System.getProperty( GATEWAY_HOME_VAR );
if( home != null ) {
@@ -603,6 +621,15 @@
return get(SIGNING_KEY_ALIAS);
}
+ @Override
+ public List<String> getGlobalRulesServices() {
+ String value = get( GLOBAL_RULES_SERVICES );
+ if ( value != null && !value.isEmpty() && !"none".equalsIgnoreCase(value.trim()) ) {
+ return Arrays.asList( value.trim().split("\\s*,\\s*") );
+ }
+ return DEFAULT_GLOBAL_RULES_SERVICES;
+ }
+
private static long parseNetworkTimeout( String s ) {
PeriodFormatter f = new PeriodFormatterBuilder()
.appendMinutes().appendSuffix("m"," min")
diff --git a/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java b/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
index 22e4503..f1529ad 100644
--- a/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
+++ b/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
@@ -1,11 +1,13 @@
package org.apache.hadoop.gateway.config.impl;
-import java.util.List;
-
import org.apache.hadoop.test.TestUtils;
+import org.hamcrest.CoreMatchers;
import org.junit.Test;
+import java.util.List;
+
import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.nullValue;
@@ -151,4 +153,31 @@
assertThat( config.getExcludedSSLCiphers(), is(hasItems("ONE","TWO","THREE")) );
}
+ @Test( timeout = TestUtils.SHORT_TIMEOUT )
+ public void testGlobalRulesServices() {
+ GatewayConfigImpl config = new GatewayConfigImpl();
+ List<String> list;
+
+ list = config.getGlobalRulesServices();
+ assertThat( list, is(notNullValue()) );
+
+ assertThat( list, is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER")));
+
+
+ config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "none" );
+ assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER")) );
+
+ config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "" );
+ assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER")) );
+
+ config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "ONE" );
+ assertThat( config.getGlobalRulesServices(), is(hasItems("ONE")) );
+
+ config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "ONE,TWO,THREE" );
+ assertThat( config.getGlobalRulesServices(), is(hasItems("ONE","TWO","THREE")) );
+
+ config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, " ONE , TWO , THREE " );
+ assertThat( config.getGlobalRulesServices(), is(hasItems("ONE","TWO","THREE")) );
+ }
+
}
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
index d830887..85da3b5 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
@@ -143,4 +143,6 @@
String getSigningKeyAlias();
+ List<String> getGlobalRulesServices();
+
}
diff --git a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 3c53597..74643e8 100644
--- a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -23,6 +23,7 @@
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
public class GatewayTestConfig extends Configuration implements GatewayConfig {
@@ -345,4 +346,8 @@
return null;
}
+ @Override
+ public List<String> getGlobalRulesServices() {
+ return Collections.EMPTY_LIST;
+ }
}
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 4c75cb9..b0b78f9 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -397,4 +397,15 @@
return null;
}
+ @Override
+ public List<String> getGlobalRulesServices() {
+ ArrayList<String> services = new ArrayList<>();
+ services.add("WEBHDFS");
+ services.add("HBASE");
+ services.add("HIVE");
+ services.add("OOZIE");
+ services.add("RESOURCEMANAGER");
+ services.add("STORM");
+ return services;
+ }
}
diff --git a/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Matcher.java b/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Matcher.java
index 6679efd..1ab30b4 100644
--- a/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Matcher.java
+++ b/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Matcher.java
@@ -19,7 +19,6 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;