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