You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/07/28 01:50:52 UTC
git commit: PHOENIX-1125 SQLException when connection string is of
form jdbc:phoenix:localhost:1234:userName
Repository: phoenix
Updated Branches:
refs/heads/3.0 2df0594ff -> af2f98123
PHOENIX-1125 SQLException when connection string is of form jdbc:phoenix:localhost:1234:userName
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/af2f9812
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/af2f9812
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/af2f9812
Branch: refs/heads/3.0
Commit: af2f981239c5b0d8387d31ec0a291fced2a3edc9
Parents: 2df0594
Author: James Taylor <jt...@salesforce.com>
Authored: Sun Jul 27 16:54:00 2014 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Sun Jul 27 16:54:00 2014 -0700
----------------------------------------------------------------------
.../apache/phoenix/jdbc/PhoenixConnection.java | 22 +-
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 4 +-
.../org/apache/phoenix/jdbc/PhoenixDriver.java | 4 +-
.../phoenix/jdbc/PhoenixEmbeddedDriver.java | 160 +++++++-------
.../phoenix/query/BaseQueryServicesImpl.java | 4 +-
.../phoenix/query/ConnectionQueryServices.java | 2 +
.../query/ConnectionQueryServicesImpl.java | 7 +
.../query/ConnectionlessQueryServicesImpl.java | 10 +-
.../query/DelegateConnectionQueryServices.java | 5 +
.../apache/phoenix/query/QueryServicesImpl.java | 6 +-
.../phoenix/query/QueryServicesOptions.java | 4 +-
.../org/apache/phoenix/util/ReadOnlyProps.java | 21 +-
.../phoenix/jdbc/PhoenixEmbeddedDriverTest.java | 37 ++--
.../apache/phoenix/jdbc/PhoenixTestDriver.java | 6 +-
.../java/org/apache/phoenix/query/BaseTest.java | 4 +-
.../phoenix/query/ConnectionlessTest.java | 218 +++++++++++++++++++
.../phoenix/query/ConnectionlessUpsertTest.java | 182 ----------------
.../phoenix/query/QueryServicesTestImpl.java | 10 +-
pom.xml | 4 +-
19 files changed, 404 insertions(+), 306 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 4209c0f..e712819 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -41,7 +41,12 @@ import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.text.Format;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
@@ -132,7 +137,6 @@ public class PhoenixConnection implements Connection, org.apache.phoenix.jdbc.Jd
this.isAutoCommit = connection.isAutoCommit;
}
- @SuppressWarnings("unchecked")
public PhoenixConnection(ConnectionQueryServices services, String url, Properties info, PMetaData metaData) throws SQLException {
this.url = url;
// Copy so client cannot change
@@ -149,11 +153,17 @@ public class PhoenixConnection implements Connection, org.apache.phoenix.jdbc.Jd
// TODO: we could avoid creating another wrapper if the only property
// specified was for the tenant ID
Map<String, String> existingProps = services.getProps().asMap();
- Map<String, String> tmpAugmentedProps = Maps.newHashMapWithExpectedSize(existingProps.size() + info.size());
+ final Map<String, String> tmpAugmentedProps = Maps.newHashMapWithExpectedSize(existingProps.size() + info.size());
tmpAugmentedProps.putAll(existingProps);
- tmpAugmentedProps.putAll((Map)this.info);
- final ReadOnlyProps augmentedProps = new ReadOnlyProps(tmpAugmentedProps);
- this.services = new DelegateConnectionQueryServices(services) {
+ boolean needsDelegate = false;
+ for (Entry<Object, Object> entry : this.info.entrySet()) {
+ String key = entry.getKey().toString();
+ String value = entry.getValue().toString();
+ String oldValue = tmpAugmentedProps.put(key, value);
+ needsDelegate |= !Objects.equal(oldValue, value);
+ }
+ this.services = !needsDelegate ? services : new DelegateConnectionQueryServices(services) {
+ final ReadOnlyProps augmentedProps = new ReadOnlyProps(tmpAugmentedProps);
@Override
public ReadOnlyProps getProps() {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index 27a53e4..de799ce 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -58,6 +58,7 @@ import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.KeyValueUtil;
import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.StringUtil;
import com.google.common.collect.Lists;
@@ -912,7 +913,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData, org.apache.pho
@Override
public String getUserName() throws SQLException {
- return ""; // FIXME: what should we return here?
+ String userName = connection.getQueryServices().getUserName();
+ return userName == null ? StringUtil.EMPTY_STRING : userName;
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java
index b305d8f..ac8f330 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java
@@ -94,7 +94,7 @@ public final class PhoenixDriver extends PhoenixEmbeddedDriver {
synchronized(this) {
result = services;
if(result == null) {
- services = result = new QueryServicesImpl();
+ services = result = new QueryServicesImpl(getDefaultProps());
}
}
}
@@ -117,7 +117,7 @@ public final class PhoenixDriver extends PhoenixEmbeddedDriver {
ConnectionQueryServices connectionQueryServices = connectionQueryServicesMap.get(normalizedConnInfo);
if (connectionQueryServices == null) {
if (normalizedConnInfo.isConnectionless()) {
- connectionQueryServices = new ConnectionlessQueryServicesImpl(services);
+ connectionQueryServices = new ConnectionlessQueryServicesImpl(services, normalizedConnInfo);
} else {
connectionQueryServices = new ConnectionQueryServicesImpl(services, normalizedConnInfo);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
index 10c24b8..ca27075 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
@@ -35,6 +35,7 @@ import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.query.ConnectionQueryServices;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SQLCloseable;
@@ -64,7 +65,18 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
public final static String MINOR_VERSION_PROP = "DriverMinorVersion";
public final static String DRIVER_NAME_PROP = "DriverName";
+ private final ReadOnlyProps defaultProps;
+
PhoenixEmbeddedDriver() {
+ Map<String, String> defaultPropsMap = Maps.newHashMapWithExpectedSize(3);
+ defaultPropsMap.put(MAJOR_VERSION_PROP, Integer.toString(getMajorVersion()));
+ defaultPropsMap.put(MINOR_VERSION_PROP, Integer.toString(getMinorVersion()));
+ defaultPropsMap.put(DRIVER_NAME_PROP, getDriverName());
+ defaultProps = new ReadOnlyProps(defaultPropsMap);
+ }
+
+ protected ReadOnlyProps getDefaultProps() {
+ return defaultProps;
}
private String getDriverName() {
@@ -109,11 +121,10 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
return null;
}
- ConnectionQueryServices connectionServices = getConnectionQueryServices(url, info);
- info.setProperty(MAJOR_VERSION_PROP, Integer.toString(getMajorVersion()));
- info.setProperty(MINOR_VERSION_PROP, Integer.toString(getMinorVersion()));
- info.setProperty(DRIVER_NAME_PROP, getDriverName());
- PhoenixConnection connection = connectionServices.connect(url, info);
+ Properties augmentedInfo = PropertiesUtil.deepCopy(info);
+ augmentedInfo.putAll(defaultProps.asMap());
+ ConnectionQueryServices connectionServices = getConnectionQueryServices(url, augmentedInfo);
+ PhoenixConnection connection = connectionServices.connect(url, augmentedInfo);
return connection;
}
@@ -165,72 +176,79 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
* @since 0.1.1
*/
public static class ConnectionInfo {
+ private static SQLException getMalFormedUrlException(String url) {
+ return new SQLExceptionInfo.Builder(SQLExceptionCode.MALFORMED_CONNECTION_URL)
+ .setMessage(url).build().buildException();
+ }
+
+ /**
+ * Detect url with quorum:1,quorum:2 as HBase does not handle different port numbers
+ * for different quorum hostnames.
+ * @param portStr
+ * @return
+ */
+ private static boolean isMultiPortUrl(String portStr) {
+ int commaIndex = portStr.indexOf(',');
+ if (commaIndex > 0) {
+ try {
+ Integer.parseInt(portStr.substring(0, commaIndex));
+ return true;
+ } catch (NumberFormatException otherE) {
+ }
+ }
+ return false;
+ }
+
protected static ConnectionInfo create(String url) throws SQLException {
StringTokenizer tokenizer = new StringTokenizer(url == null ? "" : url.substring(PhoenixRuntime.JDBC_PROTOCOL.length()),DELIMITERS, true);
- int i = 0;
- boolean isMalformedUrl = false;
+ int nTokens = 0;
String[] tokens = new String[5];
String token = null;
- while (tokenizer.hasMoreTokens() && !(token=tokenizer.nextToken()).equals(TERMINATOR) && tokenizer.hasMoreTokens() && i < tokens.length) {
+ while (tokenizer.hasMoreTokens() && !(token=tokenizer.nextToken()).equals(TERMINATOR) && tokenizer.hasMoreTokens() && nTokens < tokens.length) {
token = tokenizer.nextToken();
// This would mean we have an empty string for a token which is illegal
if (DELIMITERS.contains(token)) {
- isMalformedUrl = true;
- break;
+ throw getMalFormedUrlException(url);
}
- tokens[i++] = token;
+ tokens[nTokens++] = token;
}
+ if (tokenizer.hasMoreTokens() && !TERMINATOR.equals(token)) {
+ throw getMalFormedUrlException(url);
+ }
+ String quorum = null;
Integer port = null;
- if (!isMalformedUrl) {
- if (tokenizer.hasMoreTokens() && !TERMINATOR.equals(token)) {
- isMalformedUrl = true;
- } else if (i > 1) {
+ String rootNode = null;
+ String principal = null;
+ String keytabFile = null;
+ int tokenIndex = 0;
+ if (nTokens > tokenIndex) {
+ quorum = tokens[tokenIndex++]; // Found quorum
+ if (nTokens > tokenIndex) {
try {
- port = Integer.parseInt(tokens[1]);
- isMalformedUrl = port < 0;
- if(i == 4){
- if(!tokens[2].endsWith(".keytab")){
- isMalformedUrl = true;
- }
- tokens[4] = tokens[3];
- tokens[3] = tokens[2];
- tokens[2] = null;
+ port = Integer.parseInt(tokens[tokenIndex]);
+ if (port < 0) {
+ throw getMalFormedUrlException(url);
}
- } catch (NumberFormatException e) {
- // If we have 3 tokens, then the second one must be a port.
- // If we only have 2 tokens, the second one might be the root node:
- // Assume that is the case if we get a NumberFormatException
- if (!tokens[1].startsWith("/")) {
- isMalformedUrl = true;
+ tokenIndex++; // Found port
+ } catch (NumberFormatException e) { // No port information
+ if (isMultiPortUrl(tokens[tokenIndex])) {
+ throw getMalFormedUrlException(url);
}
- if (i == 2) {
- tokens[4] = null;
- tokens[3] = null;
- tokens[2] = tokens[1];
- tokens[1] = null;
- } else if (i == 3) {
- tokens[4] = tokens[2];
- tokens[3] = tokens[1];
- tokens[2] = null;
- tokens[1] = null;
- } else if (i == 4) {
- tokens[4] = tokens[3];
- tokens[3] = tokens[2];
- tokens[2] = tokens[1];
- tokens[1] = null;
- } else if (i == 5) {
- tokens[4] = tokens[3];
- tokens[3] = tokens[2];
- tokens[2] = tokens[1];
+ }
+ if (nTokens > tokenIndex) {
+ if (tokens[tokenIndex].startsWith("/")) {
+ rootNode = tokens[tokenIndex++]; // Found rootNode
+ }
+ if (nTokens > tokenIndex) {
+ principal = tokens[tokenIndex++]; // Found principal
+ if (nTokens > tokenIndex) {
+ keytabFile = tokens[tokenIndex++]; // Found keytabFile
+ }
}
}
}
}
- if (isMalformedUrl) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.MALFORMED_CONNECTION_URL)
- .setMessage(url).build().buildException();
- }
- return new ConnectionInfo(tokens[0],port,tokens[2], tokens[3], tokens[4]);
+ return new ConnectionInfo(quorum,port,rootNode, principal, keytabFile);
}
public ConnectionInfo normalize(ReadOnlyProps props) throws SQLException {
@@ -273,19 +291,17 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
throw new SQLExceptionInfo.Builder(SQLExceptionCode.MALFORMED_CONNECTION_URL)
.setMessage("Root node may not be specified when using the connectionless url \"" + this.toString() + "\"").build().buildException();
}
+ if(principal == null){
+ if (!isConnectionless) {
+ principal = props.get(QueryServices.HBASE_CLIENT_PRINCIPAL);
+ }
+ }
if(keytab == null){
if (!isConnectionless) {
keytab = props.get(QueryServices.HBASE_CLIENT_KEYTAB);
}
}
- if(principal == null){
- if (!isConnectionless) {
- principal = props.get(QueryServices.HBASE_CLIENT_PRINCIPAL);
- }
- }
- if (keytab == null || keytab.equals("")) return new ConnectionInfo(zookeeperQuorum,
- port, rootNode);
- else return new ConnectionInfo(zookeeperQuorum, port, rootNode, keytab, principal);
+ return new ConnectionInfo(zookeeperQuorum, port, rootNode, principal, keytab);
}
private final Integer port;
@@ -296,7 +312,7 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
private final String keytab;
// used for testing
- ConnectionInfo(String zookeeperQuorum, Integer port, String rootNode, String keytab, String principal) {
+ ConnectionInfo(String zookeeperQuorum, Integer port, String rootNode, String principal, String keytab) {
this.zookeeperQuorum = zookeeperQuorum;
this.port = port;
this.rootNode = rootNode;
@@ -321,11 +337,9 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
if (getRootNode() != null) {
connectionProps.put(QueryServices.ZOOKEEPER_ROOT_NODE_ATTRIB, getRootNode());
}
- if (getKeytab() != null) {
- connectionProps.put(QueryServices.HBASE_CLIENT_KEYTAB, getKeytab());
- }
- if (getPrincipal() != null) {
+ if (getPrincipal() != null && getKeytab() != null) {
connectionProps.put(QueryServices.HBASE_CLIENT_PRINCIPAL, getPrincipal());
+ connectionProps.put(QueryServices.HBASE_CLIENT_KEYTAB, getKeytab());
}
return connectionProps.isEmpty() ? ReadOnlyProps.EMPTY_PROPS : new ReadOnlyProps(
connectionProps.entrySet().iterator());
@@ -362,8 +376,8 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
result = prime * result + ((zookeeperQuorum == null) ? 0 : zookeeperQuorum.hashCode());
result = prime * result + ((port == null) ? 0 : port.hashCode());
result = prime * result + ((rootNode == null) ? 0 : rootNode.hashCode());
+ result = prime * result + ((principal == null) ? 0 : principal.hashCode());
result = prime * result + ((keytab == null) ? 0 : keytab.hashCode());
- result = prime * result + ((principal == null) ? 0 : keytab.hashCode());
return result;
}
@@ -382,12 +396,12 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
if (rootNode == null) {
if (other.rootNode != null) return false;
} else if (!rootNode.equals(other.rootNode)) return false;
- if (keytab == null) {
- if (other.keytab != null) return false;
- } else if (!keytab.equals(other.keytab)) return false;
if (principal == null) {
if (other.principal != null) return false;
} else if (!principal.equals(other.principal)) return false;
+ if (keytab == null) {
+ if (other.keytab != null) return false;
+ } else if (!keytab.equals(other.keytab)) return false;
return true;
}
@@ -395,8 +409,8 @@ public abstract class PhoenixEmbeddedDriver implements Driver, org.apache.phoeni
public String toString() {
return zookeeperQuorum + (port == null ? "" : ":" + port)
+ (rootNode == null ? "" : ":" + rootNode)
- + (keytab == null ? "" : ":" + keytab)
- + (principal == null ? "" : ":" + principal);
+ + (principal == null ? "" : ":" + principal)
+ + (keytab == null ? "" : ":" + keytab);
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java
index 222ea14..f116695 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java
@@ -40,7 +40,7 @@ public abstract class BaseQueryServicesImpl implements QueryServices {
private final ReadOnlyProps props;
private final QueryOptimizer queryOptimizer;
- public BaseQueryServicesImpl(QueryServicesOptions options) {
+ public BaseQueryServicesImpl(ReadOnlyProps defaultProps, QueryServicesOptions options) {
this.executor = JobManager.createThreadPoolExec(
options.getKeepAliveMs(),
options.getThreadPoolSize(),
@@ -48,7 +48,7 @@ public abstract class BaseQueryServicesImpl implements QueryServices {
this.memoryManager = new GlobalMemoryManager(
Runtime.getRuntime().maxMemory() * options.getMaxMemoryPerc() / 100,
options.getMaxMemoryWaitMs());
- this.props = options.getProps();
+ this.props = options.getProps(defaultProps);
this.queryOptimizer = new QueryOptimizer(this);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
index f085464..fd44d6b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
@@ -103,4 +103,6 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
public enum Feature {REVERSE_SCAN};
public boolean supportsFeature(Feature feature);
+
+ public String getUserName();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 3ad7ecc..b13ced2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -126,6 +126,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
// Copy of config.getProps(), but read-only to prevent synchronization that we
// don't need.
private final ReadOnlyProps props;
+ private final String userName;
private final ConcurrentHashMap<ImmutableBytesWritable,ConnectionQueryServices> childServices;
private final StatsManager statsManager;
// Cache the latest meta data here for future connections
@@ -168,6 +169,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
// on the server side during testing.
this.config = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(config);
this.props = new ReadOnlyProps(this.config.iterator());
+ this.userName = connectionInfo.getPrincipal();
this.latestMetaData = newEmptyMetaData();
// TODO: should we track connection wide memory usage or just org-wide usage?
// If connection-wide, create a MemoryManager here, otherwise just use the one from the delegate
@@ -1749,4 +1751,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
return false;
}
+ @Override
+ public String getUserName() {
+ return userName;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
index a48f811..1c1bba7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
@@ -46,6 +46,7 @@ import org.apache.phoenix.hbase.index.util.GenericKeyValueBuilder;
import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.ConnectionInfo;
import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PIndexState;
@@ -85,12 +86,14 @@ import com.google.common.collect.Maps;
public class ConnectionlessQueryServicesImpl extends DelegateQueryServices implements ConnectionQueryServices {
private PMetaData metaData;
private final Map<SequenceKey, SequenceInfo> sequenceMap = Maps.newHashMap();
+ private final String userName;
private KeyValueBuilder kvBuilder;
private volatile boolean initialized;
private volatile SQLException initializationException;
- public ConnectionlessQueryServicesImpl(QueryServices queryServices) {
+ public ConnectionlessQueryServicesImpl(QueryServices queryServices, ConnectionInfo connInfo) {
super(queryServices);
+ userName = connInfo.getPrincipal();
metaData = newEmptyMetaData();
// Use KeyValueBuilder that builds real KeyValues, as our test utils require this
this.kvBuilder = GenericKeyValueBuilder.INSTANCE;
@@ -407,4 +410,9 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
public boolean supportsFeature(Feature feature) {
return false;
}
+
+ @Override
+ public String getUserName() {
+ return userName;
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
index 4fa7993..3c119de 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
@@ -226,4 +226,9 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
public boolean supportsFeature(Feature feature) {
return getDelegate().supportsFeature(feature);
}
+
+ @Override
+ public String getUserName() {
+ return getDelegate().getUserName();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesImpl.java
index beddc46..564da60 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesImpl.java
@@ -17,6 +17,8 @@
*/
package org.apache.phoenix.query;
+import org.apache.phoenix.util.ReadOnlyProps;
+
@@ -30,7 +32,7 @@ package org.apache.phoenix.query;
*/
public final class QueryServicesImpl extends BaseQueryServicesImpl {
- public QueryServicesImpl() {
- super(QueryServicesOptions.withDefaults());
+ public QueryServicesImpl(ReadOnlyProps defaultProps) {
+ super(defaultProps, QueryServicesOptions.withDefaults());
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
----------------------------------------------------------------------
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 b4db032..07106a6 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
@@ -130,14 +130,14 @@ public class QueryServicesOptions {
this.config = config;
}
- public ReadOnlyProps getProps() {
+ public ReadOnlyProps getProps(ReadOnlyProps defaultProps) {
// Ensure that HBase RPC time out value is at least as large as our thread time out for query.
int threadTimeOutMS = config.getInt(THREAD_TIMEOUT_MS_ATTRIB, DEFAULT_THREAD_TIMEOUT_MS);
int hbaseRPCTimeOut = config.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
if (threadTimeOutMS > hbaseRPCTimeOut) {
config.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, threadTimeOutMS);
}
- return new ReadOnlyProps(config.iterator());
+ return new ReadOnlyProps(defaultProps, config.iterator());
}
public QueryServicesOptions setAll(ReadOnlyProps props) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/main/java/org/apache/phoenix/util/ReadOnlyProps.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ReadOnlyProps.java b/phoenix-core/src/main/java/org/apache/phoenix/util/ReadOnlyProps.java
index 19bc5f3..fe039d3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/ReadOnlyProps.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ReadOnlyProps.java
@@ -18,12 +18,15 @@
package org.apache.phoenix.util;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.google.common.collect.*;
+import com.google.common.collect.ImmutableMap;
/**
*
@@ -34,11 +37,11 @@ import com.google.common.collect.*;
* @since 1.2.2
*/
public class ReadOnlyProps implements Iterable<Entry<String, String>> {
- public static final ReadOnlyProps EMPTY_PROPS = new ReadOnlyProps(Iterators.<Entry<String, String>>emptyIterator());
+ public static final ReadOnlyProps EMPTY_PROPS = new ReadOnlyProps();
private final Map<String, String> props;
- public ReadOnlyProps(Iterator<Entry<String, String>> iterator) {
- Map<String, String> map = Maps.newHashMap();
+ public ReadOnlyProps(ReadOnlyProps defaultProps, Iterator<Entry<String, String>> iterator) {
+ Map<String, String> map = new HashMap<String,String>(defaultProps.asMap());
while (iterator.hasNext()) {
Entry<String,String> entry = iterator.next();
map.put(entry.getKey(), entry.getValue());
@@ -46,6 +49,14 @@ public class ReadOnlyProps implements Iterable<Entry<String, String>> {
this.props = ImmutableMap.copyOf(map);
}
+ public ReadOnlyProps(Iterator<Entry<String, String>> iterator) {
+ this(EMPTY_PROPS, iterator);
+ }
+
+ private ReadOnlyProps() {
+ this.props = Collections.emptyMap();
+ }
+
public ReadOnlyProps(Map<String, String> props) {
this.props = ImmutableMap.copyOf(props);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriverTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriverTest.java b/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriverTest.java
index a9b09e5..79f9ec6 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriverTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriverTest.java
@@ -18,14 +18,17 @@
package org.apache.phoenix.jdbc;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
-import java.sql.*;
-
-import org.junit.Test;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.ConnectionInfo;
+import org.junit.Test;
public class PhoenixEmbeddedDriverTest {
@Test
@@ -47,10 +50,12 @@ public class PhoenixEmbeddedDriverTest {
"jdbc:phoenix:v1,v2,v3:/hbase;test=true",
"jdbc:phoenix:v1,v2,v3:123:/hbase",
"jdbc:phoenix:v1,v2,v3:123:/hbase;test=false",
- "jdbc:phoenix:v1,v2,v3:123:/hbase:/user.keytab:user/principal;test=false",
- "jdbc:phoenix:v1,v2,v3:123:/user.keytab:user/principal;test=false",
- "jdbc:phoenix:v1,v2,v3:/user.keytab:user/principal;test=false",
- "jdbc:phoenix:v1,v2,v3:/hbase:/user.keytab:user/principal;test=false"
+ "jdbc:phoenix:v1,v2,v3:123:/hbase:user/principal:/user.keytab;test=false",
+ "jdbc:phoenix:v1,v2,v3:123:user/principal:/user.keytab;test=false",
+ "jdbc:phoenix:v1,v2,v3:user/principal:/user.keytab;test=false",
+ "jdbc:phoenix:v1,v2,v3:/hbase:user/principal:/user.keytab;test=false",
+ "jdbc:phoenix:v1,v2,v3:LongRunningQueries;test=false",
+ "jdbc:phoenix:v1,v2,v3:345:LongRunningQueries;test=false",
};
ConnectionInfo[] infos = new ConnectionInfo[] {
new ConnectionInfo(null,null,null),
@@ -69,10 +74,12 @@ public class PhoenixEmbeddedDriverTest {
new ConnectionInfo("v1,v2,v3",null,"/hbase"),
new ConnectionInfo("v1,v2,v3",123,"/hbase"),
new ConnectionInfo("v1,v2,v3",123,"/hbase"),
- new ConnectionInfo("v1,v2,v3",123,"/hbase", "/user.keytab","user/principal" ),
- new ConnectionInfo("v1,v2,v3",123, null, "/user.keytab","user/principal" ),
- new ConnectionInfo("v1,v2,v3", null, null, "/user.keytab","user/principal" ),
- new ConnectionInfo("v1,v2,v3",null,"/hbase", "/user.keytab","user/principal" )
+ new ConnectionInfo("v1,v2,v3",123,"/hbase","user/principal", "/user.keytab" ),
+ new ConnectionInfo("v1,v2,v3",123, null,"user/principal", "/user.keytab" ),
+ new ConnectionInfo("v1,v2,v3", null, null,"user/principal", "/user.keytab" ),
+ new ConnectionInfo("v1,v2,v3",null,"/hbase","user/principal", "/user.keytab" ),
+ new ConnectionInfo("v1,v2,v3",null,null,"LongRunningQueries", null ),
+ new ConnectionInfo("v1,v2,v3",345,null,"LongRunningQueries", null ),
};
assertEquals(urls.length,infos.length);
for (int i = 0; i < urls.length; i++) {
@@ -89,18 +96,12 @@ public class PhoenixEmbeddedDriverTest {
String[] urls = new String[] {
"jdbc:phoenix::",
"jdbc:phoenix:;",
- "jdbc:phoenix:localhost:abc:/hbase",
- "jdbc:phoenix:localhost:abc:/hbase;foo=bar",
- "jdbc:phoenix:localhost:123:/hbase:blah",
- "jdbc:phoenix:localhost:123:/hbase:blah;foo=bas",
"jdbc:phoenix:v1:1,v2:2,v3:3",
"jdbc:phoenix:v1:1,v2:2,v3:3;test=true",
"jdbc:phoenix:v1,v2,v3:-1:/hbase;test=true",
"jdbc:phoenix:v1,v2,v3:-1",
- "jdbc:phoenix:v1,v2,v3:123a:/hbase;test=true",
"jdbc:phoenix:v1,v2,v3:123::/hbase",
"jdbc:phoenix:v1,v2,v3:123::/hbase;test=false",
- "jdbc:phoenix:v1,v2,v3:123:/hbase:user;test=false"
};
for (String url : urls) {
try {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixTestDriver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixTestDriver.java b/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixTestDriver.java
index 1184fdf..2423344 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixTestDriver.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixTestDriver.java
@@ -56,13 +56,13 @@ public class PhoenixTestDriver extends PhoenixEmbeddedDriver {
public PhoenixTestDriver() {
this.overrideProps = ReadOnlyProps.EMPTY_PROPS;
- queryServices = new QueryServicesTestImpl();
+ queryServices = new QueryServicesTestImpl(getDefaultProps());
}
// For tests to override the default configuration
public PhoenixTestDriver(ReadOnlyProps props) {
overrideProps = props;
- queryServices = new QueryServicesTestImpl(overrideProps);
+ queryServices = new QueryServicesTestImpl(getDefaultProps(),overrideProps);
}
@Override
@@ -84,7 +84,7 @@ public class PhoenixTestDriver extends PhoenixEmbeddedDriver {
if (connectionQueryServices != null) { return connectionQueryServices; }
ConnectionInfo connInfo = ConnectionInfo.create(url);
if (connInfo.isConnectionless()) {
- connectionQueryServices = new ConnectionlessQueryServicesImpl(queryServices);
+ connectionQueryServices = new ConnectionlessQueryServicesImpl(queryServices, connInfo);
} else {
connectionQueryServices = new ConnectionQueryServicesTestImpl(queryServices, connInfo);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index 0336d02..c4a59fb 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -513,8 +513,8 @@ public abstract class BaseTest {
private static void setDefaultTestConfig(Configuration conf) {
ConfigUtil.setReplicationConfigIfAbsent(conf);
- QueryServicesOptions options = QueryServicesTestImpl.getDefaultTestServicesOptions();
- for (Entry<String,String> entry : options.getProps()) {
+ QueryServices services = new PhoenixTestDriver().getQueryServices();
+ for (Entry<String,String> entry : services.getProps()) {
conf.set(entry.getKey(), entry.getValue());
}
//no point doing sanity checks when running tests.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
new file mode 100644
index 0000000..4a58540
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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.query;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixDriver;
+import org.apache.phoenix.schema.PDataType;
+import org.apache.phoenix.schema.SaltingUtil;
+import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.StringUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class ConnectionlessTest {
+ private static final int saltBuckets = 200;
+ private static final String orgId = "00D300000000XHP";
+ private static final String keyPrefix1 = "111";
+ private static final String keyPrefix2 = "112";
+ private static final String entityHistoryId1 = "123456789012";
+ private static final String entityHistoryId2 = "987654321098";
+ private static final String name1 = "Eli";
+ private static final String name2 = "Simon";
+ private static final Date now = new Date(System.currentTimeMillis());
+ private static final byte[] unsaltedRowKey1 = ByteUtil.concat(
+ PDataType.CHAR.toBytes(orgId),PDataType.CHAR.toBytes(keyPrefix1),PDataType.CHAR.toBytes(entityHistoryId1));
+ private static final byte[] unsaltedRowKey2 = ByteUtil.concat(
+ PDataType.CHAR.toBytes(orgId),PDataType.CHAR.toBytes(keyPrefix2),PDataType.CHAR.toBytes(entityHistoryId2));
+ private static final byte[] saltedRowKey1 = ByteUtil.concat(
+ new byte[] {SaltingUtil.getSaltingByte(unsaltedRowKey1, 0, unsaltedRowKey1.length, saltBuckets)},
+ unsaltedRowKey1);
+ private static final byte[] saltedRowKey2 = ByteUtil.concat(
+ new byte[] {SaltingUtil.getSaltingByte(unsaltedRowKey2, 0, unsaltedRowKey2.length, saltBuckets)},
+ unsaltedRowKey2);
+
+ private static String getUrl() {
+ return PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + PhoenixRuntime.CONNECTIONLESS;
+ }
+
+ @BeforeClass
+ public static void verifyDriverRegistered() throws SQLException {
+ assertTrue(DriverManager.getDriver(getUrl()) == PhoenixDriver.INSTANCE);
+ }
+
+ @Test
+ public void testConnectionlessUpsert() throws Exception {
+ testConnectionlessUpsert(null);
+ }
+
+ @Test
+ public void testSaltedConnectionlessUpsert() throws Exception {
+ testConnectionlessUpsert(saltBuckets);
+ }
+
+ private void testConnectionlessUpsert(Integer saltBuckets) throws Exception {
+ String dmlStmt = "create table core.entity_history(\n" +
+ " organization_id char(15) not null, \n" +
+ " key_prefix char(3) not null,\n" +
+ " entity_history_id char(12) not null,\n" +
+ " created_by varchar,\n" +
+ " created_date date\n" +
+ " CONSTRAINT pk PRIMARY KEY (organization_id, key_prefix, entity_history_id) ) " +
+ (saltBuckets == null ? "" : (PhoenixDatabaseMetaData.SALT_BUCKETS + "=" + saltBuckets));
+ Properties props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ PreparedStatement statement = conn.prepareStatement(dmlStmt);
+ statement.execute();
+
+ String upsertStmt = "upsert into core.entity_history(organization_id,key_prefix,entity_history_id, created_by, created_date)\n" +
+ "values(?,?,?,?,?)";
+ statement = conn.prepareStatement(upsertStmt);
+ statement.setString(1, orgId);
+ statement.setString(2, keyPrefix2);
+ statement.setString(3, entityHistoryId2);
+ statement.setString(4, name2);
+ statement.setDate(5,now);
+ statement.execute();
+ statement.setString(1, orgId);
+ statement.setString(2, keyPrefix1);
+ statement.setString(3, entityHistoryId1);
+ statement.setString(4, name1);
+ statement.setDate(5,now);
+ statement.execute();
+
+ Iterator<Pair<byte[],List<KeyValue>>> dataIterator = PhoenixRuntime.getUncommittedDataIterator(conn);
+ Iterator<KeyValue> iterator = dataIterator.next().getSecond().iterator();
+
+ byte[] expectedRowKey1 = saltBuckets == null ? unsaltedRowKey1 : saltedRowKey1;
+ byte[] expectedRowKey2 = saltBuckets == null ? unsaltedRowKey2 : saltedRowKey2;
+ if (Bytes.compareTo(expectedRowKey1, expectedRowKey2) < 0) {
+ assertRow1(iterator, expectedRowKey1);
+ assertRow2(iterator, expectedRowKey2);
+ } else {
+ assertRow2(iterator, expectedRowKey2);
+ assertRow1(iterator, expectedRowKey1);
+ }
+
+ assertFalse(iterator.hasNext());
+ assertFalse(dataIterator.hasNext());
+ conn.rollback(); // to clear the list of mutations for the next
+ }
+
+ private static void assertRow1(Iterator<KeyValue> iterator, byte[] expectedRowKey1) {
+ KeyValue kv;
+ assertTrue(iterator.hasNext());
+ kv = iterator.next();
+ assertArrayEquals(expectedRowKey1, kv.getRow());
+ assertEquals(name1, PDataType.VARCHAR.toObject(kv.getValue()));
+ assertTrue(iterator.hasNext());
+ kv = iterator.next();
+ assertArrayEquals(expectedRowKey1, kv.getRow());
+ assertEquals(now, PDataType.DATE.toObject(kv.getValue()));
+ assertTrue(iterator.hasNext());
+ kv = iterator.next();
+ assertArrayEquals(expectedRowKey1, kv.getRow());
+ assertNull(PDataType.VARCHAR.toObject(kv.getValue()));
+ }
+
+ private static void assertRow2(Iterator<KeyValue> iterator, byte[] expectedRowKey2) {
+ KeyValue kv;
+ assertTrue(iterator.hasNext());
+ kv = iterator.next();
+ assertArrayEquals(expectedRowKey2, kv.getRow());
+ assertEquals(name2, PDataType.VARCHAR.toObject(kv.getValue()));
+ assertTrue(iterator.hasNext());
+ kv = iterator.next();
+ assertArrayEquals(expectedRowKey2, kv.getRow());
+ assertEquals(now, PDataType.DATE.toObject(kv.getValue()));
+ assertTrue(iterator.hasNext());
+ kv = iterator.next();
+ assertArrayEquals(expectedRowKey2, kv.getRow());
+ assertNull(PDataType.VARCHAR.toObject(kv.getValue()));
+ }
+
+ @Test
+ public void testNoConnectionInfo() throws Exception {
+ try {
+ DriverManager.getConnection(PhoenixRuntime.JDBC_PROTOCOL);
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.MALFORMED_CONNECTION_URL.getSQLState(),e.getSQLState());
+ }
+ }
+
+ @Test
+ public void testMultipleConnectionQueryServices() throws Exception {
+ String url1 = getUrl();
+ String url2 = url1 + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + "LongRunningQueries";
+ Connection conn1 = DriverManager.getConnection(url1);
+ try {
+ assertEquals(StringUtil.EMPTY_STRING, conn1.getMetaData().getUserName());
+ Connection conn2 = DriverManager.getConnection(url2);
+ try {
+ assertEquals("LongRunningQueries", conn2.getMetaData().getUserName());
+ ConnectionQueryServices cqs1 = conn1.unwrap(PhoenixConnection.class).getQueryServices();
+ ConnectionQueryServices cqs2 = conn2.unwrap(PhoenixConnection.class).getQueryServices();
+ assertTrue(cqs1 != cqs2);
+ Connection conn3 = DriverManager.getConnection(url1);
+ try {
+ ConnectionQueryServices cqs3 = conn3.unwrap(PhoenixConnection.class).getQueryServices();
+ assertTrue(cqs1 == cqs3);
+ Connection conn4 = DriverManager.getConnection(url2);
+ try {
+ ConnectionQueryServices cqs4 = conn4.unwrap(PhoenixConnection.class).getQueryServices();
+ assertTrue(cqs2 == cqs4);
+ } finally {
+ conn4.close();
+ }
+ } finally {
+ conn3.close();
+ }
+ } finally {
+ conn2.close();
+ }
+ } finally {
+ conn1.close();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessUpsertTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessUpsertTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessUpsertTest.java
deleted file mode 100644
index bcc3897..0000000
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessUpsertTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.query;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.sql.Connection;
-import java.sql.Date;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.Pair;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import org.apache.phoenix.exception.SQLExceptionCode;
-import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
-import org.apache.phoenix.jdbc.PhoenixDriver;
-import org.apache.phoenix.schema.PDataType;
-import org.apache.phoenix.schema.SaltingUtil;
-import org.apache.phoenix.util.ByteUtil;
-import org.apache.phoenix.util.PhoenixRuntime;
-
-
-public class ConnectionlessUpsertTest {
- private static final int saltBuckets = 200;
- private static final String orgId = "00D300000000XHP";
- private static final String keyPrefix1 = "111";
- private static final String keyPrefix2 = "112";
- private static final String entityHistoryId1 = "123456789012";
- private static final String entityHistoryId2 = "987654321098";
- private static final String name1 = "Eli";
- private static final String name2 = "Simon";
- private static final Date now = new Date(System.currentTimeMillis());
- private static final byte[] unsaltedRowKey1 = ByteUtil.concat(
- PDataType.CHAR.toBytes(orgId),PDataType.CHAR.toBytes(keyPrefix1),PDataType.CHAR.toBytes(entityHistoryId1));
- private static final byte[] unsaltedRowKey2 = ByteUtil.concat(
- PDataType.CHAR.toBytes(orgId),PDataType.CHAR.toBytes(keyPrefix2),PDataType.CHAR.toBytes(entityHistoryId2));
- private static final byte[] saltedRowKey1 = ByteUtil.concat(
- new byte[] {SaltingUtil.getSaltingByte(unsaltedRowKey1, 0, unsaltedRowKey1.length, saltBuckets)},
- unsaltedRowKey1);
- private static final byte[] saltedRowKey2 = ByteUtil.concat(
- new byte[] {SaltingUtil.getSaltingByte(unsaltedRowKey2, 0, unsaltedRowKey2.length, saltBuckets)},
- unsaltedRowKey2);
-
- private static String getUrl() {
- return PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + PhoenixRuntime.CONNECTIONLESS;
- }
-
- @BeforeClass
- public static void verifyDriverRegistered() throws SQLException {
- assertTrue(DriverManager.getDriver(getUrl()) == PhoenixDriver.INSTANCE);
- }
-
- @Test
- public void testConnectionlessUpsert() throws Exception {
- testConnectionlessUpsert(null);
- }
-
- @Test
- public void testSaltedConnectionlessUpsert() throws Exception {
- testConnectionlessUpsert(saltBuckets);
- }
-
- public void testConnectionlessUpsert(Integer saltBuckets) throws Exception {
- String dmlStmt = "create table core.entity_history(\n" +
- " organization_id char(15) not null, \n" +
- " key_prefix char(3) not null,\n" +
- " entity_history_id char(12) not null,\n" +
- " created_by varchar,\n" +
- " created_date date\n" +
- " CONSTRAINT pk PRIMARY KEY (organization_id, key_prefix, entity_history_id) ) " +
- (saltBuckets == null ? "" : (PhoenixDatabaseMetaData.SALT_BUCKETS + "=" + saltBuckets));
- Properties props = new Properties();
- Connection conn = DriverManager.getConnection(getUrl(), props);
- PreparedStatement statement = conn.prepareStatement(dmlStmt);
- statement.execute();
-
- String upsertStmt = "upsert into core.entity_history(organization_id,key_prefix,entity_history_id, created_by, created_date)\n" +
- "values(?,?,?,?,?)";
- statement = conn.prepareStatement(upsertStmt);
- statement.setString(1, orgId);
- statement.setString(2, keyPrefix2);
- statement.setString(3, entityHistoryId2);
- statement.setString(4, name2);
- statement.setDate(5,now);
- statement.execute();
- statement.setString(1, orgId);
- statement.setString(2, keyPrefix1);
- statement.setString(3, entityHistoryId1);
- statement.setString(4, name1);
- statement.setDate(5,now);
- statement.execute();
-
- Iterator<Pair<byte[],List<KeyValue>>> dataIterator = PhoenixRuntime.getUncommittedDataIterator(conn);
- Iterator<KeyValue> iterator = dataIterator.next().getSecond().iterator();
-
- byte[] expectedRowKey1 = saltBuckets == null ? unsaltedRowKey1 : saltedRowKey1;
- byte[] expectedRowKey2 = saltBuckets == null ? unsaltedRowKey2 : saltedRowKey2;
- if (Bytes.compareTo(expectedRowKey1, expectedRowKey2) < 0) {
- assertRow1(iterator, expectedRowKey1);
- assertRow2(iterator, expectedRowKey2);
- } else {
- assertRow2(iterator, expectedRowKey2);
- assertRow1(iterator, expectedRowKey1);
- }
-
- assertFalse(iterator.hasNext());
- assertFalse(dataIterator.hasNext());
- conn.rollback(); // to clear the list of mutations for the next
- }
-
- private static void assertRow1(Iterator<KeyValue> iterator, byte[] expectedRowKey1) {
- KeyValue kv;
- assertTrue(iterator.hasNext());
- kv = iterator.next();
- assertArrayEquals(expectedRowKey1, kv.getRow());
- assertEquals(name1, PDataType.VARCHAR.toObject(kv.getValue()));
- assertTrue(iterator.hasNext());
- kv = iterator.next();
- assertArrayEquals(expectedRowKey1, kv.getRow());
- assertEquals(now, PDataType.DATE.toObject(kv.getValue()));
- assertTrue(iterator.hasNext());
- kv = iterator.next();
- assertArrayEquals(expectedRowKey1, kv.getRow());
- assertNull(PDataType.VARCHAR.toObject(kv.getValue()));
- }
-
- private static void assertRow2(Iterator<KeyValue> iterator, byte[] expectedRowKey2) {
- KeyValue kv;
- assertTrue(iterator.hasNext());
- kv = iterator.next();
- assertArrayEquals(expectedRowKey2, kv.getRow());
- assertEquals(name2, PDataType.VARCHAR.toObject(kv.getValue()));
- assertTrue(iterator.hasNext());
- kv = iterator.next();
- assertArrayEquals(expectedRowKey2, kv.getRow());
- assertEquals(now, PDataType.DATE.toObject(kv.getValue()));
- assertTrue(iterator.hasNext());
- kv = iterator.next();
- assertArrayEquals(expectedRowKey2, kv.getRow());
- assertNull(PDataType.VARCHAR.toObject(kv.getValue()));
- }
-
- @Test
- public void testNoConnectionInfo() throws Exception {
- try {
- DriverManager.getConnection(PhoenixRuntime.JDBC_PROTOCOL);
- fail();
- } catch (SQLException e) {
- assertEquals(SQLExceptionCode.MALFORMED_CONNECTION_URL.getSQLState(),e.getSQLState());
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/phoenix-core/src/test/java/org/apache/phoenix/query/QueryServicesTestImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/QueryServicesTestImpl.java b/phoenix-core/src/test/java/org/apache/phoenix/query/QueryServicesTestImpl.java
index 72e7aef..e125755 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/QueryServicesTestImpl.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/QueryServicesTestImpl.java
@@ -53,11 +53,11 @@ public final class QueryServicesTestImpl extends BaseQueryServicesImpl {
public static final long DEFAULT_MAX_SERVER_METADATA_CACHE_SIZE = 1024L*1024L*4L; // 4 Mb
public static final long DEFAULT_MAX_CLIENT_METADATA_CACHE_SIZE = 1024L*1024L*2L; // 2 Mb
- public QueryServicesTestImpl() {
- this(ReadOnlyProps.EMPTY_PROPS);
+ public QueryServicesTestImpl(ReadOnlyProps defaultProps) {
+ this(defaultProps, ReadOnlyProps.EMPTY_PROPS);
}
- public static QueryServicesOptions getDefaultTestServicesOptions() {
+ private static QueryServicesOptions getDefaultServicesOptions() {
return withDefaults()
.setThreadPoolSize(DEFAULT_THREAD_POOL_SIZE)
.setQueueSize(DEFAULT_QUEUE_SIZE)
@@ -81,7 +81,7 @@ public final class QueryServicesTestImpl extends BaseQueryServicesImpl {
.setMaxServerMetaDataCacheSize(DEFAULT_MAX_SERVER_METADATA_CACHE_SIZE);
}
- public QueryServicesTestImpl(ReadOnlyProps overrideProps) {
- super(getDefaultTestServicesOptions().setAll(overrideProps));
+ public QueryServicesTestImpl(ReadOnlyProps defaultProps, ReadOnlyProps overrideProps) {
+ super(defaultProps, getDefaultServicesOptions().setAll(overrideProps));
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/af2f9812/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2fe91f5..a57a3ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,8 +112,8 @@
<maven.rat.version>0.8</maven.rat.version>
<!-- Plugin options -->
- <numForkedUT>2</numForkedUT>
- <numForkedIT>2</numForkedIT>
+ <numForkedUT>3</numForkedUT>
+ <numForkedIT>7</numForkedIT>
<!-- Set default encoding so multi-byte tests work correctly on the Mac -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>