You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by yu...@apache.org on 2015/12/19 00:12:37 UTC

[2/3] cassandra git commit: Add back support for 3rd party auth providers to bulk loader

Add back support for 3rd party auth providers to bulk loader

patch by Mike Adamson; reviewed by yukim for CASSANDRA-10873


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

Branch: refs/heads/trunk
Commit: fa18880e73f7f3bdbb1075c0baa54a7df3e667d0
Parents: 2e09583
Author: Mike Adamson <ma...@datastax.com>
Authored: Wed Dec 16 10:37:47 2015 +0000
Committer: Yuki Morishita <yu...@apache.org>
Committed: Fri Dec 18 17:09:28 2015 -0600

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../org/apache/cassandra/tools/BulkLoader.java  | 79 ++++++++++++++++++--
 .../utils/NativeSSTableLoaderClient.java        | 16 ++--
 3 files changed, 84 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/fa18880e/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index e6ab5dd..199e374 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.3
+ * Add back support for 3rd party auth providers to bulk loader (CASSANDRA-10873)
  * Eliminate the dependency on jgrapht for UDT resolution (CASSANDRA-10653)
  * (Hadoop) Close Clusters and Sessions in Hadoop Input/Output classes (CASSANDRA-1837)
  * Fix sstableloader not working with upper case keyspace name (CASSANDRA-10806)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/fa18880e/src/java/org/apache/cassandra/tools/BulkLoader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/BulkLoader.java b/src/java/org/apache/cassandra/tools/BulkLoader.java
index 73194a1..2b94a68 100644
--- a/src/java/org/apache/cassandra/tools/BulkLoader.java
+++ b/src/java/org/apache/cassandra/tools/BulkLoader.java
@@ -19,6 +19,8 @@ package org.apache.cassandra.tools;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
 import java.net.UnknownHostException;
@@ -28,6 +30,8 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import org.apache.commons.cli.*;
 
+import com.datastax.driver.core.AuthProvider;
+import com.datastax.driver.core.PlainTextAuthProvider;
 import com.datastax.driver.core.SSLOptions;
 import javax.net.ssl.SSLContext;
 import org.apache.cassandra.config.*;
@@ -50,6 +54,7 @@ public class BulkLoader
     private static final String NATIVE_PORT_OPTION = "port";
     private static final String USER_OPTION = "username";
     private static final String PASSWD_OPTION = "password";
+    private static final String AUTH_PROVIDER_OPTION = "auth-provider";
     private static final String THROTTLE_MBITS = "throttle";
 
     /* client encryption options */
