[ https://issues.apache.org/jira/browse/PHOENIX-6523?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17782008#comment-17782008 ]
ASF GitHub Bot commented on PHOENIX-6523: ----------------------------------------- stoty commented on code in PR #1658: URL: https://github.com/apache/phoenix/pull/1658#discussion_r1379639314 ########## phoenix-core/src/main/java/org/apache/phoenix/jdbc/ConnectionInfo.java: ########## @@ -0,0 +1,546 @@ +/* + * 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.jdbc; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.security.User; +import org.apache.hadoop.hbase.util.VersionInfo; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.util.KerberosUtil; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.query.HBaseFactoryProvider; +import org.apache.phoenix.query.QueryServices; +import org.apache.phoenix.util.PhoenixRuntime; +import org.apache.phoenix.util.ReadOnlyProps; +import org.slf4j.LoggerFactory; + +/** + * Class to encapsulate connection info for HBase + * @since 0.1.1 + */ +public abstract class ConnectionInfo { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ConnectionInfo.class); + protected static final Object KERBEROS_LOGIN_LOCK = new Object(); + protected static final char WINDOWS_SEPARATOR_CHAR = '\\'; + protected static final String REALM_EQUIVALENCY_WARNING_MSG = + "Provided principal does not contain a realm and the default realm cannot be" + + " determined. Ignoring realm equivalency check."; + protected static final String TERMINATOR = "" + PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR; + protected static final String DELIMITERS = TERMINATOR + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR; + protected static final String CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY = + "hbase.client.registry.impl"; + + protected static final boolean HAS_MASTER_REGISTRY; + protected static final boolean HAS_RPC_REGISTRY; + + static { + String version = VersionInfo.getVersion(); + if (VersionInfo.getMajorVersion(version) >= 3) { + HAS_MASTER_REGISTRY = true; + HAS_RPC_REGISTRY = true; + } else { + if (VersionInfo.compareVersion(VersionInfo.getVersion(), "2.3.0") < 0) { + HAS_MASTER_REGISTRY = false; + HAS_RPC_REGISTRY = false; + } else if (VersionInfo.compareVersion(VersionInfo.getVersion(), "2.5.0") < 0) { + HAS_MASTER_REGISTRY = true; + HAS_RPC_REGISTRY = false; + } else { + HAS_MASTER_REGISTRY = true; + HAS_RPC_REGISTRY = true; + } + } + } + + protected static SQLException getMalFormedUrlException(String url) { + return new SQLExceptionInfo.Builder(SQLExceptionCode.MALFORMED_CONNECTION_URL) + .setMessage(url).build().buildException(); + } + + protected final boolean isConnectionless; + protected final String principal; + protected final String keytab; + protected final User user; + protected final String haGroup; + + protected ConnectionInfo(boolean isConnectionless, String principal, String keytab, User user, + String haGroup) { + super(); + this.isConnectionless = isConnectionless; + this.principal = principal; + this.keytab = keytab; + this.user = user; + this.haGroup = haGroup; + } + + protected static String unescape(String escaped) { + return escaped.replaceAll("\\\\:", "="); + } + + public static ConnectionInfo createNoLogin(String url, ReadOnlyProps props, Properties info) + throws SQLException { + Configuration conf = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + return create(url, conf, props, info, true); + } + + public static ConnectionInfo create(String url, ReadOnlyProps props, Properties info) + throws SQLException { + Configuration conf = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + return create(url, conf, props, info); + } + + public static ConnectionInfo createNoLogin(String url, Configuration configuration, + ReadOnlyProps props, Properties info) throws SQLException { + return create(url, configuration, props, info, true); + } + + public static ConnectionInfo create(String url, Configuration configuration, + ReadOnlyProps props, Properties info) throws SQLException { + return create(url, configuration, props, info, false); + } + + public static ConnectionInfo create(String url, Configuration configuration, + ReadOnlyProps props, Properties info, boolean doNotLogin) throws SQLException { + // registry-independent URL preprocessing + url = url == null ? "" : url; + url = unescape(url); + + // Assume missing prefix + if (url.isEmpty()) { + url = PhoenixRuntime.JDBC_PROTOCOL; + } + if (!url.startsWith(PhoenixRuntime.JDBC_PROTOCOL)) { + url = PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + url; + } + + if (configuration == null) { + configuration = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + } + + Builder builder; + + if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL_ZK)) { + builder = new ZKConnectionInfo.Builder(url, configuration, props, info); + } else if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL_MASTER)) { + builder = new MasterConnectionInfo.Builder(url, configuration, props, info); + } else if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL_RPC)) { + builder = new RPCConnectionInfo.Builder(url, configuration, props, info); + } else if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL)) { + // The generic protocol was specified. Try to Determine the protocol from the config + if (MasterConnectionInfo.isMaster(configuration)) { + builder = new MasterConnectionInfo.Builder(url, configuration, props, info); + } else if (RPCConnectionInfo.isRPC(configuration)) { + builder = new RPCConnectionInfo.Builder(url, configuration, props, info); + } else if (ZKConnectionInfo.isZK(configuration)) { + builder = new ZKConnectionInfo.Builder(url, configuration, props, info); + } else { + // No registry class set in config. Use version-dependent default + if (VersionInfo.getMajorVersion(VersionInfo.getVersion()) >= 3) { + builder = new RPCConnectionInfo.Builder(url, configuration, props, info); + } else { + builder = new ZKConnectionInfo.Builder(url, configuration, props, info); + } + } + } else { + throw getMalFormedUrlException(url); + } Review Comment: I'm gonna do that after the patch has landed. Probably a dedicated page would be the best, then we could link to it from every place where the URLs are referred. I would also like to emphasize in the docs the best solution is just to rely the defaults in hbase-site.xml ########## phoenix-core/src/main/java/org/apache/phoenix/jdbc/ConnectionInfo.java: ########## @@ -0,0 +1,546 @@ +/* + * 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.jdbc; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.security.User; +import org.apache.hadoop.hbase.util.VersionInfo; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.util.KerberosUtil; +import org.apache.phoenix.exception.SQLExceptionCode; +import org.apache.phoenix.exception.SQLExceptionInfo; +import org.apache.phoenix.query.HBaseFactoryProvider; +import org.apache.phoenix.query.QueryServices; +import org.apache.phoenix.util.PhoenixRuntime; +import org.apache.phoenix.util.ReadOnlyProps; +import org.slf4j.LoggerFactory; + +/** + * Class to encapsulate connection info for HBase + * @since 0.1.1 + */ +public abstract class ConnectionInfo { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ConnectionInfo.class); + protected static final Object KERBEROS_LOGIN_LOCK = new Object(); + protected static final char WINDOWS_SEPARATOR_CHAR = '\\'; + protected static final String REALM_EQUIVALENCY_WARNING_MSG = + "Provided principal does not contain a realm and the default realm cannot be" + + " determined. Ignoring realm equivalency check."; + protected static final String TERMINATOR = "" + PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR; + protected static final String DELIMITERS = TERMINATOR + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR; + protected static final String CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY = + "hbase.client.registry.impl"; + + protected static final boolean HAS_MASTER_REGISTRY; + protected static final boolean HAS_RPC_REGISTRY; + + static { + String version = VersionInfo.getVersion(); + if (VersionInfo.getMajorVersion(version) >= 3) { + HAS_MASTER_REGISTRY = true; + HAS_RPC_REGISTRY = true; + } else { + if (VersionInfo.compareVersion(VersionInfo.getVersion(), "2.3.0") < 0) { + HAS_MASTER_REGISTRY = false; + HAS_RPC_REGISTRY = false; + } else if (VersionInfo.compareVersion(VersionInfo.getVersion(), "2.5.0") < 0) { + HAS_MASTER_REGISTRY = true; + HAS_RPC_REGISTRY = false; + } else { + HAS_MASTER_REGISTRY = true; + HAS_RPC_REGISTRY = true; + } + } + } + + protected static SQLException getMalFormedUrlException(String url) { + return new SQLExceptionInfo.Builder(SQLExceptionCode.MALFORMED_CONNECTION_URL) + .setMessage(url).build().buildException(); + } + + protected final boolean isConnectionless; + protected final String principal; + protected final String keytab; + protected final User user; + protected final String haGroup; + + protected ConnectionInfo(boolean isConnectionless, String principal, String keytab, User user, + String haGroup) { + super(); + this.isConnectionless = isConnectionless; + this.principal = principal; + this.keytab = keytab; + this.user = user; + this.haGroup = haGroup; + } + + protected static String unescape(String escaped) { + return escaped.replaceAll("\\\\:", "="); + } + + public static ConnectionInfo createNoLogin(String url, ReadOnlyProps props, Properties info) + throws SQLException { + Configuration conf = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + return create(url, conf, props, info, true); + } + + public static ConnectionInfo create(String url, ReadOnlyProps props, Properties info) + throws SQLException { + Configuration conf = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + return create(url, conf, props, info); + } + + public static ConnectionInfo createNoLogin(String url, Configuration configuration, + ReadOnlyProps props, Properties info) throws SQLException { + return create(url, configuration, props, info, true); + } + + public static ConnectionInfo create(String url, Configuration configuration, + ReadOnlyProps props, Properties info) throws SQLException { + return create(url, configuration, props, info, false); + } + + public static ConnectionInfo create(String url, Configuration configuration, + ReadOnlyProps props, Properties info, boolean doNotLogin) throws SQLException { + // registry-independent URL preprocessing + url = url == null ? "" : url; + url = unescape(url); + + // Assume missing prefix + if (url.isEmpty()) { + url = PhoenixRuntime.JDBC_PROTOCOL; + } + if (!url.startsWith(PhoenixRuntime.JDBC_PROTOCOL)) { + url = PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + url; + } + + if (configuration == null) { + configuration = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + } + + Builder builder; + + if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL_ZK)) { + builder = new ZKConnectionInfo.Builder(url, configuration, props, info); + } else if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL_MASTER)) { + builder = new MasterConnectionInfo.Builder(url, configuration, props, info); + } else if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL_RPC)) { + builder = new RPCConnectionInfo.Builder(url, configuration, props, info); + } else if (url.toLowerCase().startsWith(PhoenixRuntime.JDBC_PROTOCOL)) { + // The generic protocol was specified. Try to Determine the protocol from the config + if (MasterConnectionInfo.isMaster(configuration)) { + builder = new MasterConnectionInfo.Builder(url, configuration, props, info); + } else if (RPCConnectionInfo.isRPC(configuration)) { + builder = new RPCConnectionInfo.Builder(url, configuration, props, info); + } else if (ZKConnectionInfo.isZK(configuration)) { + builder = new ZKConnectionInfo.Builder(url, configuration, props, info); + } else { + // No registry class set in config. Use version-dependent default + if (VersionInfo.getMajorVersion(VersionInfo.getVersion()) >= 3) { + builder = new RPCConnectionInfo.Builder(url, configuration, props, info); + } else { + builder = new ZKConnectionInfo.Builder(url, configuration, props, info); + } + } + } else { + throw getMalFormedUrlException(url); + } Review Comment: I'm gonna do that after the patch has landed. Probably a dedicated page would be the best, then we could link to it from every place where the URLs are referred. I would also like to emphasize in the docs the best solution is just to rely on the defaults in hbase-site.xml > Support for HBase Registry Implementations through Phoenix connection URL > ------------------------------------------------------------------------- > > Key: PHOENIX-6523 > URL: https://issues.apache.org/jira/browse/PHOENIX-6523 > Project: Phoenix > Issue Type: Improvement > Components: core > Reporter: Ramie Raufdeen > Assignee: Istvan Toth > Priority: Major > > https://issues.apache.org/jira/browse/HBASE-23305 > https://issues.apache.org/jira/browse/HBASE-18095 > > HBase now supports a zookeeper-less connection strategy using a Master > Registry implementation. > > For this to work, the client simply needs to set a list of <host:port>s of > the HMaster quorum > > {code:java} > <property> > <name>hbase.masters</name> > <value>master1:16000,master2:16001,master3:16000</value> > </property> > {code} > > To support opting into this from a Phoenix connection URL, we can introduce a > "connector type". We'll leverage the *+* char of [JDBC URL > grammar|https://docs.oracle.com/cd/E17952_01/connector-j-8.0-en/connector-j-reference-jdbc-url-format.html] > to specify the connection type. Connections will start to look something > like this: > {code:java} > jdbc:phoenix+zk:hostname1,2,3...:<properties> > jdbc:phoenix+hrpc:hostname1,2,3...:<properties> > jdbc:phoenix+bigtable:hostname1,2,3...:<properties>{code} > Above are examples of opting into hrpc/zk/bigtable registry implementations > of HBase. > > If no connector is specified, the driver will default to a Zookeeper based > connection. > > > -- This message was sent by Atlassian Jira (v8.20.10#820010)