This is an automated email from the ASF dual-hosted git repository.

vinayakumarb pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new f1875b2  HADOOP-16059. Use SASL Factories Cache to Improve 
Performance. Contributed by Ayush Saxena.
f1875b2 is described below

commit f1875b205e492ef071e7ef78b147efee0e51263d
Author: Vinayakumar B <vinayakum...@apache.org>
AuthorDate: Fri May 3 11:22:14 2019 +0530

    HADOOP-16059. Use SASL Factories Cache to Improve Performance. Contributed 
by Ayush Saxena.
---
 .../hadoop/security/FastSaslClientFactory.java     | 80 ++++++++++++++++++++++
 .../hadoop/security/FastSaslServerFactory.java     | 78 +++++++++++++++++++++
 .../org/apache/hadoop/security/SaslRpcClient.java  | 12 +++-
 .../org/apache/hadoop/security/SaslRpcServer.java  | 58 ++--------------
 .../datatransfer/sasl/SaslParticipant.java         | 26 ++++++-
 5 files changed, 196 insertions(+), 58 deletions(-)

diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/FastSaslClientFactory.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/FastSaslClientFactory.java
new file mode 100644
index 0000000..d5259d3
--- /dev/null
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/FastSaslClientFactory.java
@@ -0,0 +1,80 @@
+/**
+ * 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.security;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslException;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+
+/**
+ * Class for dealing with caching SASL client factories.
+ */
+@InterfaceAudience.LimitedPrivate({ "HDFS", "MapReduce" })
+public class FastSaslClientFactory implements SaslClientFactory {
+  private final Map<String, List<SaslClientFactory>> factoryCache =
+      new HashMap<String, List<SaslClientFactory>>();
+
+  public FastSaslClientFactory(Map<String, ?> props) {
+    final Enumeration<SaslClientFactory> factories =
+        Sasl.getSaslClientFactories();
+    while (factories.hasMoreElements()) {
+      SaslClientFactory factory = factories.nextElement();
+      for (String mech : factory.getMechanismNames(props)) {
+        if (!factoryCache.containsKey(mech)) {
+          factoryCache.put(mech, new ArrayList<SaslClientFactory>());
+        }
+        factoryCache.get(mech).add(factory);
+      }
+    }
+  }
+
+  @Override
+  public String[] getMechanismNames(Map<String, ?> props) {
+    return factoryCache.keySet().toArray(new String[0]);
+  }
+
+  @Override
+  public SaslClient createSaslClient(String[] mechanisms,
+      String authorizationId, String protocol, String serverName,
+      Map<String, ?> props, CallbackHandler cbh) throws SaslException {
+    for (String mechanism : mechanisms) {
+      List<SaslClientFactory> factories = factoryCache.get(mechanism);
+      if (factories != null) {
+        for (SaslClientFactory factory : factories) {
+          SaslClient saslClient =
+              factory.createSaslClient(new String[] {mechanism},
+                  authorizationId, protocol, serverName, props, cbh);
+          if (saslClient != null) {
+            return saslClient;
+          }
+        }
+      }
+    }
+    return null;
+  }
+}
\ No newline at end of file
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/FastSaslServerFactory.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/FastSaslServerFactory.java
new file mode 100644
index 0000000..79519d4
--- /dev/null
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/FastSaslServerFactory.java
@@ -0,0 +1,78 @@
+/**
+ * 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.security;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+
+/**
+ * Class for dealing with caching SASL server factories.
+ */
+@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
+public class FastSaslServerFactory implements SaslServerFactory {
+  private final Map<String, List<SaslServerFactory>> factoryCache =
+      new HashMap<String, List<SaslServerFactory>>();
+
+  public FastSaslServerFactory(Map<String, ?> props) {
+    final Enumeration<SaslServerFactory> factories =
+        Sasl.getSaslServerFactories();
+    while (factories.hasMoreElements()) {
+      SaslServerFactory factory = factories.nextElement();
+      for (String mech : factory.getMechanismNames(props)) {
+        if (!factoryCache.containsKey(mech)) {
+          factoryCache.put(mech, new ArrayList<SaslServerFactory>());
+        }
+        factoryCache.get(mech).add(factory);
+      }
+    }
+  }
+
+  @Override
+  public SaslServer createSaslServer(String mechanism, String protocol,
+      String serverName, Map<String, ?> props, CallbackHandler cbh)
+      throws SaslException {
+    SaslServer saslServer = null;
+    List<SaslServerFactory> factories = factoryCache.get(mechanism);
+    if (factories != null) {
+      for (SaslServerFactory factory : factories) {
+        saslServer = factory.createSaslServer(
+            mechanism, protocol, serverName, props, cbh);
+        if (saslServer != null) {
+          break;
+        }
+      }
+    }
+    return saslServer;
+  }
+
+  @Override
+  public String[] getMechanismNames(Map<String, ?> props) {
+    return factoryCache.keySet().toArray(new String[0]);
+  }
+}
\ No newline at end of file
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java
index d236ab0..a63ad4f 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java
@@ -44,6 +44,7 @@ import javax.security.sasl.RealmChoiceCallback;
 import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
