You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/09/01 13:17:40 UTC

[42/64] [partial] knox git commit: KNOX-998 - Refactoring save 1

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java
deleted file mode 100644
index a54c03b..0000000
--- a/gateway-provider-identity-assertion-common/src/test/java/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.function;
-
-import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
-import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteServletContextListener;
-import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteServletFilter;
-import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor;
-import org.apache.hadoop.gateway.identityasserter.common.function.UsernameFunctionProcessor;
-import org.apache.hadoop.gateway.security.PrimaryPrincipal;
-import org.apache.hadoop.gateway.util.urltemplate.Parser;
-import org.apache.hadoop.test.TestUtils;
-import org.apache.hadoop.test.log.NoOpLogger;
-import org.apache.hadoop.test.mock.MockInteraction;
-import org.apache.hadoop.test.mock.MockServlet;
-import org.apache.http.auth.BasicUserPrincipal;
-import org.eclipse.jetty.servlet.FilterHolder;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.http.HttpTester;
-import org.eclipse.jetty.servlet.ServletTester;
-import org.eclipse.jetty.util.ArrayQueue;
-import org.eclipse.jetty.util.log.Log;
-import org.hamcrest.core.Is;
-import org.junit.After;
-import org.junit.Test;
-
-import javax.security.auth.Subject;
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.junit.Assert.fail;
-
-public class UsernameFunctionProcessorTest {
-
-  private ServletTester server;
-  private HttpTester.Request request;
-  private HttpTester.Response response;
-  private ArrayQueue<MockInteraction> interactions;
-  private MockInteraction interaction;
-
-  private static URL getTestResource( String name ) {
-    name = UsernameFunctionProcessorTest.class.getName().replaceAll( "\\.", "/" ) + "/" + name;
-    URL url = ClassLoader.getSystemResource( name );
-    return url;
-  }
-
-  public void setUp( String username, Map<String,String> initParams ) throws Exception {
-    String descriptorUrl = getTestResource( "rewrite.xml" ).toExternalForm();
-
-    Log.setLog( new NoOpLogger() );
-
-    server = new ServletTester();
-    server.setContextPath( "/" );
-    server.getContext().addEventListener( new UrlRewriteServletContextListener() );
-    server.getContext().setInitParameter(
-        UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME, descriptorUrl );
-
-    FilterHolder setupFilter = server.addFilter( SetupFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
-    setupFilter.setFilter( new SetupFilter( username ) );
-    FilterHolder rewriteFilter = server.addFilter( UrlRewriteServletFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
-    if( initParams != null ) {
-      for( Map.Entry<String,String> entry : initParams.entrySet() ) {
-        rewriteFilter.setInitParameter( entry.getKey(), entry.getValue() );
-      }
-    }
-    rewriteFilter.setFilter( new UrlRewriteServletFilter() );
-
-    interactions = new ArrayQueue<MockInteraction>();
-
-    ServletHolder servlet = server.addServlet( MockServlet.class, "/" );
-    servlet.setServlet( new MockServlet( "mock-servlet", interactions ) );
-
-    server.start();
-
-    interaction = new MockInteraction();
-    request = HttpTester.newRequest();
-    response = null;
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    if( server != null ) {
-      server.stop();
-    }
-  }
-
-  @Test
-  public void testInitialize() throws Exception {
-    UsernameFunctionProcessor processor = new UsernameFunctionProcessor();
-    // Shouldn't fail.
-    processor.initialize( null, null );
-  }
-
-  @Test
-  public void testDestroy() throws Exception {
-    UsernameFunctionProcessor processor = new UsernameFunctionProcessor();
-    // Shouldn't fail.
-    processor.destroy();
-  }
-
-  @Test
-  public void testResolve() throws Exception {
-    final UsernameFunctionProcessor processor = new UsernameFunctionProcessor();
-    assertThat( processor.resolve( null, null ), nullValue() );
-    assertThat( processor.resolve( null, Arrays.asList( "test-input" ) ), contains( "test-input" ) );
-    Subject subject = new Subject();
-    subject.getPrincipals().add( new PrimaryPrincipal( "test-username" ) );
-    subject.setReadOnly();
-    Subject.doAs( subject, new PrivilegedExceptionAction<Object>() {
-      @Override
-      public Object run() throws Exception {
-        assertThat( processor.resolve( null, null ), contains( "test-username" ) );
-        assertThat( processor.resolve( null, Arrays.asList( "test-ignored" ) ), contains( "test-username" ) );
-        return null;
-      }
-    } );
-  }
-
-  @Test
-  public void testServiceLoader() throws Exception {
-    ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionProcessor.class );
-    Iterator iterator = loader.iterator();
-    while( iterator.hasNext() ) {
-      Object object = iterator.next();
-      if( object instanceof UsernameFunctionProcessor ) {
-        return;
-      }
-    }
-    fail( "Failed to find UsernameFunctionProcessor via service loader." );
-  }
-
-  @Test
-  public void testRequestUrlRewriteOfUsernameViaRewriteRule() throws Exception {
-    Map<String,String> initParams = new HashMap<>();
-    initParams.put( "request.url", "test-rule-username" );
-    setUp( "test-user", initParams );
-
-    String input = "<root/>";
-    String expect = "<root/>";
-
-    // Setup the server side request/response interaction.
-    interaction.expect()
-        .method( "PUT" )
-        .requestUrl( "test-output-scheme://test-input-host:777/test-output-path/test-input-path" )
-        .queryParam( "user.name", "test-user" )
-        .queryParam( "test-query-input-name", "test-query-input-value" )
-        .queryParam( "test-query-output-name", "test-query-output-value" )
-        .contentType( "text/xml" )
-        .content( expect, Charset.forName( "UTF-8" ) );
-    interaction.respond().status( 200 );
-    interactions.add( interaction );
-    request.setMethod( "PUT" );
-    request.setURI( "/test-input-path?test-query-input-name=test-query-input-value" );
-    //request.setVersion( "HTTP/1.1" );
-    request.setHeader( "Host", "test-input-host:777" );
-    request.setHeader( "Content-Type", "text/xml; charset=UTF-8" );
-    request.setContent( input );
-
-    response = TestUtils.execute( server, request );
-
-    // Test the results.
-    assertThat( response.getStatus(), Is.is( 200 ) );
-  }
-
-  private static class SetupFilter implements Filter {
-    private Subject subject;
-
-    public SetupFilter( String userName ) {
-      subject = new Subject();
-      subject.getPrincipals().add( new BasicUserPrincipal( userName ) );
-    }
-
-    @Override
-    public void init( FilterConfig filterConfig ) throws ServletException {
-    }
-
-    @Override
-    public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException {
-      HttpServletRequest httpRequest = ((HttpServletRequest)request);
-      StringBuffer sourceUrl = httpRequest.getRequestURL();
-      String queryString = httpRequest.getQueryString();
-      if( queryString != null ) {
-        sourceUrl.append( "?" );
-        sourceUrl.append( queryString );
-      }
-      try {
-        request.setAttribute(
-            AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME,
-            Parser.parseLiteral( sourceUrl.toString() ) );
-      } catch( URISyntaxException e ) {
-        throw new ServletException( e );
-      }
-      try {
-        Subject.doAs( subject, new PrivilegedExceptionAction<Void>() {
-          @Override
-          public Void run() throws Exception {
-              chain.doFilter( request, response );
-              return null;
-          }
-        } );
-      } catch( PrivilegedActionException e ) {
-        throw new ServletException( e );
-      }
-    }
-
-    @Override
-    public void destroy() {
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java
new file mode 100644
index 0000000..bd5b32c
--- /dev/null
+++ b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/CommonIdentityAssertionFilterTest.java
@@ -0,0 +1,130 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.filter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.security.auth.Subject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author larry
+ *
+ */
+public class CommonIdentityAssertionFilterTest {
+
+  private String username = null;
+  private String[] mappedGroups = null;
+  private Filter filter = null;
+  
+  @Before
+  public void setup() {
+    filter = new CommonIdentityAssertionFilter() {
+      @Override
+      public String mapUserPrincipal(String principalName) {
+        username = principalName.toUpperCase();
+        return principalName;
+      }
+
+      @Override
+      public String[] mapGroupPrincipals(String principalName, Subject subject) {
+        String[] groups = new String[2];
+        int i = 0;
+        for(GroupPrincipal p : subject.getPrincipals(GroupPrincipal.class)) {
+          groups[i] = p.getName().toUpperCase();
+          i++;
+        }
+        mappedGroups = groups;
+        return groups;
+      }
+    };
+  }
+
+  @Test
+  public void testSimpleFilter() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals("LARRY", username);
+    assertEquals(mappedGroups.length, 2);
+    assertTrue(mappedGroups[0].equals("USERS") || mappedGroups[0].equals("ADMIN"));
+    assertTrue(mappedGroups[1], mappedGroups[1].equals("USERS") || mappedGroups[1].equals("ADMIN"));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java
new file mode 100644
index 0000000..745fbdd
--- /dev/null
+++ b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/filter/IdentityAssertionHttpServletRequestWrapperTest.java
@@ -0,0 +1,279 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.filter;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.identityasserter.common.filter.IdentityAsserterHttpServletRequestWrapper;
+import org.apache.hadoop.test.category.FastTests;
+import org.apache.hadoop.test.category.UnitTests;
+import org.apache.hadoop.test.mock.MockHttpServletRequest;
+import org.apache.hadoop.test.mock.MockServletInputStream;
+import org.junit.Test;
+import org.junit.After;
+import org.junit.experimental.categories.Category;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+@Category( { UnitTests.class, FastTests.class } )
+public class IdentityAssertionHttpServletRequestWrapperTest {
+
+  @After
+  public void resetSystemProps() {
+    System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "false");
+  }
+
+  @Test
+  public void testInsertUserNameInPostMethod() throws IOException {
+    String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) );
+    request.setCharacterEncoding( "UTF-8" );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setMethod("POST");
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() );
+    String output = wrapper.getQueryString();
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testInsertUserNameInPostMethodWithoutEncoding() throws IOException {
+    String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setMethod("POST");
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() );
+    String output = wrapper.getQueryString();
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testInsertUserNameInPostMethodWithIso88591Encoding() throws IOException {
+    String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setCharacterEncoding( "ISO-8859-1" );
+    request.setMethod("POST");
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() );
+    String output = wrapper.getQueryString();
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testOverwriteUserNameInPostMethod() throws IOException {
+    String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) );
+    request.setCharacterEncoding( "UTF-8" );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setMethod("POST");
+    
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() );
+    String output = wrapper.getQueryString();
+    assertThat( output, containsString( "user.name=output-user" ) );
+    assertThat( output, not( containsString( "input-user" ) ) );
+  }
+
+  @Test
+  public void testIngoreNonFormBody() throws IOException {
+    String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( "UTF-8" ) ) ) );
+    request.setCharacterEncoding( "UTF-8" );
+    request.setContentType( "text/plain" );
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String outputBody = IOUtils.toString( wrapper.getInputStream(), wrapper.getCharacterEncoding() );
+
+    assertThat( outputBody, containsString( "user.name=input-user" ) );
+    assertThat( outputBody, not( containsString( "output-user" ) ) );
+  }
+
+  @Test
+  public void testInsertUserNameInQueryString() {
+    String input = "param=value";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testInsertDoAsInQueryString() {
+    System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "true");
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString("op=LISTSTATUS&user.name=jack&User.Name=jill&DOas=admin&doas=root");
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+    assertThat(output, is("op=LISTSTATUS&doAs=output-user"));
+  }
+
+  @Test
+  public void testInsertUserNameInNullQueryString() {
+    String input = null;
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testInsertUserNameInNullQueryStringForGET() {
+    String input = null;
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testInsertUserNameInQueryStringForPOST() {
+    String input = null;
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+    request.setMethod("POST");
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "user.name=output-user" ) );
+  }
+
+  @Test
+  public void testOverwriteUserNameInQueryString() {
+    String input = "user.name=input-user";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+        = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "user.name=output-user" ) );
+    assertThat( output, not( containsString( "input-user" ) ) );
+  }
+
+  @Test
+  public void testParameterWithNullValueInQueryString() {
+    String input = "paramWithNullValue&param2=abc";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    IdentityAsserterHttpServletRequestWrapper wrapper
+      = new IdentityAsserterHttpServletRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "user.name=output-user" ) );
+    assertThat( output, containsString( "paramWithNullValue" ) );
+    assertThat( output, containsString( "param2=abc" ) );
+  }
+
+  @Test
+  public void testUrlEncode() {
+    String s;
+    HashMap<String,List<String>> m;
+
+    m = new HashMap<>();
+    m.put( "null-values", null );
+    s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" );
+    assertThat( s, is( "null-values" ) );
+
+    m = new HashMap<>();
+    m.put( "no-values", new ArrayList<String>(0) );
+    s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" );
+    assertThat( s, is( "no-values" ) );
+
+    m = new HashMap<>();
+    List<String> lst = new ArrayList<String>();
+    lst.add("value1");
+    m.put( "one-value", lst);
+    s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" );
+    assertThat( s, is( "one-value=value1" ) );
+
+    m = new HashMap<>();
+    lst = new ArrayList<String>();
+    String[] a = {"value1", "value2"};
+    lst.addAll(Arrays.asList(a));
+    m.put( "two-values", lst);
+    s = IdentityAsserterHttpServletRequestWrapper.urlEncode( m, "UTF-8" );
+    assertThat( s, is( "two-values=value1&two-values=value2" ) );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java
new file mode 100644
index 0000000..3cce3a0
--- /dev/null
+++ b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionDescriptorTest.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.function;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor;
+import org.apache.knox.gateway.identityasserter.common.function.UsernameFunctionDescriptor;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+public class UsernameFunctionDescriptorTest {
+
+  @Test
+  public void testName() throws Exception {
+    UsernameFunctionDescriptor descriptor = new UsernameFunctionDescriptor();
+    assertThat( descriptor.name(), is( "username" ) );
+  }
+
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionDescriptor.class );
+    Iterator iterator = loader.iterator();
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof UsernameFunctionDescriptor ) {
+        return;
+      }
+    }
+    fail( "Failed to find UsernameFunctionDescriptor via service loader." );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest.java
new file mode 100644
index 0000000..0f9d67c
--- /dev/null
+++ b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest.java
@@ -0,0 +1,247 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.function;
+
+import org.apache.knox.gateway.filter.AbstractGatewayFilter;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletContextListener;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteServletFilter;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor;
+import org.apache.knox.gateway.identityasserter.common.function.UsernameFunctionProcessor;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.apache.knox.gateway.util.urltemplate.Parser;
+import org.apache.hadoop.test.TestUtils;
+import org.apache.hadoop.test.log.NoOpLogger;
+import org.apache.hadoop.test.mock.MockInteraction;
+import org.apache.hadoop.test.mock.MockServlet;
+import org.apache.http.auth.BasicUserPrincipal;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.http.HttpTester;
+import org.eclipse.jetty.servlet.ServletTester;
+import org.eclipse.jetty.util.ArrayQueue;
+import org.eclipse.jetty.util.log.Log;
+import org.hamcrest.core.Is;
+import org.junit.After;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+import static org.junit.Assert.fail;
+
+public class UsernameFunctionProcessorTest {
+
+  private ServletTester server;
+  private HttpTester.Request request;
+  private HttpTester.Response response;
+  private ArrayQueue<MockInteraction> interactions;
+  private MockInteraction interaction;
+
+  private static URL getTestResource( String name ) {
+    name = UsernameFunctionProcessorTest.class.getName().replaceAll( "\\.", "/" ) + "/" + name;
+    URL url = ClassLoader.getSystemResource( name );
+    return url;
+  }
+
+  public void setUp( String username, Map<String,String> initParams ) throws Exception {
+    String descriptorUrl = getTestResource( "rewrite.xml" ).toExternalForm();
+
+    Log.setLog( new NoOpLogger() );
+
+    server = new ServletTester();
+    server.setContextPath( "/" );
+    server.getContext().addEventListener( new UrlRewriteServletContextListener() );
+    server.getContext().setInitParameter(
+        UrlRewriteServletContextListener.DESCRIPTOR_LOCATION_INIT_PARAM_NAME, descriptorUrl );
+
+    FilterHolder setupFilter = server.addFilter( SetupFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+    setupFilter.setFilter( new SetupFilter( username ) );
+    FilterHolder rewriteFilter = server.addFilter( UrlRewriteServletFilter.class, "/*", EnumSet.of( DispatcherType.REQUEST ) );
+    if( initParams != null ) {
+      for( Map.Entry<String,String> entry : initParams.entrySet() ) {
+        rewriteFilter.setInitParameter( entry.getKey(), entry.getValue() );
+      }
+    }
+    rewriteFilter.setFilter( new UrlRewriteServletFilter() );
+
+    interactions = new ArrayQueue<MockInteraction>();
+
+    ServletHolder servlet = server.addServlet( MockServlet.class, "/" );
+    servlet.setServlet( new MockServlet( "mock-servlet", interactions ) );
+
+    server.start();
+
+    interaction = new MockInteraction();
+    request = HttpTester.newRequest();
+    response = null;
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if( server != null ) {
+      server.stop();
+    }
+  }
+
+  @Test
+  public void testInitialize() throws Exception {
+    UsernameFunctionProcessor processor = new UsernameFunctionProcessor();
+    // Shouldn't fail.
+    processor.initialize( null, null );
+  }
+
+  @Test
+  public void testDestroy() throws Exception {
+    UsernameFunctionProcessor processor = new UsernameFunctionProcessor();
+    // Shouldn't fail.
+    processor.destroy();
+  }
+
+  @Test
+  public void testResolve() throws Exception {
+    final UsernameFunctionProcessor processor = new UsernameFunctionProcessor();
+    assertThat( processor.resolve( null, null ), nullValue() );
+    assertThat( processor.resolve( null, Arrays.asList( "test-input" ) ), contains( "test-input" ) );
+    Subject subject = new Subject();
+    subject.getPrincipals().add( new PrimaryPrincipal( "test-username" ) );
+    subject.setReadOnly();
+    Subject.doAs( subject, new PrivilegedExceptionAction<Object>() {
+      @Override
+      public Object run() throws Exception {
+        assertThat( processor.resolve( null, null ), contains( "test-username" ) );
+        assertThat( processor.resolve( null, Arrays.asList( "test-ignored" ) ), contains( "test-username" ) );
+        return null;
+      }
+    } );
+  }
+
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( UrlRewriteFunctionProcessor.class );
+    Iterator iterator = loader.iterator();
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof UsernameFunctionProcessor ) {
+        return;
+      }
+    }
+    fail( "Failed to find UsernameFunctionProcessor via service loader." );
+  }
+
+  @Test
+  public void testRequestUrlRewriteOfUsernameViaRewriteRule() throws Exception {
+    Map<String,String> initParams = new HashMap<>();
+    initParams.put( "request.url", "test-rule-username" );
+    setUp( "test-user", initParams );
+
+    String input = "<root/>";
+    String expect = "<root/>";
+
+    // Setup the server side request/response interaction.
+    interaction.expect()
+        .method( "PUT" )
+        .requestUrl( "test-output-scheme://test-input-host:777/test-output-path/test-input-path" )
+        .queryParam( "user.name", "test-user" )
+        .queryParam( "test-query-input-name", "test-query-input-value" )
+        .queryParam( "test-query-output-name", "test-query-output-value" )
+        .contentType( "text/xml" )
+        .content( expect, Charset.forName( "UTF-8" ) );
+    interaction.respond().status( 200 );
+    interactions.add( interaction );
+    request.setMethod( "PUT" );
+    request.setURI( "/test-input-path?test-query-input-name=test-query-input-value" );
+    //request.setVersion( "HTTP/1.1" );
+    request.setHeader( "Host", "test-input-host:777" );
+    request.setHeader( "Content-Type", "text/xml; charset=UTF-8" );
+    request.setContent( input );
+
+    response = TestUtils.execute( server, request );
+
+    // Test the results.
+    assertThat( response.getStatus(), Is.is( 200 ) );
+  }
+
+  private static class SetupFilter implements Filter {
+    private Subject subject;
+
+    public SetupFilter( String userName ) {
+      subject = new Subject();
+      subject.getPrincipals().add( new BasicUserPrincipal( userName ) );
+    }
+
+    @Override
+    public void init( FilterConfig filterConfig ) throws ServletException {
+    }
+
+    @Override
+    public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException {
+      HttpServletRequest httpRequest = ((HttpServletRequest)request);
+      StringBuffer sourceUrl = httpRequest.getRequestURL();
+      String queryString = httpRequest.getQueryString();
+      if( queryString != null ) {
+        sourceUrl.append( "?" );
+        sourceUrl.append( queryString );
+      }
+      try {
+        request.setAttribute(
+            AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME,
+            Parser.parseLiteral( sourceUrl.toString() ) );
+      } catch( URISyntaxException e ) {
+        throw new ServletException( e );
+      }
+      try {
+        Subject.doAs( subject, new PrivilegedExceptionAction<Void>() {
+          @Override
+          public Void run() throws Exception {
+              chain.doFilter( request, response );
+              return null;
+          }
+        } );
+      } catch( PrivilegedActionException e ) {
+        throw new ServletException( e );
+      }
+    }
+
+    @Override
+    public void destroy() {
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml b/gateway-provider-identity-assertion-common/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
deleted file mode 100644
index cf28b92..0000000
--- a/gateway-provider-identity-assertion-common/src/test/resources/org/apache/hadoop/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
--->
-<rules>
-
-    <rule name="test-rule-username">
-        <match pattern="*://{host}:{port}/{path=**}?{**}"/>
-        <rewrite template="test-output-scheme://{host}:{port}/test-output-path/{path=**}?user.name={$username}?{**}?test-query-output-name=test-query-output-value"/>
-    </rule>
-
-</rules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-common/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-common/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml b/gateway-provider-identity-assertion-common/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
new file mode 100644
index 0000000..cf28b92
--- /dev/null
+++ b/gateway-provider-identity-assertion-common/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
@@ -0,0 +1,24 @@
+<!--
+  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-username">
+        <match pattern="*://{host}:{port}/{path=**}?{**}"/>
+        <rewrite template="test-output-scheme://{host}:{port}/test-output-path/{path=**}?user.name={$username}?{**}?test-query-output-name=test-query-output-value"/>
+    </rule>
+
+</rules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/ConcatIdentityAsserterMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/ConcatIdentityAsserterMessages.java b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/ConcatIdentityAsserterMessages.java
deleted file mode 100644
index 548f3cc..0000000
--- a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/ConcatIdentityAsserterMessages.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway;
-
-import org.apache.hadoop.gateway.i18n.messages.Message;
-import org.apache.hadoop.gateway.i18n.messages.MessageLevel;
-import org.apache.hadoop.gateway.i18n.messages.Messages;
-import org.apache.hadoop.gateway.i18n.messages.StackTrace;
-
-@Messages(logger="org.apache.hadoop.gateway")
-public interface ConcatIdentityAsserterMessages {
-
-  @Message( level = MessageLevel.WARN, text = "Skipping unencodable parameter {0}={1}, {2}: {3}" )
-  void skippingUnencodableParameter( String name, String value, String encoding, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java
deleted file mode 100644
index 5eb2ca1..0000000
--- a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.concat.filter;
-
-import org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
-
-public class ConcatIdentityAsserterDeploymentContributor extends AbstractIdentityAsserterDeploymentContributor {
-
-  @Override
-  public String getName() {
-    return "Concat";
-  }
-
-  protected String getFilterClassname() {
-    return ConcatIdentityAssertionFilter.class.getName();
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
deleted file mode 100644
index aea98e6..0000000
--- a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.concat.filter;
-
-import javax.security.auth.Subject;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import org.apache.hadoop.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
-
-public class ConcatIdentityAssertionFilter extends CommonIdentityAssertionFilter {
-  private String prefix = null;
-  private String suffix = null;
-  
-  /* (non-Javadoc)
-   * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
-   */
-  @Override
-  public void init(FilterConfig filterConfig) throws ServletException {
-    super.init(filterConfig);
-
-    prefix = filterConfig.getInitParameter("concat.prefix");
-    suffix = filterConfig.getInitParameter("concat.suffix");
-    if (prefix == null) {
-      prefix = "";
-    }
-    if (suffix == null) {
-      suffix = "";
-    }
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAssertionFilter#mapGroupPrincipals(java.lang.String, javax.security.auth.Subject)
-   */
-  @Override
-  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) {
-    return null;
-  }
-
-  /* (non-Javadoc)
-   * @see org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAssertionFilter#mapUserPrincipal(java.lang.String)
-   */
-  @Override
-  public String mapUserPrincipal(String principalName) {
-    return prefix + principalName + suffix;
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/ConcatIdentityAsserterMessages.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/ConcatIdentityAsserterMessages.java b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/ConcatIdentityAsserterMessages.java
new file mode 100644
index 0000000..a1d9db1
--- /dev/null
+++ b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/ConcatIdentityAsserterMessages.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway;
+
+import org.apache.knox.gateway.i18n.messages.Message;
+import org.apache.knox.gateway.i18n.messages.MessageLevel;
+import org.apache.knox.gateway.i18n.messages.Messages;
+import org.apache.knox.gateway.i18n.messages.StackTrace;
+
+@Messages(logger="org.apache.hadoop.gateway")
+public interface ConcatIdentityAsserterMessages {
+
+  @Message( level = MessageLevel.WARN, text = "Skipping unencodable parameter {0}={1}, {2}: {3}" )
+  void skippingUnencodableParameter( String name, String value, String encoding, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java
new file mode 100644
index 0000000..726ac6e
--- /dev/null
+++ b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributor.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.concat.filter;
+
+import org.apache.knox.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
+
+public class ConcatIdentityAsserterDeploymentContributor extends AbstractIdentityAsserterDeploymentContributor {
+
+  @Override
+  public String getName() {
+    return "Concat";
+  }
+
+  protected String getFilterClassname() {
+    return ConcatIdentityAssertionFilter.class.getName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
new file mode 100644
index 0000000..9665d78
--- /dev/null
+++ b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.concat.filter;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
+
+public class ConcatIdentityAssertionFilter extends CommonIdentityAssertionFilter {
+  private String prefix = null;
+  private String suffix = null;
+  
+  /* (non-Javadoc)
+   * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+   */
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    super.init(filterConfig);
+
+    prefix = filterConfig.getInitParameter("concat.prefix");
+    suffix = filterConfig.getInitParameter("concat.suffix");
+    if (prefix == null) {
+      prefix = "";
+    }
+    if (suffix == null) {
+      suffix = "";
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see AbstractIdentityAssertionFilter#mapGroupPrincipals(java.lang.String, javax.security.auth.Subject)
+   */
+  @Override
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) {
+    return null;
+  }
+
+  /* (non-Javadoc)
+   * @see AbstractIdentityAssertionFilter#mapUserPrincipal(java.lang.String)
+   */
+  @Override
+  public String mapUserPrincipal(String principalName) {
+    return prefix + principalName + suffix;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
deleted file mode 100644
index bbfd4ae..0000000
--- a/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
+++ /dev/null
@@ -1,19 +0,0 @@
-##########################################################################
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##########################################################################
-
-org.apache.hadoop.gateway.identityasserter.concat.filter.ConcatIdentityAsserterDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..b7255bc
--- /dev/null
+++ b/gateway-provider-identity-assertion-concat/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
@@ -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.knox.gateway.identityasserter.concat.filter.ConcatIdentityAsserterDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java
deleted file mode 100644
index b046ef6..0000000
--- a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.concat.filter;
-
-import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor;
-import org.apache.hadoop.gateway.identityasserter.concat.filter.ConcatIdentityAsserterDeploymentContributor;
-import org.junit.Test;
-
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
-
-public class ConcatIdentityAsserterDeploymentContributorTest {
-
-  @Test
-  public void testServiceLoader() throws Exception {
-    ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
-    Iterator<ProviderDeploymentContributor> iterator = loader.iterator();
-    assertThat( "Service iterator empty.", iterator.hasNext() );
-    while( iterator.hasNext() ) {
-      Object object = iterator.next();
-      if( object instanceof ConcatIdentityAsserterDeploymentContributor ) {
-        return;
-      }
-    }
-    fail( "Failed to find " + ConcatIdentityAsserterDeploymentContributor.class.getName() + " via service loader." );
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
deleted file mode 100644
index 2531779..0000000
--- a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/hadoop/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.concat.filter;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.security.Principal;
-
-import javax.security.auth.Subject;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-
-import org.apache.hadoop.gateway.security.GroupPrincipal;
-import org.apache.hadoop.gateway.security.PrimaryPrincipal;
-import org.easymock.EasyMock;
-import org.junit.Test;
-
-/**
- *
- */
-public class ConcatIdentityAssertionFilterTest {
-
-  @Test
-  public void testPrefixAndSuffix() throws Exception {
-    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-
-    ConcatIdentityAssertionFilter filter = new ConcatIdentityAssertionFilter();
-    Subject subject = new Subject();
-    
-    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
-    subject.getPrincipals().add(new GroupPrincipal("users"));
-    subject.getPrincipals().add(new GroupPrincipal("admin"));
-    
-    filter.init(config);
-    String username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(username, subject);
-    assertEquals(username, "larry");
-    assertNull(groups); // means for the caller to use the existing subject groups
-    
-    config = EasyMock.createNiceMock( FilterConfig.class );
-    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.expect(config.getInitParameter("concat.prefix") ).andReturn( "sir-" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-    filter.init(config);
-    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    assertEquals(username, "sir-larry");
-
-    config = EasyMock.createNiceMock( FilterConfig.class );
-    context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.expect(config.getInitParameter("concat.suffix") ).andReturn( "-tenant-1" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-    filter.init(config);
-    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    assertEquals(username, "larry-tenant-1");
-
-    config = EasyMock.createNiceMock( FilterConfig.class );
-    context = EasyMock.createNiceMock(ServletContext.class);
-    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
-    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
-    EasyMock.expect(config.getInitParameter("concat.prefix") ).andReturn( "sir-" ).anyTimes();
-    EasyMock.expect(config.getInitParameter("concat.suffix") ).andReturn( "-tenant-1" ).anyTimes();
-    EasyMock.replay( config );
-    EasyMock.replay( context );
-    filter.init(config);
-    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    assertEquals(username, "sir-larry-tenant-1");
-  }
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java
new file mode 100644
index 0000000..f1bae77
--- /dev/null
+++ b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAsserterDeploymentContributorTest.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.concat.filter;
+
+import org.apache.knox.gateway.deploy.ProviderDeploymentContributor;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+public class ConcatIdentityAsserterDeploymentContributorTest {
+
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader<ProviderDeploymentContributor> loader = ServiceLoader.load( ProviderDeploymentContributor.class );
+    Iterator<ProviderDeploymentContributor> iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof ConcatIdentityAsserterDeploymentContributor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + ConcatIdentityAsserterDeploymentContributor.class.getName() + " via service loader." );
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
new file mode 100644
index 0000000..ec0a1e4
--- /dev/null
+++ b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.concat.filter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class ConcatIdentityAssertionFilterTest {
+
+  @Test
+  public void testPrefixAndSuffix() throws Exception {
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    ConcatIdentityAssertionFilter filter = new ConcatIdentityAssertionFilter();
+    Subject subject = new Subject();
+    
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    
+    filter.init(config);
+    String username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    String[] groups = filter.mapGroupPrincipals(username, subject);
+    assertEquals(username, "larry");
+    assertNull(groups); // means for the caller to use the existing subject groups
+    
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("concat.prefix") ).andReturn( "sir-" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    assertEquals(username, "sir-larry");
+
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("concat.suffix") ).andReturn( "-tenant-1" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    assertEquals(username, "larry-tenant-1");
+
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("concat.prefix") ).andReturn( "sir-" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("concat.suffix") ).andReturn( "-tenant-1" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    assertEquals(username, "sir-larry-tenant-1");
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderDeploymentContributor.java b/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderDeploymentContributor.java
deleted file mode 100644
index e20f17a..0000000
--- a/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderDeploymentContributor.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.hadoop.groups.filter;
-
-import org.apache.hadoop.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
-
-/**
- * A provider deployment contributor for looking up authenticated user groups as
- * seen by Hadoop implementation.
- * 
- * @since 0.11.0
- */
-
-public class HadoopGroupProviderDeploymentContributor
-    extends AbstractIdentityAsserterDeploymentContributor {
-
-  /**
-   * Name of our <b>identity-assertion</b> provider.
-   */
-  public static final String HADOOP_GROUP_PROVIDER = "HadoopGroupProvider";
-
-  /* create an instance */
-  public HadoopGroupProviderDeploymentContributor() {
-    super();
-  }
-
-  /*
-   * (non-Javadoc)
-   * 
-   * @see
-   * org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor#getName()
-   */
-  @Override
-  public String getName() {
-    return HADOOP_GROUP_PROVIDER;
-  }
-
-  /*
-   * (non-Javadoc)
-   * 
-   * @see org.apache.hadoop.gateway.identityasserter.common.filter.
-   * AbstractIdentityAsserterDeploymentContributor#getFilterClassname()
-   */
-  @Override
-  protected String getFilterClassname() {
-    return HadoopGroupProviderFilter.class.getName();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java b/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
deleted file mode 100644
index 31ab827..0000000
--- a/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/hadoop/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.gateway.identityasserter.hadoop.groups.filter;
-
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.List;
-
-import javax.security.auth.Subject;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
-import org.apache.hadoop.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
-import org.apache.hadoop.security.GroupMappingServiceProvider;
-import org.apache.hadoop.security.Groups;
-
-/**
- * A filter that integrates the Hadoop {@link GroupMappingServiceProvider} for
- * looking up group membership of the authenticated (asserted) identity.
- * 
- * @since 0.11.0
- */
-public class HadoopGroupProviderFilter extends CommonIdentityAssertionFilter {
-
-  /**
-   * Logging
-   */
-  public static HadoopGroupProviderMessages LOG = MessagesFactory
-      .get(HadoopGroupProviderMessages.class);
-
-  /**
-   * Configuration object needed by for hadoop classes
-   */
-  private Configuration hadoopConfig;
-
-  /**
-   * Hadoop Groups implementation.
-   */
-  private Groups hadoopGroups;
-
-  /* create an instance */
-  public HadoopGroupProviderFilter() {
-    super();
-  }
-
-  @Override
-  public void init(final FilterConfig filterConfig) throws ServletException {
-    super.init(filterConfig);
-
-    try {
-      hadoopConfig = new Configuration(false);
-
-      if (filterConfig.getInitParameterNames() != null) {
-
-        for (final Enumeration<String> keys = filterConfig
-            .getInitParameterNames(); keys.hasMoreElements();) {
-
-          final String key = keys.nextElement();
-          hadoopConfig.set(key, filterConfig.getInitParameter(key));
-
-        }
-
-      }
-      hadoopGroups = new Groups(hadoopConfig);
-
-    } catch (final Exception e) {
-      throw new ServletException(e);
-    }
-
-  }
-
-  /**
-   * Query the Hadoop implementation of {@link Groups} to retrieve groups for
-   * provided user.
-   */
-  public String[] mapGroupPrincipals(final String mappedPrincipalName,
-      final Subject subject) {
-    /* return the groups as seen by Hadoop */
-    String[] groups = null;
-    try {
-      final List<String> groupList = hadoopGroups
-          .getGroups(mappedPrincipalName);
-      LOG.groupsFound(mappedPrincipalName, groupList.toString());
-      groups = groupList.toArray(new String[0]);
-
-    } catch (final IOException e) {
-      if (e.toString().contains("No groups found for user")) {
-        /* no groups found move on */
-        LOG.noGroupsFound(mappedPrincipalName);
-      } else {
-        /* Log the error and return empty group */
-        LOG.errorGettingUserGroups(mappedPrincipalName, e);
-      }
-      groups = new String[0];
-    }
-    return groups;
-  }
-
-  public String mapUserPrincipal(final String principalName) {
-    /* return the passed principal */
-    return principalName;
-  }
-
-}