Repository: knox
Updated Branches:
  refs/heads/master 19166412f -> 79493c2d8


KNOX-1522 - Add HA support for HadoopAuthProvider

Signed-off-by: Kevin Risden <[email protected]>


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

Branch: refs/heads/master
Commit: 79493c2d8219c48c7a64c032d0b3e246a08f4426
Parents: 1916641
Author: Kevin Risden <[email protected]>
Authored: Thu Oct 11 10:29:20 2018 -0400
Committer: Kevin Risden <[email protected]>
Committed: Thu Oct 11 14:53:28 2018 -0400

----------------------------------------------------------------------
 gateway-provider-security-hadoopauth/pom.xml    |  16 +++
 .../gateway/hadoopauth/HadoopAuthMessages.java  |   7 +
 .../deploy/HadoopAuthDeploymentContributor.java |  54 ++++++--
 .../HadoopAuthDeploymentContributorTest.java    | 138 +++++++++++++++++++
 4 files changed, 205 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/79493c2d/gateway-provider-security-hadoopauth/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-security-hadoopauth/pom.xml 
b/gateway-provider-security-hadoopauth/pom.xml
index 4a997f2..3353b68 100755
--- a/gateway-provider-security-hadoopauth/pom.xml
+++ b/gateway-provider-security-hadoopauth/pom.xml
@@ -53,6 +53,11 @@
         </dependency>
 
         <dependency>
+            <groupId>org.jboss.shrinkwrap</groupId>
+            <artifactId>shrinkwrap-api</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
@@ -64,9 +69,20 @@
         </dependency>
 
         <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
             <groupId>org.apache.knox</groupId>
             <artifactId>gateway-test-utils</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-server</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/knox/blob/79493c2d/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/HadoopAuthMessages.java
----------------------------------------------------------------------
diff --git 
a/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/HadoopAuthMessages.java
 
b/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/HadoopAuthMessages.java
index 2a92d36..859e901 100755
--- 
a/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/HadoopAuthMessages.java
+++ 
b/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/HadoopAuthMessages.java
@@ -20,11 +20,18 @@ package org.apache.knox.gateway.hadoopauth;
 import org.apache.knox.gateway.i18n.messages.Message;
 import org.apache.knox.gateway.i18n.messages.MessageLevel;
 import org.apache.knox.gateway.i18n.messages.Messages;
