You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by su...@apache.org on 2016/06/09 18:08:15 UTC

knox git commit: KNOX-711 Added the ability to scope rewrite rules

Repository: knox
Updated Branches:
  refs/heads/master a227981fa -> 286e02a44


KNOX-711 Added the ability to scope rewrite rules


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/286e02a4
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/286e02a4
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/286e02a4

Branch: refs/heads/master
Commit: 286e02a44dfb5f9ee101007b46bcb8ee47fa62d7
Parents: a227981
Author: Sumit Gupta <su...@apache.org>
Authored: Thu Jun 9 14:06:16 2016 -0400
Committer: Sumit Gupta <su...@apache.org>
Committed: Thu Jun 9 14:06:16 2016 -0400

----------------------------------------------------------------------
 .../filter/rewrite/api/UrlRewriteProcessor.java |  17 ++-
 .../rewrite/api/UrlRewriteRuleDescriptor.java   |   4 +
 .../filter/rewrite/ext/ScopedMatcher.java       | 129 +++++++++++++++++++
 .../impl/UrlRewriteDeploymentContributor.java   |   6 +-
 .../filter/rewrite/impl/UrlRewriteRequest.java  |   6 +-
 .../impl/UrlRewriteRuleDescriptorImpl.java      |  21 +++
 .../impl/UrlRewriteRuleProcessorHolder.java     |  29 +++++
 .../rewrite/api/UrlRewriteProcessorTest.java    |  61 +++++++++
 .../rewrite/impl/xml/XmlFilterReaderTest.java   |  49 ++++---
 .../xml/XmlUrlRewriteRulesExporterTest.java     |   3 +-
 .../rewrite-with-same-rules-different-scope.xml |  54 ++++++++
 .../gateway/config/impl/GatewayConfigImpl.java  |  29 ++++-
 .../config/impl/GatewayConfigImplTest.java      |  33 ++++-
 .../hadoop/gateway/config/GatewayConfig.java    |   2 +
 .../hadoop/gateway/GatewayTestConfig.java       |   5 +
 .../hadoop/gateway/GatewayTestConfig.java       |  11 ++
 .../gateway/util/urltemplate/Matcher.java       |   1 -
 17 files changed, 433 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessor.java
----------------------------------------------------------------------
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 org.apache.hadoop.gateway.util.urltemplate.Template;
 
 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 @@ public class UrlRewriteProcessor implements UrlRewriter {
   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 @@ public class UrlRewriteProcessor implements UrlRewriter {
   @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 @@ public class UrlRewriteProcessor implements UrlRewriter {
       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 ) {

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteRuleDescriptor.java
----------------------------------------------------------------------
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 @@ public interface UrlRewriteRuleDescriptor extends UrlRewriteFlowDescriptor<UrlRe
 
   UrlRewriteStepDescriptor name( String name );
 
+  String scope();
+
+  UrlRewriteStepDescriptor scope( String scope );
+
   EnumSet<UrlRewriter.Direction> directions();
 
   UrlRewriteRuleDescriptor directions( String directions );

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/ScopedMatcher.java
----------------------------------------------------------------------
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;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteDeploymentContributor.java
----------------------------------------------------------------------
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 @@ package org.apache.hadoop.gateway.filter.rewrite.impl;
 
 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 @@ public class UrlRewriteDeploymentContributor extends ProviderDeploymentContribut
 
   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 @@ public class UrlRewriteDeploymentContributor extends ProviderDeploymentContribut
       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());
   }
 
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRequest.java
----------------------------------------------------------------------
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.IOException;
 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 @@ public class UrlRewriteRequest extends GatewayRequestWrapper implements Resolver
   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 class UrlRewriteRequest extends GatewayRequestWrapper implements Resolver
    */
   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 @@ public class UrlRewriteRequest extends GatewayRequestWrapper implements Resolver
 
   @Override
   public List<String> resolve( String name ) {
-    return Collections.emptyList();
+    return Arrays.asList( config.getInitParameter( name ) );
   }
 
   private class EnumerationRewriter implements Enumeration<String> {

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleDescriptorImpl.java
----------------------------------------------------------------------
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 @@ import java.util.StringTokenizer;
 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 @@ public class UrlRewriteRuleDescriptorImpl extends UrlRewriteFlowDescriptorBase<U
     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;

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/impl/UrlRewriteRuleProcessorHolder.java
----------------------------------------------------------------------
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;
+  }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest.java
----------------------------------------------------------------------
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.InputStreamReader;
 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 @@ public class UrlRewriteProcessorTest {
   }
 
   @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 );

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlFilterReaderTest.java
----------------------------------------------------------------------
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.apache.hadoop.test.TestUtils;
 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 javax.xml.transform.stream.StreamResult;
 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.is;
 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 @@ public class XmlFilterReaderTest {
       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 ) );

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/test/java/org/apache/hadoop/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporterTest.java
----------------------------------------------------------------------
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 @@ public class XmlUrlRewriteRulesExporterTest {
   @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 @@ public class XmlUrlRewriteRulesExporterTest {
     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

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-provider-rewrite/src/test/resources/org/apache/hadoop/gateway/filter/rewrite/api/UrlRewriteProcessorTest/rewrite-with-same-rules-different-scope.xml
----------------------------------------------------------------------
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>

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
index 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.InetSocketAddress;
 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 class GatewayConfigImpl extends Configuration implements GatewayConfig {
   public static final String SECURITY_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".security.dir";
   public static final String DATA_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".data.dir";
   public static final String STACKS_SERVICES_DIR = GATEWAY_CONFIG_FILE_PREFIX + ".services.dir";
+  public static final String 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 class GatewayConfigImpl extends Configuration implements GatewayConfig {
   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 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     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 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     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")

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-server/src/test/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImplTest.java
----------------------------------------------------------------------
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 @@ public class GatewayConfigImplTest {
     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")) );
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
index 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 @@ public interface GatewayConfig {
 
   String getSigningKeyAlias();
 
+  List<String> getGlobalRulesServices();
+
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 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 org.apache.hadoop.gateway.config.GatewayConfig;
 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 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
     return null;
   }
 
+  @Override
+  public List<String> getGlobalRulesServices() {
+    return Collections.EMPTY_LIST;
+  }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
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 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
     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;
+  }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/286e02a4/gateway-util-urltemplate/src/main/java/org/apache/hadoop/gateway/util/urltemplate/Matcher.java
----------------------------------------------------------------------
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 @@ package org.apache.hadoop.gateway.util.urltemplate;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;