You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by st...@apache.org on 2019/12/20 06:08:00 UTC
[phoenix-queryserver] branch master updated: PHOENIX-5641 Decouple
phoenix-queryserver from phoenix-core
This is an automated email from the ASF dual-hosted git repository.
stoty pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix-queryserver.git
The following commit(s) were added to refs/heads/master by this push:
new 960289a PHOENIX-5641 Decouple phoenix-queryserver from phoenix-core
960289a is described below
commit 960289a6ec6afd263d0e2faaf9ac1c585ce4d587
Author: Istvan Toth <st...@stoty.hu>
AuthorDate: Thu Dec 19 08:13:54 2019 +0100
PHOENIX-5641 Decouple phoenix-queryserver from phoenix-core
---
.../service/LoadBalanceZookeeperConfImpl.java | 24 ++---
pom.xml | 112 +++++++++++----------
.../phoenix/queryserver/client/ThinClientUtil.java | 2 +-
queryserver-orchestrator/pom.xml | 5 +-
queryserver/pom.xml | 17 ++--
.../HttpParamImpersonationQueryServerIT.java | 8 +-
.../phoenix/end2end/QueryServerBasicsIT.java | 3 +-
.../end2end/SecureQueryServerPhoenixDBIT.java | 5 +-
.../phoenix/end2end/ServerCustomizersIT.java | 3 +-
.../phoenix/queryserver/QueryServerOptions.java | 110 ++++++++++++++++++++
.../phoenix/queryserver/QueryServerProperties.java | 79 +++++++++++++++
.../queryserver/server/PhoenixMetaFactoryImpl.java | 83 ++++++++++++---
.../phoenix/queryserver/server/QueryServer.java | 90 ++++++++---------
.../org/apache/phoenix/util/InstanceResolver.java | 95 +++++++++++++++++
14 files changed, 495 insertions(+), 141 deletions(-)
diff --git a/load-balancer/src/main/java/org/apache/phoenix/loadbalancer/service/LoadBalanceZookeeperConfImpl.java b/load-balancer/src/main/java/org/apache/phoenix/loadbalancer/service/LoadBalanceZookeeperConfImpl.java
index 98e2682..807295b 100644
--- a/load-balancer/src/main/java/org/apache/phoenix/loadbalancer/service/LoadBalanceZookeeperConfImpl.java
+++ b/load-balancer/src/main/java/org/apache/phoenix/loadbalancer/service/LoadBalanceZookeeperConfImpl.java
@@ -23,8 +23,8 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.net.HostAndPort;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
-import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.queryserver.QueryServerOptions;
+import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
@@ -53,30 +53,30 @@ public class LoadBalanceZookeeperConfImpl implements LoadBalanceZookeeperConf {
@Override
public String getQueryServerBasePath(){
- return configuration.get(QueryServices.PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH,
- QueryServicesOptions.DEFAULT_PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH);
+ return configuration.get(QueryServerProperties.PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH,
+ QueryServerOptions.DEFAULT_PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH);
}
@Override
public String getServiceName(){
- return configuration.get(QueryServices.PHOENIX_QUERY_SERVER_SERVICE_NAME,
- QueryServicesOptions.DEFAULT_PHOENIX_QUERY_SERVER_SERVICE_NAME);
+ return configuration.get(QueryServerProperties.PHOENIX_QUERY_SERVER_SERVICE_NAME,
+ QueryServerOptions.DEFAULT_PHOENIX_QUERY_SERVER_SERVICE_NAME);
}
@Override
public String getZkConnectString(){
- return String.format("%s:%s",configuration.get(QueryServices.ZOOKEEPER_QUORUM_ATTRIB,
- "localhost"),configuration.get(QueryServices.ZOOKEEPER_PORT_ATTRIB,"2181"));
+ return String.format("%s:%s",configuration.get(QueryServerProperties.ZOOKEEPER_QUORUM_ATTRIB,
+ "localhost"),configuration.get(QueryServerProperties.ZOOKEEPER_PORT_ATTRIB,"2181"));
}
private String getZkLbUserName(){
- return configuration.get(QueryServices.PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME,
- QueryServicesOptions.DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME);
+ return configuration.get(QueryServerProperties.PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME,
+ QueryServerOptions.DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME);
}
private String getZkLbPassword(){
- return configuration.get(QueryServices.PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD,
- QueryServicesOptions.DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD);
+ return configuration.get(QueryServerProperties.PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD,
+ QueryServerOptions.DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD);
}
@Override
diff --git a/pom.xml b/pom.xml
index 21b6aec..cd3c003 100644
--- a/pom.xml
+++ b/pom.xml
@@ -313,18 +313,6 @@
<!-- Intra-project dependencies -->
<dependency>
<groupId>org.apache.phoenix</groupId>
- <artifactId>phoenix-core</artifactId>
- <version>${phoenix.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.phoenix</groupId>
- <artifactId>phoenix-core</artifactId>
- <version>${phoenix.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.phoenix</groupId>
<artifactId>queryserver</artifactId>
<version>${project.version}</version>
</dependency>
@@ -391,35 +379,6 @@
<scope>test</scope>
</dependency>
- <!-- Required for mini-cluster since hbase built against old version of hadoop -->
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
- <version>${hadoop-two.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-client</artifactId>
- <version>${hadoop-two.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-hdfs</artifactId>
- <version>${hadoop-two.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-hdfs</artifactId>
- <version>${hadoop-two.version}</version>
- <type>test-jar</type> <!-- this does not work which is typical for maven.-->
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-minikdc</artifactId>
- <version>${hadoop-two.version}</version>
- </dependency>
-
<!-- General Dependencies -->
<dependency>
<groupId>org.apache.curator</groupId>
@@ -469,22 +428,11 @@
<version>${sqlline.version}</version>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${junit.version}</version>
- </dependency>
- <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>${mockito-all.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.api.version}</version>
@@ -499,6 +447,66 @@
<artifactId>argparse4j</artifactId>
<version>0.8.1</version>
</dependency>
+
+ <!-- Test dependencies -->
+ <dependency>
+ <groupId>org.apache.phoenix</groupId>
+ <artifactId>phoenix-core</artifactId>
+ <version>${phoenix.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.phoenix</groupId>
+ <artifactId>phoenix-core</artifactId>
+ <version>${phoenix.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>${mockito-all.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Required for mini-cluster since hbase built against old version of hadoop -->
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
+ <version>${hadoop-two.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-client</artifactId>
+ <version>${hadoop-two.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs</artifactId>
+ <version>${hadoop-two.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs</artifactId>
+ <version>${hadoop-two.version}</version>
+ <type>test-jar</type> <!-- this does not work which is typical for maven.-->
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-minikdc</artifactId>
+ <version>${hadoop-two.version}</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</dependencyManagement>
diff --git a/queryserver-client/src/main/java/org/apache/phoenix/queryserver/client/ThinClientUtil.java b/queryserver-client/src/main/java/org/apache/phoenix/queryserver/client/ThinClientUtil.java
index 59fe093..1ea64e7 100644
--- a/queryserver-client/src/main/java/org/apache/phoenix/queryserver/client/ThinClientUtil.java
+++ b/queryserver-client/src/main/java/org/apache/phoenix/queryserver/client/ThinClientUtil.java
@@ -21,7 +21,7 @@ package org.apache.phoenix.queryserver.client;
* Utilities for thin clients.
*/
public final class ThinClientUtil {
- // The default serialization is also defined in QueryServicesOptions. phoenix-queryserver-client
+ // The default serialization is also defined in QueryServerOptions. phoenix-queryserver-client
// currently doesn't depend on phoenix-core so we have to deal with the duplication.
private static final String DEFAULT_SERIALIZATION = "PROTOBUF";
diff --git a/queryserver-orchestrator/pom.xml b/queryserver-orchestrator/pom.xml
index 8efb324..12e559f 100644
--- a/queryserver-orchestrator/pom.xml
+++ b/queryserver-orchestrator/pom.xml
@@ -61,10 +61,7 @@
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
+ <scope>compile</scope>
</dependency>
</dependencies>
diff --git a/queryserver/pom.xml b/queryserver/pom.xml
index dd8f758..d68d8e8 100644
--- a/queryserver/pom.xml
+++ b/queryserver/pom.xml
@@ -143,6 +143,10 @@
</build>
<dependencies>
+ <dependency>
+ <groupId>org.apache.hbase</groupId>
+ <artifactId>hbase-common</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>queryserver-client</artifactId>
@@ -165,10 +169,6 @@
<artifactId>avatica-server</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.phoenix</groupId>
- <artifactId>phoenix-core</artifactId>
- </dependency>
- <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
@@ -178,14 +178,19 @@
</dependency>
<!-- for tests -->
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
+ <groupId>org.apache.phoenix</groupId>
+ <artifactId>phoenix-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
+ <scope>test</scope>
<classifier>tests</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/queryserver/src/it/java/org/apache/phoenix/end2end/HttpParamImpersonationQueryServerIT.java b/queryserver/src/it/java/org/apache/phoenix/end2end/HttpParamImpersonationQueryServerIT.java
index e982a1e..e92a837 100644
--- a/queryserver/src/it/java/org/apache/phoenix/end2end/HttpParamImpersonationQueryServerIT.java
+++ b/queryserver/src/it/java/org/apache/phoenix/end2end/HttpParamImpersonationQueryServerIT.java
@@ -46,6 +46,8 @@ import org.apache.hadoop.security.UserGroupInformation;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.queryserver.QueryServerOptions;
+import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.phoenix.queryserver.client.Driver;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -74,7 +76,7 @@ public class HttpParamImpersonationQueryServerIT extends AbstractKerberisedTest
// user1 is allowed to impersonate others, user2 is not
conf.set("hadoop.proxyuser.user1.groups", "*");
conf.set("hadoop.proxyuser.user1.hosts", "*");
- conf.setBoolean(QueryServices.QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR_ATTRIB, true);
+ conf.setBoolean(QueryServerProperties.QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR_ATTRIB, true);
configureAndStartQueryServer(conf, 2);
}
@@ -85,7 +87,7 @@ public class HttpParamImpersonationQueryServerIT extends AbstractKerberisedTest
final Entry<String,File> user2 = getUser(2);
// Build the JDBC URL by hand with the doAs
final String doAsUrlTemplate = Driver.CONNECT_STRING_PREFIX + "url=http://localhost:" + PQS_PORT + "?"
- + QueryServicesOptions.DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM + "=%s;authentication=SPNEGO;serialization=PROTOBUF";
+ + QueryServerOptions.DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM + "=%s;authentication=SPNEGO;serialization=PROTOBUF";
final String tableName = "POSITIVE_IMPERSONATION";
final int numRows = 5;
final UserGroupInformation serviceUgi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(SERVICE_PRINCIPAL, KEYTAB.getAbsolutePath());
@@ -118,7 +120,7 @@ public class HttpParamImpersonationQueryServerIT extends AbstractKerberisedTest
final Entry<String,File> user2 = getUser(2);
// Build the JDBC URL by hand with the doAs
final String doAsUrlTemplate = Driver.CONNECT_STRING_PREFIX + "url=http://localhost:" + PQS_PORT + "?"
- + QueryServicesOptions.DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM + "=%s;authentication=SPNEGO;serialization=PROTOBUF";
+ + QueryServerOptions.DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM + "=%s;authentication=SPNEGO;serialization=PROTOBUF";
final String tableName = "DISALLOWED_IMPERSONATION";
final int numRows = 5;
final UserGroupInformation serviceUgi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(SERVICE_PRINCIPAL, KEYTAB.getAbsolutePath());
diff --git a/queryserver/src/it/java/org/apache/phoenix/end2end/QueryServerBasicsIT.java b/queryserver/src/it/java/org/apache/phoenix/end2end/QueryServerBasicsIT.java
index ceb0a78..4ebec1b 100644
--- a/queryserver/src/it/java/org/apache/phoenix/end2end/QueryServerBasicsIT.java
+++ b/queryserver/src/it/java/org/apache/phoenix/end2end/QueryServerBasicsIT.java
@@ -43,6 +43,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.phoenix.queryserver.client.ThinClientUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -67,7 +68,7 @@ public class QueryServerBasicsIT extends BaseHBaseManagedTimeIT {
@BeforeClass
public static void beforeClass() throws Exception {
CONF = getTestClusterConfig();
- CONF.setInt(QueryServices.QUERY_SERVER_HTTP_PORT_ATTRIB, 0);
+ CONF.setInt(QueryServerProperties.QUERY_SERVER_HTTP_PORT_ATTRIB, 0);
String url = getUrl();
AVATICA_SERVER = new QueryServerThread(new String[] { url }, CONF,
QueryServerBasicsIT.class.getName());
diff --git a/queryserver/src/it/java/org/apache/phoenix/end2end/SecureQueryServerPhoenixDBIT.java b/queryserver/src/it/java/org/apache/phoenix/end2end/SecureQueryServerPhoenixDBIT.java
index 205a831..05f7f15 100644
--- a/queryserver/src/it/java/org/apache/phoenix/end2end/SecureQueryServerPhoenixDBIT.java
+++ b/queryserver/src/it/java/org/apache/phoenix/end2end/SecureQueryServerPhoenixDBIT.java
@@ -54,6 +54,7 @@ import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authentication.util.KerberosName;
import org.apache.phoenix.query.ConfigurationFactory;
import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.phoenix.queryserver.client.ThinClientUtil;
import org.apache.phoenix.queryserver.server.QueryServer;
import org.apache.phoenix.util.InstanceResolver;
@@ -234,8 +235,8 @@ public class SecureQueryServerPhoenixDBIT {
conf.set("phoenix.queryserver.http.keytab.file", KEYTAB.getAbsolutePath());
conf.set("phoenix.queryserver.kerberos.principal", PQS_PRINCIPAL + "@" + KDC.getRealm());
conf.set("phoenix.queryserver.keytab.file", KEYTAB.getAbsolutePath());
- conf.setBoolean(QueryServices.QUERY_SERVER_DISABLE_KERBEROS_LOGIN, true);
- conf.setInt(QueryServices.QUERY_SERVER_HTTP_PORT_ATTRIB, 0);
+ conf.setBoolean(QueryServerProperties.QUERY_SERVER_DISABLE_KERBEROS_LOGIN, true);
+ conf.setInt(QueryServerProperties.QUERY_SERVER_HTTP_PORT_ATTRIB, 0);
// Required so that PQS can impersonate the end-users to HBase
conf.set("hadoop.proxyuser.phoenixqs.groups", "*");
conf.set("hadoop.proxyuser.phoenixqs.hosts", "*");
diff --git a/queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java b/queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
index db08908..699000f 100644
--- a/queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
+++ b/queryserver/src/it/java/org/apache/phoenix/end2end/ServerCustomizersIT.java
@@ -28,6 +28,7 @@ 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;
+import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.phoenix.queryserver.server.ServerCustomizersFactory;
import org.apache.phoenix.util.InstanceResolver;
import org.eclipse.jetty.security.ConstraintMapping;
@@ -60,7 +61,7 @@ public class ServerCustomizersIT extends BaseHBaseManagedTimeIT {
@BeforeClass
public static void setup() throws Exception {
Configuration conf = getTestClusterConfig();
- conf.set(QueryServices.QUERY_SERVER_CUSTOMIZERS_ENABLED, "true");
+ conf.set(QueryServerProperties.QUERY_SERVER_CUSTOMIZERS_ENABLED, "true");
PQS_UTIL = new QueryServerTestUtil(conf);
PQS_UTIL.startLocalHBaseCluster(ServerCustomizersIT.class);
// Register a test jetty server customizer
diff --git a/queryserver/src/main/java/org/apache/phoenix/queryserver/QueryServerOptions.java b/queryserver/src/main/java/org/apache/phoenix/queryserver/QueryServerOptions.java
new file mode 100644
index 0000000..33f7771
--- /dev/null
+++ b/queryserver/src/main/java/org/apache/phoenix/queryserver/QueryServerOptions.java
@@ -0,0 +1,110 @@
+/*
+ * 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.phoenix.queryserver;
+
+import static org.apache.phoenix.queryserver.QueryServerProperties.PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH;
+import static org.apache.phoenix.queryserver.QueryServerProperties.PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED;
+import static org.apache.phoenix.queryserver.QueryServerProperties.PHOENIX_QUERY_SERVER_SERVICE_NAME;
+import static org.apache.phoenix.queryserver.QueryServerProperties.PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD;
+import static org.apache.phoenix.queryserver.QueryServerProperties.PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+
+public class QueryServerOptions {
+
+ // QueryServer defaults -- ensure ThinClientUtil is also updated since
+ // phoenix-queryserver-client
+ // doesn't depend on phoenix-core.
+ public static final String DEFAULT_QUERY_SERVER_SERIALIZATION = "PROTOBUF";
+ public static final int DEFAULT_QUERY_SERVER_HTTP_PORT = 8765;
+ public static final long DEFAULT_QUERY_SERVER_UGI_CACHE_MAX_SIZE = 1000L;
+ public static final int DEFAULT_QUERY_SERVER_UGI_CACHE_INITIAL_SIZE = 100;
+ 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;
+
+ @SuppressWarnings("serial")
+ public static final Set<String> DEFAULT_QUERY_SERVER_SKIP_WORDS = new HashSet<String>() {
+ {
+ add("secret");
+ add("passwd");
+ add("password");
+ add("credential");
+ }
+ };
+
+ // Loadbalancer defaults
+ public static final boolean DEFAULT_PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED = false;
+ public static final String DEFAULT_PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH = "/phoenix";
+ public static final String DEFAULT_PHOENIX_QUERY_SERVER_SERVICE_NAME = "queryserver";
+ public static final String DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME = "phoenix";
+ public static final String DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD = "phoenix";
+
+ // Common defaults
+ public static final String DEFAULT_EXTRA_JDBC_ARGUMENTS = "";
+
+ private final Configuration config;
+
+ private QueryServerOptions(Configuration config) {
+ this.config = config;
+ }
+
+ public static QueryServerOptions withDefaults() {
+ Configuration config = HBaseConfiguration.create();
+ QueryServerOptions options =
+ new QueryServerOptions(config)
+ .setIfUnset(PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED,
+ DEFAULT_PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED)
+ .setIfUnset(PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH,
+ DEFAULT_PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH)
+ .setIfUnset(PHOENIX_QUERY_SERVER_SERVICE_NAME,
+ DEFAULT_PHOENIX_QUERY_SERVER_SERVICE_NAME)
+ .setIfUnset(PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME,
+ DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME)
+ .setIfUnset(PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD,
+ DEFAULT_PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD);
+
+ return options;
+ }
+
+ public Configuration getConfiguration() {
+ return config;
+ }
+
+ private QueryServerOptions setIfUnset(String name, int value) {
+ config.setIfUnset(name, Integer.toString(value));
+ return this;
+ }
+
+ private QueryServerOptions setIfUnset(String name, boolean value) {
+ config.setIfUnset(name, Boolean.toString(value));
+ return this;
+ }
+
+ private QueryServerOptions setIfUnset(String name, long value) {
+ config.setIfUnset(name, Long.toString(value));
+ return this;
+ }
+
+ private QueryServerOptions setIfUnset(String name, String value) {
+ config.setIfUnset(name, value);
+ return this;
+ }
+
+}
diff --git a/queryserver/src/main/java/org/apache/phoenix/queryserver/QueryServerProperties.java b/queryserver/src/main/java/org/apache/phoenix/queryserver/QueryServerProperties.java
new file mode 100644
index 0000000..aa081f6
--- /dev/null
+++ b/queryserver/src/main/java/org/apache/phoenix/queryserver/QueryServerProperties.java
@@ -0,0 +1,79 @@
+/*
+ * 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.phoenix.queryserver;
+
+public class QueryServerProperties {
+
+ // queryserver configuration keys
+ public static final String QUERY_SERVER_SERIALIZATION_ATTRIB =
+ "phoenix.queryserver.serialization";
+ public static final String QUERY_SERVER_META_FACTORY_ATTRIB =
+ "phoenix.queryserver.metafactory.class";
+ public static final String QUERY_SERVER_HTTP_PORT_ATTRIB = "phoenix.queryserver.http.port";
+ public static final String QUERY_SERVER_ENV_LOGGING_ATTRIB =
+ "phoenix.queryserver.envvars.logging.disabled";
+ public static final String QUERY_SERVER_ENV_LOGGING_SKIPWORDS_ATTRIB =
+ "phoenix.queryserver.envvars.logging.skipwords";
+ public static final String QUERY_SERVER_KEYTAB_FILENAME_ATTRIB =
+ "phoenix.queryserver.keytab.file";
+ public static final String QUERY_SERVER_HTTP_KEYTAB_FILENAME_ATTRIB =
+ "phoenix.queryserver.http.keytab.file";
+ public static final String QUERY_SERVER_KERBEROS_PRINCIPAL_ATTRIB =
+ "phoenix.queryserver.kerberos.principal";
+ public static final String QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB_LEGACY =
+ "phoenix.queryserver.kerberos.http.principal";
+ public static final String QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB =
+ "phoenix.queryserver.http.kerberos.principal";
+ public static final String QUERY_SERVER_DNS_NAMESERVER_ATTRIB =
+ "phoenix.queryserver.dns.nameserver";
+ public static final String QUERY_SERVER_DNS_INTERFACE_ATTRIB =
+ "phoenix.queryserver.dns.interface";
+ public static final String QUERY_SERVER_HBASE_SECURITY_CONF_ATTRIB =
+ "hbase.security.authentication";
+ public static final String QUERY_SERVER_UGI_CACHE_MAX_SIZE =
+ "phoenix.queryserver.ugi.cache.max.size";
+ public static final String QUERY_SERVER_UGI_CACHE_INITIAL_SIZE =
+ "phoenix.queryserver.ugi.cache.initial.size";
+ public static final String QUERY_SERVER_UGI_CACHE_CONCURRENCY =
+ "phoenix.queryserver.ugi.cache.concurrency";
+ 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_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";
+
+ // keys for load balancer
+ public static final String PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED =
+ "phoenix.queryserver.loadbalancer.enabled";
+ public static final String PHOENIX_QUERY_SERVER_CLUSTER_BASE_PATH =
+ "phoenix.queryserver.base.path";
+ public static final String PHOENIX_QUERY_SERVER_SERVICE_NAME =
+ "phoenix.queryserver.service.name";
+ public static final String PHOENIX_QUERY_SERVER_ZK_ACL_USERNAME =
+ "phoenix.queryserver.zookeeper.acl.username";
+ public static final String PHOENIX_QUERY_SERVER_ZK_ACL_PASSWORD =
+ "phoenix.queryserver.zookeeper.acl.password";
+
+ // keys that are also used by phoenix-core
+ public static final String ZOOKEEPER_QUORUM_ATTRIB = "hbase.zookeeper.quorum";
+ public static final String ZOOKEEPER_PORT_ATTRIB = "hbase.zookeeper.property.clientPort";
+ public static final String EXTRA_JDBC_ARGUMENTS_ATTRIB = "phoenix.jdbc.extra.arguments";
+
+}
diff --git a/queryserver/src/main/java/org/apache/phoenix/queryserver/server/PhoenixMetaFactoryImpl.java b/queryserver/src/main/java/org/apache/phoenix/queryserver/server/PhoenixMetaFactoryImpl.java
index c74d2c9..88c577f 100644
--- a/queryserver/src/main/java/org/apache/phoenix/queryserver/server/PhoenixMetaFactoryImpl.java
+++ b/queryserver/src/main/java/org/apache/phoenix/queryserver/server/PhoenixMetaFactoryImpl.java
@@ -17,31 +17,28 @@
*/
package org.apache.phoenix.queryserver.server;
-import com.google.common.base.Preconditions;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
import org.apache.calcite.avatica.Meta;
import org.apache.calcite.avatica.jdbc.JdbcMeta;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HConstants;
-import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
-import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.queryserver.QueryServerOptions;
+import org.apache.phoenix.queryserver.QueryServerProperties;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
+import com.google.common.base.Preconditions;
/**
* Bridge between Phoenix and Avatica.
*/
public class PhoenixMetaFactoryImpl extends Configured implements PhoenixMetaFactory {
+
// invoked via reflection
public PhoenixMetaFactoryImpl() {
super(HBaseConfiguration.create());
@@ -60,7 +57,7 @@ public class PhoenixMetaFactoryImpl extends Configured implements PhoenixMetaFac
try {
final String url;
if (args.size() == 0) {
- url = QueryUtil.getConnectionUrl(info, conf);
+ url = getConnectionUrl(info, conf);
} else if (args.size() == 1) {
url = args.get(0);
} else {
@@ -73,4 +70,64 @@ public class PhoenixMetaFactoryImpl extends Configured implements PhoenixMetaFac
throw new RuntimeException(e);
}
}
+
+ //The following are copied and adopted from the phoenix-core QueryUtil and PhoenixEmbedded classes
+
+ public final static String JDBC_PROTOCOL = "jdbc:phoenix";
+ public final static char JDBC_PROTOCOL_SEPARATOR = ':';
+ public final static char JDBC_PROTOCOL_TERMINATOR = ';';
+
+ /**
+ * @return connection url using the various properties set in props and conf.
+ */
+ public String getConnectionUrl(Properties props, Configuration conf)
+ throws ClassNotFoundException, SQLException {
+ // read the hbase properties from the configuration
+ int port = getInt(HConstants.ZOOKEEPER_CLIENT_PORT, HConstants.DEFAULT_ZOOKEPER_CLIENT_PORT, props, conf);
+ // Build the ZK quorum server string with "server:clientport" list, separated by ','
+ final String server = getString(HConstants.ZOOKEEPER_QUORUM, HConstants.LOCALHOST, props, conf);
+ String znodeParent = getString(HConstants.ZOOKEEPER_ZNODE_PARENT, HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT, props, conf);
+ String url = getUrl(server, port, znodeParent);
+ if (url.endsWith(JDBC_PROTOCOL_TERMINATOR + "")) {
+ url = url.substring(0, url.length() - 1);
+ }
+ // Mainly for testing to tack on the test=true part to ensure driver is found on server
+ String defaultExtraArgs =
+ conf != null
+ ? conf.get(QueryServerProperties.EXTRA_JDBC_ARGUMENTS_ATTRIB,
+ QueryServerOptions.DEFAULT_EXTRA_JDBC_ARGUMENTS)
+ : QueryServerOptions.DEFAULT_EXTRA_JDBC_ARGUMENTS;
+ // If props doesn't have a default for extra args then use the extra args in conf as default
+ String extraArgs =
+ props.getProperty(QueryServerProperties.EXTRA_JDBC_ARGUMENTS_ATTRIB, defaultExtraArgs);
+ if (extraArgs.length() > 0) {
+ url += JDBC_PROTOCOL_TERMINATOR + extraArgs + JDBC_PROTOCOL_TERMINATOR;
+ } else {
+ url += JDBC_PROTOCOL_TERMINATOR;
+ }
+ return url;
+ }
+
+ private int getInt(String key, int defaultValue, Properties props, Configuration conf) {
+ if (conf == null) {
+ Preconditions.checkNotNull(props);
+ return Integer.parseInt(props.getProperty(key, String.valueOf(defaultValue)));
+ }
+ return conf.getInt(key, defaultValue);
+ }
+
+ private String getString(String key, String defaultValue, Properties props, Configuration conf) {
+ if (conf == null) {
+ Preconditions.checkNotNull(props);
+ return props.getProperty(key, defaultValue);
+ }
+ return conf.get(key, defaultValue);
+ }
+
+ private static String getUrl(String zookeeperQuorum, Integer port, String rootNode) {
+ return JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR
+ + zookeeperQuorum + (port == null ? "" : ":" + port)
+ + (rootNode == null ? "" : ":" + rootNode)
+ + JDBC_PROTOCOL_TERMINATOR;
+ }
}
diff --git a/queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java b/queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
index 5f39362..8486a79 100644
--- a/queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
+++ b/queryserver/src/main/java/org/apache/phoenix/queryserver/server/QueryServer.java
@@ -49,9 +49,9 @@ import org.apache.hadoop.security.authorize.AuthorizationException;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
-import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.query.QueryServicesOptions;
import org.apache.phoenix.loadbalancer.service.LoadBalanceZookeeperConf;
+import org.apache.phoenix.queryserver.QueryServerOptions;
+import org.apache.phoenix.queryserver.QueryServerProperties;
import org.apache.phoenix.queryserver.register.Registry;
import org.apache.phoenix.util.InstanceResolver;
import org.eclipse.jetty.server.Server;
@@ -77,8 +77,6 @@ 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.
*/
@@ -116,12 +114,12 @@ public final class QueryServer extends Configured implements Tool, Runnable {
*/
public static void logProcessInfo(Configuration conf) {
// log environment variables unless asked not to
- if (conf == null || !conf.getBoolean(QueryServices.QUERY_SERVER_ENV_LOGGING_ATTRIB, false)) {
+ if (conf == null || !conf.getBoolean(QueryServerProperties.QUERY_SERVER_ENV_LOGGING_ATTRIB, false)) {
Set<String> skipWords = new HashSet<String>(
- QueryServicesOptions.DEFAULT_QUERY_SERVER_SKIP_WORDS);
+ QueryServerOptions.DEFAULT_QUERY_SERVER_SKIP_WORDS);
if (conf != null) {
String[] confSkipWords = conf.getStrings(
- QueryServices.QUERY_SERVER_ENV_LOGGING_SKIPWORDS_ATTRIB);
+ QueryServerProperties.QUERY_SERVER_ENV_LOGGING_SKIPWORDS_ATTRIB);
if (confSkipWords != null) {
skipWords.addAll(Arrays.asList(confSkipWords));
}
@@ -192,38 +190,38 @@ public final class QueryServer extends Configured implements Tool, Runnable {
@Override
public int run(String[] args) throws Exception {
logProcessInfo(getConf());
- final boolean loadBalancerEnabled = getConf().getBoolean(QueryServices.PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED,
- QueryServicesOptions.DEFAULT_PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED);
+ final boolean loadBalancerEnabled = getConf().getBoolean(QueryServerProperties.PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED,
+ QueryServerOptions.DEFAULT_PHOENIX_QUERY_SERVER_LOADBALANCER_ENABLED);
try {
final boolean isKerberos = "kerberos".equalsIgnoreCase(getConf().get(
- QueryServices.QUERY_SERVER_HBASE_SECURITY_CONF_ATTRIB));
- final boolean disableSpnego = getConf().getBoolean(QueryServices.QUERY_SERVER_SPNEGO_AUTH_DISABLED_ATTRIB,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_SPNEGO_AUTH_DISABLED);
+ QueryServerProperties.QUERY_SERVER_HBASE_SECURITY_CONF_ATTRIB));
+ final boolean disableSpnego = getConf().getBoolean(QueryServerProperties.QUERY_SERVER_SPNEGO_AUTH_DISABLED_ATTRIB,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_SPNEGO_AUTH_DISABLED);
String hostname;
- final boolean disableLogin = getConf().getBoolean(QueryServices.QUERY_SERVER_DISABLE_KERBEROS_LOGIN,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_DISABLE_KERBEROS_LOGIN);
+ final boolean disableLogin = getConf().getBoolean(QueryServerProperties.QUERY_SERVER_DISABLE_KERBEROS_LOGIN,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_DISABLE_KERBEROS_LOGIN);
// handle secure cluster credentials
if (isKerberos && !disableLogin) {
hostname = Strings.domainNamePointerToHostName(DNS.getDefaultHost(
- getConf().get(QueryServices.QUERY_SERVER_DNS_INTERFACE_ATTRIB, "default"),
- getConf().get(QueryServices.QUERY_SERVER_DNS_NAMESERVER_ATTRIB, "default")));
+ getConf().get(QueryServerProperties.QUERY_SERVER_DNS_INTERFACE_ATTRIB, "default"),
+ getConf().get(QueryServerProperties.QUERY_SERVER_DNS_NAMESERVER_ATTRIB, "default")));
if (LOG.isDebugEnabled()) {
LOG.debug("Login to " + hostname + " using " + getConf().get(
- QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB)
+ QueryServerProperties.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB)
+ " and principal " + getConf().get(
- QueryServices.QUERY_SERVER_KERBEROS_PRINCIPAL_ATTRIB) + ".");
+ QueryServerProperties.QUERY_SERVER_KERBEROS_PRINCIPAL_ATTRIB) + ".");
}
- SecurityUtil.login(getConf(), QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB,
- QueryServices.QUERY_SERVER_KERBEROS_PRINCIPAL_ATTRIB, hostname);
+ SecurityUtil.login(getConf(), QueryServerProperties.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB,
+ QueryServerProperties.QUERY_SERVER_KERBEROS_PRINCIPAL_ATTRIB, hostname);
LOG.info("Login successful.");
} else {
hostname = InetAddress.getLocalHost().getHostName();
LOG.info(" Kerberos is off and hostname is : "+hostname);
}
- int port = getConf().getInt(QueryServices.QUERY_SERVER_HTTP_PORT_ATTRIB,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_HTTP_PORT);
+ int port = getConf().getInt(QueryServerProperties.QUERY_SERVER_HTTP_PORT_ATTRIB,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_HTTP_PORT);
LOG.debug("Listening on port " + port);
// Update proxyuser configuration for impersonation
@@ -241,8 +239,8 @@ public final class QueryServer extends Configured implements Tool, Runnable {
// 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)) {
+ if (getConf().getBoolean(QueryServerProperties.QUERY_SERVER_CUSTOM_AUTH_ENABLED,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_CUSTOM_AUTH_ENABLED)) {
avaticaServerConfiguration = enableCustomAuth(builder, getConf(), ugi);
} else {
if (isKerberos) {
@@ -287,17 +285,17 @@ public final class QueryServer extends Configured implements Tool, Runnable {
@VisibleForTesting
void configureSpnegoAuthentication(HttpServer.Builder builder, UserGroupInformation ugi) throws IOException {
- String keytabPath = getConf().get(QueryServices.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB);
+ String keytabPath = getConf().get(QueryServerProperties.QUERY_SERVER_KEYTAB_FILENAME_ATTRIB);
File keytab = new File(keytabPath);
String httpKeytabPath =
- getConf().get(QueryServices.QUERY_SERVER_HTTP_KEYTAB_FILENAME_ATTRIB, null);
+ getConf().get(QueryServerProperties.QUERY_SERVER_HTTP_KEYTAB_FILENAME_ATTRIB, null);
String httpPrincipal = getSpnegoPrincipal(getConf());
File httpKeytab = null;
if (null != httpKeytabPath) {
httpKeytab = new File(httpKeytabPath);
}
- String realmsString = getConf().get(QueryServices.QUERY_SERVER_KERBEROS_ALLOWED_REALMS, null);
+ String realmsString = getConf().get(QueryServerProperties.QUERY_SERVER_KERBEROS_ALLOWED_REALMS, null);
String[] additionalAllowedRealms = null;
if (null != realmsString) {
additionalAllowedRealms = StringUtils.split(realmsString, ',');
@@ -317,16 +315,16 @@ public final class QueryServer extends Configured implements Tool, Runnable {
*/
String getSpnegoPrincipal(Configuration conf) throws IOException {
String httpPrincipal = conf.get(
- QueryServices.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB, null);
+ QueryServerProperties.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB, null);
// Backwards compat for a configuration key change
if (httpPrincipal == null) {
httpPrincipal = conf.get(
- QueryServices.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB_LEGACY, null);
+ QueryServerProperties.QUERY_SERVER_KERBEROS_HTTP_PRINCIPAL_ATTRIB_LEGACY, null);
}
String hostname = Strings.domainNamePointerToHostName(DNS.getDefaultHost(
- conf.get(QueryServices.QUERY_SERVER_DNS_INTERFACE_ATTRIB, "default"),
- conf.get(QueryServices.QUERY_SERVER_DNS_NAMESERVER_ATTRIB, "default")));
+ conf.get(QueryServerProperties.QUERY_SERVER_DNS_INTERFACE_ATTRIB, "default"),
+ conf.get(QueryServerProperties.QUERY_SERVER_DNS_NAMESERVER_ATTRIB, "default")));
return SecurityUtil.getServerPrincipal(httpPrincipal, hostname);
}
@@ -348,7 +346,7 @@ public final class QueryServer extends Configured implements Tool, Runnable {
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,
+ QueryServerProperties.QUERY_SERVER_META_FACTORY_ATTRIB, PhoenixMetaFactoryImpl.class,
PhoenixMetaFactory.class);
PhoenixMetaFactory factory =
factoryClass.getDeclaredConstructor(Configuration.class).newInstance(getConf());
@@ -424,8 +422,8 @@ public final class QueryServer extends Configured implements Tool, Runnable {
* @return The Serialization method
*/
Driver.Serialization getSerialization(Configuration conf) {
- String serializationName = conf.get(QueryServices.QUERY_SERVER_SERIALIZATION_ATTRIB,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_SERIALIZATION);
+ String serializationName = conf.get(QueryServerProperties.QUERY_SERVER_SERIALIZATION_ATTRIB,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_SERIALIZATION);
Driver.Serialization serialization;
// Otherwise, use what was provided in the configuration
@@ -450,8 +448,8 @@ public final class QueryServer extends Configured implements Tool, Runnable {
// add remoteUserExtractor to builder if enabled
@VisibleForTesting
public void setRemoteUserExtractorIfNecessary(HttpServer.Builder builder, Configuration conf) {
- if (conf.getBoolean(QueryServices.QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR_ATTRIB,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR)) {
+ if (conf.getBoolean(QueryServerProperties.QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR_ATTRIB,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_WITH_REMOTEUSEREXTRACTOR)) {
builder.withRemoteUserExtractor(createRemoteUserExtractor(conf));
}
}
@@ -459,8 +457,8 @@ public final class QueryServer extends Configured implements Tool, Runnable {
@VisibleForTesting
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)) {
+ if (conf.getBoolean(QueryServerProperties.QUERY_SERVER_CUSTOMIZERS_ENABLED,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_CUSTOMIZERS_ENABLED)) {
builder.withServerCustomizers(createServerCustomizers(conf, avaticaServerConfiguration), Server.class);
}
}
@@ -513,8 +511,8 @@ public final class QueryServer extends Configured implements Tool, Runnable {
public PhoenixRemoteUserExtractor(Configuration conf) {
this.requestRemoteUserExtractor = new HttpRequestRemoteUserExtractor();
- this.userExtractParam = conf.get(QueryServices.QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM);
+ this.userExtractParam = conf.get(QueryServerProperties.QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_REMOTEUSEREXTRACTOR_PARAM);
this.paramRemoteUserExtractor = new HttpQueryStringParameterRemoteUserExtractor(userExtractParam);
}
@@ -553,12 +551,12 @@ public final class QueryServer extends Configured implements Tool, Runnable {
public PhoenixDoAsCallback(UserGroupInformation serverUgi, Configuration conf) {
this.serverUgi = Objects.requireNonNull(serverUgi);
this.ugiCache = CacheBuilder.newBuilder()
- .initialCapacity(conf.getInt(QueryServices.QUERY_SERVER_UGI_CACHE_INITIAL_SIZE,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_UGI_CACHE_INITIAL_SIZE))
- .concurrencyLevel(conf.getInt(QueryServices.QUERY_SERVER_UGI_CACHE_CONCURRENCY,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_UGI_CACHE_CONCURRENCY))
- .maximumSize(conf.getLong(QueryServices.QUERY_SERVER_UGI_CACHE_MAX_SIZE,
- QueryServicesOptions.DEFAULT_QUERY_SERVER_UGI_CACHE_MAX_SIZE))
+ .initialCapacity(conf.getInt(QueryServerProperties.QUERY_SERVER_UGI_CACHE_INITIAL_SIZE,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_UGI_CACHE_INITIAL_SIZE))
+ .concurrencyLevel(conf.getInt(QueryServerProperties.QUERY_SERVER_UGI_CACHE_CONCURRENCY,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_UGI_CACHE_CONCURRENCY))
+ .maximumSize(conf.getLong(QueryServerProperties.QUERY_SERVER_UGI_CACHE_MAX_SIZE,
+ QueryServerOptions.DEFAULT_QUERY_SERVER_UGI_CACHE_MAX_SIZE))
.build(new UgiCacheLoader(this.serverUgi));
}
diff --git a/queryserver/src/main/java/org/apache/phoenix/util/InstanceResolver.java b/queryserver/src/main/java/org/apache/phoenix/util/InstanceResolver.java
new file mode 100644
index 0000000..4757e46
--- /dev/null
+++ b/queryserver/src/main/java/org/apache/phoenix/util/InstanceResolver.java
@@ -0,0 +1,95 @@
+/*
+ * 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.phoenix.util;
+
+import org.apache.commons.collections.IteratorUtils;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Resolves object instances registered using the JDK 6+ {@link java.util.ServiceLoader}.
+ *
+ *
+ * @since 2.0
+ */
+public class InstanceResolver {
+ private static final ConcurrentHashMap<Class, Object> RESOLVED_SINGLETONS = new ConcurrentHashMap<Class, Object>();
+
+ private InstanceResolver() {/* not allowed */}
+
+ /**
+ * Resolves an instance of the specified class if it has not already been resolved.
+ * @param clazz The type of instance to resolve
+ * @param defaultInstance The instance to use if a custom instance has not been registered
+ * @return The resolved instance or the default instance provided.
+ * {@code null} if an instance is not registered and a default is not provided.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getSingleton(Class<T> clazz, T defaultInstance) {
+ Object obj = RESOLVED_SINGLETONS.get(clazz);
+ if(obj != null) {
+ return (T)obj;
+ }
+ if (defaultInstance != null && !clazz.isInstance(defaultInstance)) throw new IllegalArgumentException("defaultInstance is not of type " + clazz.getName());
+ final Object o = resolveSingleton(clazz, defaultInstance);
+ obj = RESOLVED_SINGLETONS.putIfAbsent(clazz, o);
+ if(obj == null) {
+ obj = o;
+ }
+ return (T)obj;
+ }
+
+ /**
+ * Resolves all instances of a specified class and add it to the list of default implementations
+ * @param clazz Type of the instance to resolve
+ * @param defaultInstances {@link List} of instances that match the type clazz
+ * @param <T> Type of class passed
+ * @return {@link List} of instance of the specified class. Newly found instances will be added
+ * to the existing contents of defaultInstances
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> List get(Class<T> clazz, List<T> defaultInstances) {
+ Iterator<T> iterator = ServiceLoader.load(clazz).iterator();
+ if (defaultInstances != null) {
+ defaultInstances.addAll(IteratorUtils.toList(iterator));
+ } else {
+ defaultInstances = IteratorUtils.toList(iterator);
+ }
+
+ return defaultInstances;
+ }
+
+ private synchronized static <T> T resolveSingleton(Class<T> clazz, T defaultInstance) {
+ ServiceLoader<T> loader = ServiceLoader.load(clazz);
+ // returns the first registered instance found
+ for (T singleton : loader) {
+ return singleton;
+ }
+ return defaultInstance;
+ }
+
+ @VisibleForTesting
+ public static void clearSingletons() {
+ RESOLVED_SINGLETONS.clear();
+ }
+}