@@ -93,6 +94,7 @@ public class SaslRpcClient {
   private SaslClient saslClient;
   private SaslPropertiesResolver saslPropsResolver;
   private AuthMethod authMethod;
+  private static SaslClientFactory saslFactory;
   
   private static final RpcRequestHeaderProto saslHeader = ProtoUtil
       .makeRpcRequestHeader(RpcKind.RPC_PROTOCOL_BUFFER,
@@ -101,6 +103,10 @@ public class SaslRpcClient {
   private static final RpcSaslProto negotiateRequest =
       RpcSaslProto.newBuilder().setState(SaslState.NEGOTIATE).build();
 
+  static {
+    saslFactory = new FastSaslClientFactory(null);
+  }
+
   /**
    * Create a SaslRpcClient that can be used by a RPC client to negotiate
    * SASL authentication with a RPC server
@@ -251,8 +257,8 @@ public class SaslRpcClient {
       LOG.debug("Creating SASL " + mechanism + "(" + method + ") "
           + " client to authenticate to service at " + saslServerName);
     }
-    return Sasl.createSaslClient(
-        new String[] { mechanism }, saslUser, saslProtocol, saslServerName,
+    return saslFactory.createSaslClient(
+        new String[] {mechanism}, saslUser, saslProtocol, saslServerName,
         saslProperties, saslCallback);
   }
 
@@ -687,4 +693,4 @@ public class SaslRpcClient {
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java
index 643af79..7c3f14d 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java
@@ -26,10 +26,6 @@ import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.security.PrivilegedExceptionAction;
 import java.security.Security;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import javax.security.auth.callback.Callback;
@@ -39,7 +35,6 @@ import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.sasl.AuthorizeCallback;
 import javax.security.sasl.RealmCallback;
-import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 import javax.security.sasl.SaslServerFactory;
@@ -178,10 +173,12 @@ public class SaslRpcServer {
   }
 
   public static void init(Configuration conf) {
-    Security.addProvider(new SaslPlainServer.SecurityProvider());
-    // passing null so factory is populated with all possibilities.  the
-    // properties passed when instantiating a server are what really matter
-    saslFactory = new FastSaslServerFactory(null);
+    if (saslFactory == null) {
+      Security.addProvider(new SaslPlainServer.SecurityProvider());
+      // passing null so factory is populated with all possibilities. the
+      // properties passed when instantiating a server are what really matter
+      saslFactory = new FastSaslServerFactory(null);
+    }
   }
   
   static String encodeIdentifier(byte[] identifier) {
@@ -367,47 +364,4 @@ public class SaslRpcServer {
       }
     }
   }
-  
-  // Sasl.createSaslServer is 100-200X slower than caching the factories!
-  private static class FastSaslServerFactory implements SaslServerFactory {
-    private final Map<String,List<SaslServerFactory>> factoryCache =
-        new HashMap<String,List<SaslServerFactory>>();
-
-    FastSaslServerFactory(Map<String,?> props) {
-      final Enumeration<SaslServerFactory> factories =
-          Sasl.getSaslServerFactories();
-      while (factories.hasMoreElements()) {
-        SaslServerFactory factory = factories.nextElement();
-        for (String mech : factory.getMechanismNames(props)) {
-          if (!factoryCache.containsKey(mech)) {
-            factoryCache.put(mech, new ArrayList<SaslServerFactory>());
-          }
-          factoryCache.get(mech).add(factory);
-        }
-      }
-    }
-
-    @Override
-    public SaslServer createSaslServer(String mechanism, String protocol,
-        String serverName, Map<String,?> props, CallbackHandler cbh)
-        throws SaslException {
-      SaslServer saslServer = null;
-      List<SaslServerFactory> factories = factoryCache.get(mechanism);
-      if (factories != null) {
-        for (SaslServerFactory factory : factories) {
-          saslServer = factory.createSaslServer(
-              mechanism, protocol, serverName, props, cbh);
-          if (saslServer != null) {
-            break;
-          }
-        }
-      }
-      return saslServer;
-    }
-
-    @Override
-    public String[] getMechanismNames(Map<String, ?> props) {
-      return factoryCache.keySet().toArray(new String[0]);
-    }
-  }
 }
diff --git 
a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslParticipant.java
 
b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslParticipant.java
index 1db9f50..f51f458 100644
--- 
a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslParticipant.java
+++ 
b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslParticipant.java
@@ -23,11 +23,15 @@ import java.util.Map;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslClientFactory;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
+import org.apache.hadoop.security.FastSaslClientFactory;
+import org.apache.hadoop.security.FastSaslServerFactory;
 import org.apache.hadoop.security.SaslInputStream;
 import org.apache.hadoop.security.SaslOutputStream;
 
@@ -51,7 +55,20 @@ class SaslParticipant {
   // One of these will always be null.
   private final SaslServer saslServer;
   private final SaslClient saslClient;
+  private static SaslServerFactory saslServerFactory;
+  private static SaslClientFactory saslClientFactory;
 
+  private static void initializeSaslServerFactory() {
+    if (saslServerFactory == null) {
+      saslServerFactory = new FastSaslServerFactory(null);
+    }
+  }
+
+  private static void initializeSaslClientFactory() {
+    if (saslClientFactory == null) {
+      saslClientFactory = new FastSaslClientFactory(null);
+    }
+  }
   /**
    * Creates a SaslParticipant wrapping a SaslServer.
    *
@@ -63,7 +80,8 @@ class SaslParticipant {
   public static SaslParticipant createServerSaslParticipant(
       Map<String, String> saslProps, CallbackHandler callbackHandler)
       throws SaslException {
-    return new SaslParticipant(Sasl.createSaslServer(MECHANISM,
+    initializeSaslServerFactory();
+    return new SaslParticipant(saslServerFactory.createSaslServer(MECHANISM,
       PROTOCOL, SERVER_NAME, saslProps, callbackHandler));
   }
 
@@ -79,8 +97,10 @@ class SaslParticipant {
   public static SaslParticipant createClientSaslParticipant(String userName,
       Map<String, String> saslProps, CallbackHandler callbackHandler)
       throws SaslException {
-    return new SaslParticipant(Sasl.createSaslClient(new String[] { MECHANISM 
},
-      userName, PROTOCOL, SERVER_NAME, saslProps, callbackHandler));
+    initializeSaslClientFactory();
+    return new SaslParticipant(
+        saslClientFactory.createSaslClient(new String[] {MECHANISM}, userName,
+            PROTOCOL, SERVER_NAME, saslProps, callbackHandler));
   }
 
   /**


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to