+import org.apache.knox.gateway.i18n.messages.StackTrace;
 
 @Messages(logger="org.apache.knox.gateway.provider.global.hadoopauth")
 public interface HadoopAuthMessages {
   
   @Message( level = MessageLevel.DEBUG, text = "Hadoop Authentication Asserted 
Principal: {0}" )
   void hadoopAuthAssertedPrincipal(String name);
+
+  @Message( level = MessageLevel.ERROR, text = "Alias service exception: {0}" )
+  void aliasServiceException(@StackTrace( level = MessageLevel.DEBUG ) 
Exception e);
+
+  @Message( level = MessageLevel.ERROR, text = "Unable to get password for 
{0}: {1}" )
+  void unableToGetPassword(String name, @StackTrace( level = 
MessageLevel.DEBUG ) Exception e);
   
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/79493c2d/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/deploy/HadoopAuthDeploymentContributor.java
----------------------------------------------------------------------
diff --git 
a/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/deploy/HadoopAuthDeploymentContributor.java
 
b/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/deploy/HadoopAuthDeploymentContributor.java
index 92c2bb6..4cc4925 100755
--- 
a/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/deploy/HadoopAuthDeploymentContributor.java
+++ 
b/gateway-provider-security-hadoopauth/src/main/java/org/apache/knox/gateway/hadoopauth/deploy/HadoopAuthDeploymentContributor.java
@@ -21,6 +21,12 @@ import org.apache.knox.gateway.deploy.DeploymentContext;
 import org.apache.knox.gateway.deploy.ProviderDeploymentContributorBase;
 import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
 import org.apache.knox.gateway.descriptor.ResourceDescriptor;
+import org.apache.knox.gateway.hadoopauth.HadoopAuthMessages;
+import org.apache.knox.gateway.hadoopauth.filter.HadoopAuthFilter;
+import org.apache.knox.gateway.hadoopauth.filter.HadoopAuthPostFilter;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.AliasServiceException;
 import org.apache.knox.gateway.topology.Provider;
 import org.apache.knox.gateway.topology.Service;
 
@@ -30,14 +36,16 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
-public class HadoopAuthDeploymentContributor extends
-    ProviderDeploymentContributorBase {
+public class HadoopAuthDeploymentContributor extends 
ProviderDeploymentContributorBase {
 
-  private static final String ROLE = "authentication";
-  private static final String NAME = "HadoopAuth";
+  private static HadoopAuthMessages log = MessagesFactory.get( 
HadoopAuthMessages.class );
 
-  private static final String HADOOPAUTH_FILTER_CLASSNAME = 
"org.apache.knox.gateway.hadoopauth.filter.HadoopAuthFilter";
-  private static final String HADOOPAUTH_POSTFILTER_CLASSNAME = 
"org.apache.knox.gateway.hadoopauth.filter.HadoopAuthPostFilter";
+  private static final String HADOOPAUTH_FILTER_CLASSNAME = 
HadoopAuthFilter.class.getCanonicalName();
+  private static final String HADOOPAUTH_POSTFILTER_CLASSNAME = 
HadoopAuthPostFilter.class.getCanonicalName();
+
+  public static final String ROLE = "authentication";
+  public static final String NAME = "HadoopAuth";
+  private AliasService as;
 
   @Override
   public String getRole() {
@@ -49,6 +57,10 @@ public class HadoopAuthDeploymentContributor extends
     return NAME;
   }
 
+  public void setAliasService(AliasService as) {
+    this.as = as;
+  }
+
   @Override
   public void initializeContribution(DeploymentContext context) {
     super.initializeContribution(context);
@@ -57,15 +69,37 @@ public class HadoopAuthDeploymentContributor extends
   @Override
   public void contributeFilter(DeploymentContext context, Provider provider, 
Service service,
       ResourceDescriptor resource, List<FilterParamDescriptor> params) {
+    String clusterName = context.getTopology().getName();
+
+    List<String> aliases = new ArrayList<>();
+    try {
+      aliases = this.as.getAliasesForCluster(clusterName);
+    } catch (AliasServiceException e) {
+      log.aliasServiceException(e);
+    }
+
     // blindly add all the provider params as filter init params
     if (params == null) {
-      params = new ArrayList<FilterParamDescriptor>();
+      params = new ArrayList<>();
     }
     Map<String, String> providerParams = provider.getParams();
     for(Entry<String, String> entry : providerParams.entrySet()) {
-      params.add( resource.createFilterParam().name( 
entry.getKey().toLowerCase(Locale.ROOT) ).value( entry.getValue() ) );
+      String key = entry.getKey().toLowerCase(Locale.ROOT);
+      String value = null;
+      if(aliases.contains(key)) {
+        try {
+          value = 
String.valueOf(this.as.getPasswordFromAliasForCluster(clusterName, key));
+        } catch (AliasServiceException e) {
+          log.unableToGetPassword(key, e);
+        }
+      } else {
+        value = entry.getValue();
+      }
+
+      params.add( resource.createFilterParam().name( key ).value( value ) );
     }
-    resource.addFilter().name( getName() ).role( getRole() ).impl( 
HADOOPAUTH_FILTER_CLASSNAME ).params( params );
-    resource.addFilter().name( "Post" + getName() ).role( getRole() ).impl( 
HADOOPAUTH_POSTFILTER_CLASSNAME ).params( params );
+
+    resource.addFilter().name( getName() ).role( getRole() 
).impl(HADOOPAUTH_FILTER_CLASSNAME).params( params );
+    resource.addFilter().name( "Post" + getName() ).role( getRole() 
).impl(HADOOPAUTH_POSTFILTER_CLASSNAME).params( params );
   }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/79493c2d/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/HadoopAuthDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git 
a/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/HadoopAuthDeploymentContributorTest.java
 
b/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/HadoopAuthDeploymentContributorTest.java
new file mode 100644
index 0000000..7306172
--- /dev/null
+++ 
b/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/HadoopAuthDeploymentContributorTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.hadoopauth;
+
+import org.apache.knox.gateway.deploy.DeploymentContext;
+import org.apache.knox.gateway.deploy.ProviderDeploymentContributor;
+import org.apache.knox.gateway.descriptor.FilterDescriptor;
+import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
+import org.apache.knox.gateway.descriptor.GatewayDescriptor;
+import org.apache.knox.gateway.descriptor.ResourceDescriptor;
+import org.apache.knox.gateway.descriptor.impl.GatewayDescriptorImpl;
+import 
org.apache.knox.gateway.hadoopauth.deploy.HadoopAuthDeploymentContributor;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
+import org.apache.knox.gateway.topology.Provider;
+import org.apache.knox.gateway.topology.Topology;
+import org.easymock.EasyMock;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.TreeMap;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class HadoopAuthDeploymentContributorTest {
+
+  @SuppressWarnings("rawtypes")
+  @Test
+  public void testServiceLoader() {
+    ServiceLoader loader = ServiceLoader.load( 
ProviderDeploymentContributor.class );
+    Iterator iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof HadoopAuthDeploymentContributor) {
+        return;
+      }
+    }
+    fail( "Failed to find " + HadoopAuthDeploymentContributor.class.getName() 
+ " via service loader." );
+  }
+
+  @Test
+  public void testDeployment() throws Exception {
+    String aliasKey = "signature.secret";
+    String aliasValue = "password";
+    String normalKey = "type";
+    String normalValue = "simple";
+
+    WebArchive webArchive = ShrinkWrap.create( WebArchive.class, 
"test-acrhive" );
+
+    Provider provider = new Provider();
+    provider.setEnabled( true );
+    provider.setName( HadoopAuthDeploymentContributor.NAME );
+    // Keep order of params in map for testing
+    Map<String, String> params = new TreeMap<>();
+    params.put(aliasKey, aliasKey);
+    params.put(normalKey, normalValue);
+    provider.setParams(params);
+
+    Topology topology = new Topology();
+    topology.setName( "Sample" );
+
+    DeploymentContext context = EasyMock.createNiceMock( 
DeploymentContext.class );
+    EasyMock.expect( context.getWebArchive() ).andReturn( webArchive 
).anyTimes();
+    EasyMock.expect( context.getTopology() ).andReturn( topology ).anyTimes();
+    EasyMock.replay( context );
+
+    GatewayDescriptor gatewayDescriptor = new GatewayDescriptorImpl();
+    ResourceDescriptor resource = gatewayDescriptor.createResource();
+    
+    AliasService as = EasyMock.createNiceMock( AliasService.class );
+    EasyMock.expect(as.getAliasesForCluster(context.getTopology().getName()))
+        .andReturn(Collections.singletonList(aliasKey)).anyTimes();
+    
EasyMock.expect(as.getPasswordFromAliasForCluster(context.getTopology().getName(),
 aliasKey))
+        .andReturn(aliasValue.toCharArray()).anyTimes();
+    EasyMock.replay( as );
+    DefaultCryptoService cryptoService = new DefaultCryptoService();
+    cryptoService.setAliasService( as );
+
+    GatewayServices gatewayServices = EasyMock.createNiceMock( 
GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( 
GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService ).anyTimes();
+
+    HadoopAuthDeploymentContributor contributor = new 
HadoopAuthDeploymentContributor();
+    contributor.setAliasService(as);
+
+    assertThat( contributor.getRole(), is( 
HadoopAuthDeploymentContributor.ROLE ) );
+    assertThat( contributor.getName(), is( 
HadoopAuthDeploymentContributor.NAME ) );
+
+    // Just make sure it doesn't blow up.
+    contributor.initializeContribution( context );
+
+    contributor.contributeFilter(context, provider, null, resource, null);
+
+    // Just make sure it doesn't blow up.
+    contributor.finalizeContribution( context );
+
+    // Check that the params are properly setup
+    FilterDescriptor hadoopAuthFilterDescriptor = resource.filters().get(0);
+    assertNotNull(hadoopAuthFilterDescriptor);
+    assertEquals(HadoopAuthDeploymentContributor.NAME, 
hadoopAuthFilterDescriptor.name());
+    List<FilterParamDescriptor> hadoopAuthFilterParams = 
hadoopAuthFilterDescriptor.params();
+    assertEquals(2, hadoopAuthFilterParams.size());
+
+    FilterParamDescriptor paramDescriptor = hadoopAuthFilterParams.get(0);
+    assertEquals(aliasKey, paramDescriptor.name());
+    assertEquals(aliasValue, paramDescriptor.value());
+
+    FilterParamDescriptor paramDescriptor2 = hadoopAuthFilterParams.get(1);
+    assertEquals(normalKey, paramDescriptor2.name());
+    assertEquals(normalValue, paramDescriptor2.value());
+  }
+}

Reply via email to