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

tdsilva pushed a commit to branch 4.14-HBase-1.2
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 77dde071113f3160bba6093fba928514efa4ff92
Author: Karan Mehta <karanmeht...@gmail.com>
AuthorDate: Mon Aug 20 16:52:22 2018 -0700

    PHOENIX-4755 Provide an option to plugin custom avatica server config in PQS
---
 .../org/apache/phoenix/query/QueryServices.java    |   3 +-
 .../apache/phoenix/query/QueryServicesOptions.java |   1 +
 .../phoenix/end2end/ServerCustomizersIT.java       |   4 +-
 .../server/AvaticaServerConfigurationFactory.java  |  20 +++
 .../phoenix/queryserver/server/QueryServer.java    | 167 ++++++++++++++-------
 .../server/ServerCustomizersFactory.java           |   7 +-
 .../CustomAvaticaServerConfigurationTest.java      |  20 +++
 .../server/QueryServerConfigurationTest.java       |  26 +++-
 .../queryserver/server/ServerCustomizersTest.java  |  13 +-
 9 files changed, 194 insertions(+), 67 deletions(-)

diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java 
b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
index c7548df..9072d26 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
@@ -251,8 +251,9 @@ public interface QueryServices extends SQLCloseable {
     public static final String QUERY_SERVER_KERBEROS_ALLOWED_REALMS = 
"phoenix.queryserver.kerberos.allowed.realms";
     public static final String QUERY_SERVER_SPNEGO_AUTH_DISABLED_ATTRIB = 
"phoenix.queryserver.spnego.auth.disabled";
     public static final String QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR_ATTRIB = 
"phoenix.queryserver.withRemoteUserExtractor";
-    public static final String QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM = 
"phoenix.queryserver.remoteUserExtractor.param";
     public static final String QUERY_SERVER_CUSTOMIZERS_ENABLED = 
"phoenix.queryserver.customizers.enabled";
+    public static final String QUERY_SERVER_CUSTOM_AUTH_ENABLED = 
"phoenix.queryserver.custom.auth.enabled";
+    public static final String QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM = 
"phoenix.queryserver.remoteUserExtractor.param";
     public static final String QUERY_SERVER_DISABLE_KERBEROS_LOGIN = 
"phoenix.queryserver.disable.kerberos.login";
 
     // metadata configs
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java 
b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
index 7933ba0..02a3d4b 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
@@ -299,6 +299,7 @@ public class QueryServicesOptions {
     public static final int DEFAULT_QUERY_SERVER_UGI_CACHE_CONCURRENCY = 10;
     public static final boolean DEFAULT_QUERY_SERVER_SPNEGO_AUTH_DISABLED = 
false;
     public static final boolean DEFAULT_QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR 
= false;
+    public static final boolean DEFAULT_QUERY_SERVER_CUSTOM_AUTH_ENABLED = 
false;
     public static final String DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM 
= "doAs";
     public static final boolean DEFAULT_QUERY_SERVER_DISABLE_KERBEROS_LOGIN = 
false;
     public static final boolean DEFAULT_QUERY_SERVER_CUSTOMIZERS_ENABLED = 
false;
diff --git 
a/phoenix-queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
 
b/phoenix-queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
index d990adb..db08908 100644
--- 
a/phoenix-queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
+++ 
b/phoenix-queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
 import org.apache.calcite.avatica.server.ServerCustomizer;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.phoenix.query.QueryServices;
@@ -66,7 +67,8 @@ public class ServerCustomizersIT extends 
BaseHBaseManagedTimeIT {
         InstanceResolver.clearSingletons();
         InstanceResolver.getSingleton(ServerCustomizersFactory.class, new 
ServerCustomizersFactory() {
             @Override
-            public List<ServerCustomizer<Server>> 
createServerCustomizers(Configuration conf) {
+            public List<ServerCustomizer<Server>> 
createServerCustomizers(Configuration conf,
+                                                                          
AvaticaServerConfiguration avaticaServerConfiguration) {
                 return Collections.<ServerCustomizer<Server>>singletonList(new 
TestServerCustomizer());
             }
         });
diff --git 
a/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/AvaticaServerConfigurationFactory.java
 
b/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/AvaticaServerConfigurationFactory.java
new file mode 100644
index 0000000..87a72ea
--- /dev/null
+++ 
b/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/AvaticaServerConfigurationFactory.java
@@ -0,0 +1,20 @@
+package org.apache.phoenix.queryserver.server;
+
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+
+
+public interface AvaticaServerConfigurationFactory {
+
+    AvaticaServerConfiguration getAvaticaServerConfiguration(Configuration 
conf, UserGroupInformation ugi);
+
+    class AvaticaServerConfigurationFactoryImpl implements 
AvaticaServerConfigurationFactory {
+
+        @Override
+        public AvaticaServerConfiguration 
getAvaticaServerConfiguration(Configuration conf, UserGroupInformation ugi) {
+            return null;
+        }
+    }
+
+}
diff --git 
a/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
 
b/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
index 47466c8..4766394 100644
--- 
a/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
+++ 
b/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
@@ -27,6 +27,7 @@ import org.apache.calcite.avatica.Meta;
 import org.apache.calcite.avatica.remote.Driver;
 import org.apache.calcite.avatica.remote.LocalService;
 import org.apache.calcite.avatica.remote.Service;
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
 import org.apache.calcite.avatica.server.DoAsRemoteUserCallback;
 import org.apache.calcite.avatica.server.HttpServer;
 import org.apache.calcite.avatica.server.RemoteUserExtractor;
@@ -76,6 +77,8 @@ import java.util.concurrent.TimeUnit;
 
 import javax.servlet.http.HttpServletRequest;
 
+import static 
org.apache.phoenix.query.QueryServicesOptions.DEFAULT_QUERY_SERVER_CUSTOM_AUTH_ENABLED;
+
 /**
  * A query server for Phoenix over Calcite's Avatica.
  */
@@ -219,27 +222,38 @@ public final class QueryServer extends Configured 
implements Tool, Runnable {
         LOG.info(" Kerberos is off and hostname is : "+hostname);
       }
 
-      Class<? extends PhoenixMetaFactory> factoryClass = getConf().getClass(
-          QueryServices.QUERY_SERVER_META_FACTORY_ATTRIB, 
PhoenixMetaFactoryImpl.class,
-          PhoenixMetaFactory.class);
       int port = getConf().getInt(QueryServices.QUERY_SERVER_HTTP_PORT_ATTRIB,
           QueryServicesOptions.DEFAULT_QUERY_SERVER_HTTP_PORT);
       LOG.debug("Listening on port " + port);
-      PhoenixMetaFactory factory =
-          
factoryClass.getDeclaredConstructor(Configuration.class).newInstance(getConf());
-      Meta meta = factory.create(Arrays.asList(args));
-      Service service = new LocalService(meta);
+
+      // Update proxyuser configuration for impersonation
+      ProxyUsers.refreshSuperUserGroupsConfiguration(getConf());
 
       // Start building the Avatica HttpServer
-      final HttpServer.Builder<Server> builder = HttpServer.Builder.<Server> 
newBuilder()
-          .withPort(port).withHandler(service, getSerialization(getConf()));
+      final HttpServer.Builder<Server>
+              builder =
+              HttpServer.Builder.<Server>newBuilder().withPort(port);
+
+      UserGroupInformation ugi = getUserGroupInformation();
 
-      // Enable client auth when using Kerberos auth for HBase
-      if (isKerberos) {
-        configureClientAuthentication(builder, disableSpnego);
+      AvaticaServerConfiguration avaticaServerConfiguration = null;
+
+      // RemoteUserCallbacks and RemoteUserExtractor are part of 
AvaticaServerConfiguration
+      // Hence they should be customizable when using 
QUERY_SERVER_CUSTOM_AUTH_ENABLED
+      // Handlers should be customized via ServerCustomizers
+      if (getConf().getBoolean(QueryServices.QUERY_SERVER_CUSTOM_AUTH_ENABLED,
+              DEFAULT_QUERY_SERVER_CUSTOM_AUTH_ENABLED)) {
+        avaticaServerConfiguration = enableCustomAuth(builder, getConf(), ugi);
+      } else {
+        if (isKerberos) {
+          // Enable client auth when using Kerberos auth for HBase
+          configureClientAuthentication(builder, disableSpnego, ugi);
+        }
+        setRemoteUserExtractorIfNecessary(builder, getConf());
+        setHandler(args, builder);
       }
-      setRemoteUserExtractorIfNecessary(builder, getConf());
-      enableServerCustomizersIfNecessary(builder, getConf());
+
+      enableServerCustomizersIfNecessary(builder, getConf(), 
avaticaServerConfiguration);
 
       // Build and start the HttpServer
       server = builder.build();
@@ -262,48 +276,71 @@ public final class QueryServer extends Configured 
implements Tool, Runnable {
   }
 
   @VisibleForTesting
-  void configureClientAuthentication(final HttpServer.Builder builder, boolean 
disableSpnego) throws IOException {
+  void configureClientAuthentication(final HttpServer.Builder builder, boolean 
disableSpnego, UserGroupInformation ugi) throws IOException {
+
+    // Enable SPNEGO for client authentication unless it's explicitly disabled
+    if (!disableSpnego) {
+      configureSpnegoAuthentication(builder, ugi);
+    }
+    configureCallBack(builder, ugi);
+  }
+
+  @VisibleForTesting
+  void configureSpnegoAuthentication(HttpServer.Builder builder, 
UserGroupInformation ugi) {
+    String keytabPath = 
getConf().get(QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB);
+    File keytab = new File(keytabPath);
+    String httpKeytabPath =
+            
getConf().get(QueryServices.QUERY_SERVER_HTTP_KEYTAB_FILENAME_ATTRIB, null);
+    String httpPrincipal =
+            
getConf().get(QueryServices.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB, null);
+    // Backwards compat for a configuration key change
+    if (httpPrincipal == null) {
+      httpPrincipal =
+              
getConf().get(QueryServices.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB_LEGACY, 
null);
+    }
+    File httpKeytab = null;
+    if (null != httpKeytabPath) {
+        httpKeytab = new File(httpKeytabPath);
+    }
+
+    String realmsString = 
getConf().get(QueryServices.QUERY_SERVER_KERBEROS_ALLOWED_REALMS, null);
+    String[] additionalAllowedRealms = null;
+    if (null != realmsString) {
+      additionalAllowedRealms = StringUtils.split(realmsString, ',');
+    }
+    if (null != httpKeytabPath && null != httpPrincipal) {
+      builder.withSpnego(httpPrincipal, 
additionalAllowedRealms).withAutomaticLogin(httpKeytab);
+    } else {
+      builder.withSpnego(ugi.getUserName(), additionalAllowedRealms)
+              .withAutomaticLogin(keytab);
+    }
+  }
+
+  @VisibleForTesting
+  UserGroupInformation getUserGroupInformation() throws IOException {
     UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
     LOG.debug("Current user is " + ugi);
     if (!ugi.hasKerberosCredentials()) {
       ugi = UserGroupInformation.getLoginUser();
       LOG.debug("Current user does not have Kerberos credentials, using 
instead " + ugi);
     }
+    return ugi;
+  }
 
-    // Make sure the proxyuser configuration is up to date
-    ProxyUsers.refreshSuperUserGroupsConfiguration(getConf());
-
-    // Always enable impersonation for the proxy user (through standard Hadoop 
configuration means)
+  @VisibleForTesting
+  void configureCallBack(HttpServer.Builder<Server> builder, 
UserGroupInformation ugi) {
     builder.withImpersonation(new PhoenixDoAsCallback(ugi, getConf()));
+  }
 
-    // Enable SPNEGO for client authentication unless it's explicitly disabled
-    if (!disableSpnego) {
-      String keytabPath = 
getConf().get(QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB);
-      File keytab = new File(keytabPath);
-      String httpKeytabPath =
-          
getConf().get(QueryServices.QUERY_SERVER_HTTP_KEYTAB_FILENAME_ATTRIB, null);
-      String httpPrincipal =
-          
getConf().get(QueryServices.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB, null);
-      // Backwards compat for a configuration key change
-      if (httpPrincipal == null) {
-        httpPrincipal =
-            
getConf().get(QueryServices.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB_LEGACY, 
null);
-      }
-      File httpKeytab = null;
-      if (null != httpKeytabPath) httpKeytab = new File(httpKeytabPath);
-
-      String realmsString = 
getConf().get(QueryServices.QUERY_SERVER_KERBEROS_ALLOWED_REALMS, null);
-      String[] additionalAllowedRealms = null;
-      if (null != realmsString) {
-        additionalAllowedRealms = StringUtils.split(realmsString, ',');
-      }
-      if ((null != httpKeytabPath) && (null != httpPrincipal)) {
-        builder.withSpnego(httpPrincipal, 
additionalAllowedRealms).withAutomaticLogin(httpKeytab);
-      } else {
-        builder.withSpnego(ugi.getUserName(), additionalAllowedRealms)
-            .withAutomaticLogin(keytab);
-      }
-    }
+  private void setHandler(String[] args, HttpServer.Builder<Server> builder) 
throws Exception {
+    Class<? extends PhoenixMetaFactory> factoryClass = getConf().getClass(
+            QueryServices.QUERY_SERVER_META_FACTORY_ATTRIB, 
PhoenixMetaFactoryImpl.class,
+            PhoenixMetaFactory.class);
+    PhoenixMetaFactory factory =
+            
factoryClass.getDeclaredConstructor(Configuration.class).newInstance(getConf());
+    Meta meta = factory.create(Arrays.asList(args));
+    Service service = new LocalService(meta);
+    builder.withHandler(service, getSerialization(getConf()));
   }
 
   public synchronized void stop() {
@@ -405,20 +442,32 @@ public final class QueryServer extends Configured 
implements Tool, Runnable {
     }
   }
 
-  private static final RemoteUserExtractorFactory DEFAULT_USER_EXTRACTOR =
-    new RemoteUserExtractorFactory.RemoteUserExtractorFactoryImpl();
-
   @VisibleForTesting
-  public void enableServerCustomizersIfNecessary(HttpServer.Builder<Server> 
builder, Configuration conf) {
+  public void enableServerCustomizersIfNecessary(HttpServer.Builder<Server> 
builder,
+                                                 Configuration conf, 
AvaticaServerConfiguration avaticaServerConfiguration) {
     if (conf.getBoolean(QueryServices.QUERY_SERVER_CUSTOMIZERS_ENABLED,
             QueryServicesOptions.DEFAULT_QUERY_SERVER_CUSTOMIZERS_ENABLED)) {
-      builder.withServerCustomizers(createServerCustomizers(conf), 
Server.class);
+      builder.withServerCustomizers(createServerCustomizers(conf, 
avaticaServerConfiguration), Server.class);
     }
   }
 
+  @VisibleForTesting
+  public AvaticaServerConfiguration 
enableCustomAuth(HttpServer.Builder<Server> builder,
+                                                     Configuration conf, 
UserGroupInformation ugi) {
+    AvaticaServerConfiguration avaticaServerConfiguration = 
createAvaticaServerConfig(conf, ugi);
+    builder.withCustomAuthentication(avaticaServerConfiguration);
+    return avaticaServerConfiguration;
+  }
+
+  private static final RemoteUserExtractorFactory DEFAULT_USER_EXTRACTOR =
+    new RemoteUserExtractorFactory.RemoteUserExtractorFactoryImpl();
+
   private static final ServerCustomizersFactory DEFAULT_SERVER_CUSTOMIZERS =
     new ServerCustomizersFactory.ServerCustomizersFactoryImpl();
 
+  private static final AvaticaServerConfigurationFactory DEFAULT_SERVER_CONFIG 
=
+    new 
AvaticaServerConfigurationFactory.AvaticaServerConfigurationFactoryImpl();
+
   @VisibleForTesting
   RemoteUserExtractor createRemoteUserExtractor(Configuration conf) {
     RemoteUserExtractorFactory factory =
@@ -427,16 +476,22 @@ public final class QueryServer extends Configured 
implements Tool, Runnable {
   }
 
   @VisibleForTesting
-  List<ServerCustomizer<Server>> createServerCustomizers(Configuration conf) {
+  List<ServerCustomizer<Server>> createServerCustomizers(Configuration conf, 
AvaticaServerConfiguration avaticaServerConfiguration) {
     ServerCustomizersFactory factory =
       InstanceResolver.getSingleton(ServerCustomizersFactory.class, 
DEFAULT_SERVER_CUSTOMIZERS);
-    return factory.createServerCustomizers(conf);
+    return factory.createServerCustomizers(conf, avaticaServerConfiguration);
+  }
+
+  @VisibleForTesting
+  AvaticaServerConfiguration createAvaticaServerConfig(Configuration conf, 
UserGroupInformation ugi) {
+    AvaticaServerConfigurationFactory factory =
+            
InstanceResolver.getSingleton(AvaticaServerConfigurationFactory.class, 
DEFAULT_SERVER_CONFIG);
+    return factory.getAvaticaServerConfiguration(conf, ugi);
   }
 
   /**
    * Use the correctly way to extract end user.
    */
-
   static class PhoenixRemoteUserExtractor implements RemoteUserExtractor{
     private final HttpQueryStringParameterRemoteUserExtractor 
paramRemoteUserExtractor;
     private final HttpRequestRemoteUserExtractor requestRemoteUserExtractor;
@@ -477,7 +532,7 @@ public final class QueryServer extends Configured 
implements Tool, Runnable {
   /**
    * Callback to run the Avatica server action as the remote (proxy) user 
instead of the server.
    */
-  static class PhoenixDoAsCallback implements DoAsRemoteUserCallback {
+  public static class PhoenixDoAsCallback implements DoAsRemoteUserCallback {
     private final UserGroupInformation serverUgi;
     private final LoadingCache<String,UserGroupInformation> ugiCache;
 
diff --git 
a/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/ServerCustomizersFactory.java
 
b/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/ServerCustomizersFactory.java
index 462cd5d..942660a 100644
--- 
a/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/ServerCustomizersFactory.java
+++ 
b/phoenix-queryserver/src/main/java/org/apache/phoenix/queryserver/server/ServerCustomizersFactory.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.queryserver.server;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
 import org.apache.calcite.avatica.server.ServerCustomizer;
 import org.apache.hadoop.conf.Configuration;
 import org.eclipse.jetty.server.Server;
@@ -32,9 +33,10 @@ public interface ServerCustomizersFactory {
     /**
      * Creates a list of customizers that will customize the server.
      * @param conf Configuration to use
+     * @param avaticaServerConfiguration to use in case custom-auth is enabled
      * @return List of server suctomizers
      */
-    List<ServerCustomizer<Server>> createServerCustomizers(Configuration conf);
+    List<ServerCustomizer<Server>> createServerCustomizers(Configuration conf, 
AvaticaServerConfiguration avaticaServerConfiguration);
 
     /**
      * Factory that creates an empty list of customizers.
@@ -42,7 +44,8 @@ public interface ServerCustomizersFactory {
     class ServerCustomizersFactoryImpl implements ServerCustomizersFactory {
         private static final List<ServerCustomizer<Server>> EMPTY_LIST = 
Collections.emptyList();
         @Override
-        public List<ServerCustomizer<Server>> 
createServerCustomizers(Configuration conf) {
+        public List<ServerCustomizer<Server>> 
createServerCustomizers(Configuration conf,
+                                                                      
AvaticaServerConfiguration avaticaServerConfiguration) {
             return EMPTY_LIST;
         }
     }
diff --git 
a/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/CustomAvaticaServerConfigurationTest.java
 
b/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/CustomAvaticaServerConfigurationTest.java
new file mode 100644
index 0000000..20bc868
--- /dev/null
+++ 
b/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/CustomAvaticaServerConfigurationTest.java
@@ -0,0 +1,20 @@
+package org.apache.phoenix.queryserver.server;
+
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class CustomAvaticaServerConfigurationTest {
+    @Test
+    public void testDefaultFactory() throws IOException {
+        QueryServer queryServer = new QueryServer();
+        UserGroupInformation ugi = queryServer.getUserGroupInformation();
+        // the default factory creates null object
+        AvaticaServerConfiguration avaticaServerConfiguration = 
queryServer.createAvaticaServerConfig(new Configuration(), ugi);
+        Assert.assertNull(avaticaServerConfiguration);
+    }
+}
diff --git 
a/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/QueryServerConfigurationTest.java
 
b/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/QueryServerConfigurationTest.java
index f2a1022..d01d2ea 100644
--- 
a/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/QueryServerConfigurationTest.java
+++ 
b/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/QueryServerConfigurationTest.java
@@ -20,10 +20,12 @@ package org.apache.phoenix.queryserver.server;
 import java.io.File;
 import java.io.IOException;
 
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
 import org.apache.calcite.avatica.server.DoAsRemoteUserCallback;
 import org.apache.calcite.avatica.server.HttpServer;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.phoenix.query.QueryServices;
 import org.junit.Before;
 import org.junit.Rule;
@@ -39,34 +41,52 @@ public class QueryServerConfigurationTest {
 
   private HttpServer.Builder builder;
   private QueryServer queryServer;
+  private UserGroupInformation ugi;
 
   @Before
   public void setup() throws IOException {
-    File keytabFile = testFolder.newFile("test.keytab");
-    CONF.set(QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB, 
keytabFile.getAbsolutePath());
     builder = mock(HttpServer.Builder.class);
     queryServer = new QueryServer(new String[0], CONF);
+    ugi = queryServer.getUserGroupInformation();
   }
 
   @Test
   public void testSpnegoEnabled() throws IOException {
+    setupKeytabForSpnego();
     // SPENEGO settings will be provided to the builder when enabled
     doReturn(builder).when(builder).withSpnego(anyString(), 
any(String[].class));
     configureAndVerifyImpersonation(builder, false);
     // A keytab file will also be provided for automatic login
     verify(builder).withAutomaticLogin(any(File.class));
+    verify(builder, 
never()).withCustomAuthentication(any(AvaticaServerConfiguration.class));
   }
 
   @Test
   public void testSpnegoDisabled() throws IOException {
+    setupKeytabForSpnego();
     configureAndVerifyImpersonation(builder, true);
     verify(builder, never()).withSpnego(anyString(), any(String[].class));
     verify(builder, never()).withAutomaticLogin(any(File.class));
+    verify(builder, 
never()).withCustomAuthentication(any(AvaticaServerConfiguration.class));
+  }
+
+  @Test
+  public void testCustomServerConfiguration() {
+    queryServer.enableCustomAuth(builder, CONF, ugi);
+    
verify(builder).withCustomAuthentication(any(AvaticaServerConfiguration.class));
+    verify(builder, never()).withSpnego(anyString(), any(String[].class));
+    verify(builder, never()).withAutomaticLogin(any(File.class));
+    verify(builder, 
never()).withImpersonation(any(DoAsRemoteUserCallback.class));
+  }
+
+  private void setupKeytabForSpnego() throws IOException {
+    File keytabFile = testFolder.newFile("test.keytab");
+    CONF.set(QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB, 
keytabFile.getAbsolutePath());
   }
 
   private void configureAndVerifyImpersonation(HttpServer.Builder builder, 
boolean disableSpnego)
       throws IOException {
-    queryServer.configureClientAuthentication(builder, disableSpnego);
+    queryServer.configureClientAuthentication(builder, disableSpnego, ugi);
     verify(builder).withImpersonation(any(DoAsRemoteUserCallback.class));
   }
 }
diff --git 
a/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/ServerCustomizersTest.java
 
b/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/ServerCustomizersTest.java
index 45fec37..93e1e37 100644
--- 
a/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/ServerCustomizersTest.java
+++ 
b/phoenix-queryserver/src/test/java/org/apache/phoenix/queryserver/server/ServerCustomizersTest.java
@@ -21,6 +21,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.calcite.avatica.server.HttpServer;
+import org.apache.calcite.avatica.server.AvaticaServerConfiguration;
 import org.apache.calcite.avatica.server.ServerCustomizer;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.phoenix.query.QueryServices;
@@ -45,14 +46,16 @@ public class ServerCustomizersTest {
     @Test
     public void testDefaultFactory() {
         QueryServer queryServer = new QueryServer();
+        AvaticaServerConfiguration avaticaServerConfiguration = null;
         // the default factory creates an empty list of server customizers
         List<ServerCustomizer<Server>> customizers =
-            queryServer.createServerCustomizers(new Configuration());
+                queryServer.createServerCustomizers(new Configuration(), 
avaticaServerConfiguration);
         Assert.assertEquals(0, customizers.size());
     }
 
     @Test
     public void testUseProvidedCustomizers() {
+        AvaticaServerConfiguration avaticaServerConfiguration = null;
         final List<ServerCustomizer<Server>> expected =
             Collections.<ServerCustomizer<Server>> singletonList(new 
ServerCustomizer<Server>() {
               @Override
@@ -63,25 +66,27 @@ public class ServerCustomizersTest {
         // Register the server customizer list
         InstanceResolver.getSingleton(ServerCustomizersFactory.class, new 
ServerCustomizersFactory() {
             @Override
-            public List<ServerCustomizer<Server>> 
createServerCustomizers(Configuration conf) {
+            public List<ServerCustomizer<Server>> 
createServerCustomizers(Configuration conf,
+                                                                          
AvaticaServerConfiguration avaticaServerConfiguration) {
                 return expected;
             }
         });
         Configuration conf = new Configuration(false);
         conf.set(QueryServices.QUERY_SERVER_CUSTOMIZERS_ENABLED, "true");
         QueryServer queryServer = new QueryServer();
-        List<ServerCustomizer<Server>> actual = 
queryServer.createServerCustomizers(conf);
+        List<ServerCustomizer<Server>> actual = 
queryServer.createServerCustomizers(conf, avaticaServerConfiguration);
         Assert.assertEquals("Customizers are different", expected, actual);
     }
 
     @Test
     @SuppressWarnings("unchecked")
     public void testEnableCustomizers() {
+        AvaticaServerConfiguration avaticaServerConfiguration = null;
         HttpServer.Builder builder = mock(HttpServer.Builder.class);
         Configuration conf = new Configuration(false);
         conf.set(QueryServices.QUERY_SERVER_CUSTOMIZERS_ENABLED, "true");
         QueryServer queryServer = new QueryServer();
-        queryServer.enableServerCustomizersIfNecessary(builder, conf);
+        queryServer.enableServerCustomizersIfNecessary(builder, conf, 
avaticaServerConfiguration);
         verify(builder).withServerCustomizers(anyList(), any(Class.class));
     }
 }
\ No newline at end of file

Reply via email to