@@ -67,15 +72,14 @@ public class BulkLoader
     public static void main(String args[])
     {
         Config.setClientMode(true);
-        LoaderOptions options = LoaderOptions.parseArgs(args);
+        LoaderOptions options = LoaderOptions.parseArgs(args).validateArguments();
         OutputHandler handler = new OutputHandler.SystemOutput(options.verbose, options.debug);
         SSTableLoader loader = new SSTableLoader(
                 options.directory,
                 new ExternalClient(
                         options.hosts,
                         options.nativePort,
-                        options.user,
-                        options.passwd,
+                        options.authProvider,
                         options.storagePort,
                         options.sslStoragePort,
                         options.serverEncOptions,
@@ -277,14 +281,13 @@ public class BulkLoader
 
         public ExternalClient(Set<InetAddress> hosts,
                               int port,
-                              String user,
-                              String passwd,
+                              AuthProvider authProvider,
                               int storagePort,
                               int sslStoragePort,
                               EncryptionOptions.ServerEncryptionOptions serverEncryptionOptions,
                               SSLOptions sslOptions)
         {
-            super(hosts, port, user, passwd, sslOptions);
+            super(hosts, port, authProvider, sslOptions);
             this.storagePort = storagePort;
             this.sslStoragePort = sslStoragePort;
             this.serverEncOptions = serverEncryptionOptions;
@@ -307,6 +310,8 @@ public class BulkLoader
         public int nativePort = 9042;
         public String user;
         public String passwd;
+        public String authProviderName;
+        public AuthProvider authProvider;
         public int throttle = 0;
         public int storagePort;
         public int sslStoragePort;
@@ -374,6 +379,9 @@ public class BulkLoader
                 if (cmd.hasOption(PASSWD_OPTION))
                     opts.passwd = cmd.getOptionValue(PASSWD_OPTION);
 
+                if (cmd.hasOption(AUTH_PROVIDER_OPTION))
+                    opts.authProviderName = cmd.getOptionValue(AUTH_PROVIDER_OPTION);
+
                 if (cmd.hasOption(INITIAL_HOST_ADDRESS_OPTION))
                 {
                     String[] nodes = cmd.getOptionValue(INITIAL_HOST_ADDRESS_OPTION).split(",");
@@ -494,6 +502,64 @@ public class BulkLoader
             }
         }
 
+        public LoaderOptions validateArguments()
+        {
+            // Both username and password need to be provided
+            if ((user != null) != (passwd != null))
+                errorMsg("Username and password must both be provided", getCmdLineOptions());
+
+            if (user != null)
+            {
+                // Support for 3rd party auth providers that support plain text credentials.
+                // In this case the auth provider must provide a constructor of the form:
+                //
+                // public MyAuthProvider(String username, String password)
+                if (authProviderName != null)
+                {
+                    try
+                    {
+                        Class authProviderClass = Class.forName(authProviderName);
+                        Constructor constructor = authProviderClass.getConstructor(String.class, String.class);
+                        authProvider = (AuthProvider)constructor.newInstance(user, passwd);
+                    }
+                    catch (ClassNotFoundException e)
+                    {
+                        errorMsg("Unknown auth provider: " + e.getMessage(), getCmdLineOptions());
+                    }
+                    catch (NoSuchMethodException e)
+                    {
+                        errorMsg("Auth provider does not support plain text credentials: " + e.getMessage(), getCmdLineOptions());
+                    }
+                    catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
+                    {
+                        errorMsg("Could not create auth provider with plain text credentials: " + e.getMessage(), getCmdLineOptions());
+                    }
+                }
+                else
+                {
+                    // If a 3rd party auth provider wasn't provided use the driver plain text provider
+                    authProvider = new PlainTextAuthProvider(user, passwd);
+                }
+            }
+            // Alternate support for 3rd party auth providers that don't use plain text credentials.
+            // In this case the auth provider must provide a nullary constructor of the form:
+            //
+            // public MyAuthProvider()
+            else if (authProviderName != null)
+            {
+                try
+                {
+                    authProvider = (AuthProvider)Class.forName(authProviderName).newInstance();
+                }
+                catch (ClassNotFoundException | InstantiationException | IllegalAccessException e)
+                {
+                    errorMsg("Unknown auth provider" + e.getMessage(), getCmdLineOptions());
+                }
+            }
+
+            return this;
+        }
+
         private static void errorMsg(String msg, CmdLineOptions options)
         {
             System.err.println(msg);
@@ -513,6 +579,7 @@ public class BulkLoader
             options.addOption("t",  THROTTLE_MBITS, "throttle", "throttle speed in Mbits (default unlimited)");
             options.addOption("u",  USER_OPTION, "username", "username for cassandra authentication");
             options.addOption("pw", PASSWD_OPTION, "password", "password for cassandra authentication");
+            options.addOption("ap", AUTH_PROVIDER_OPTION, "auth provider", "custom AuthProvider class name for cassandra authentication");
             options.addOption("cph", CONNECTIONS_PER_HOST, "connectionsPerHost", "number of concurrent connections-per-host.");
             // ssl connection-related options
             options.addOption("ts", SSL_TRUSTSTORE, "TRUSTSTORE", "Client SSL: full path to truststore");

http://git-wip-us.apache.org/repos/asf/cassandra/blob/fa18880e/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java b/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java
index bb927fc..225e453 100644
--- a/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java
+++ b/src/java/org/apache/cassandra/utils/NativeSSTableLoaderClient.java
@@ -40,18 +40,22 @@ public class NativeSSTableLoaderClient extends SSTableLoader.Client
     protected final Map<String, CFMetaData> tables;
     private final Collection<InetAddress> hosts;
     private final int port;
-    private final String username;
-    private final String password;
+    private final AuthProvider authProvider;
     private final SSLOptions sslOptions;
 
+
     public NativeSSTableLoaderClient(Collection<InetAddress> hosts, int port, String username, String password, SSLOptions sslOptions)
     {
+        this(hosts, port, new PlainTextAuthProvider(username, password), sslOptions);
+    }
+
+    public NativeSSTableLoaderClient(Collection<InetAddress> hosts, int port, AuthProvider authProvider, SSLOptions sslOptions)
+    {
         super();
         this.tables = new HashMap<>();
         this.hosts = hosts;
         this.port = port;
-        this.username = username;
-        this.password = password;
+        this.authProvider = authProvider;
         this.sslOptions = sslOptions;
     }
 
@@ -60,8 +64,8 @@ public class NativeSSTableLoaderClient extends SSTableLoader.Client
         Cluster.Builder builder = Cluster.builder().addContactPoints(hosts).withPort(port);
         if (sslOptions != null)
             builder.withSSL(sslOptions);
-        if (username != null && password != null)
-            builder = builder.withCredentials(username, password);
+        if (authProvider != null)
+            builder = builder.withAuthProvider(authProvider);
 
         try (Cluster cluster = builder.build(); Session session = cluster.connect())
         {