You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by el...@apache.org on 2015/06/02 23:57:06 UTC
[1/7] accumulo git commit: ACCUMULO-3881 Fix *ProxyITs to work with
Kerberos enabled.
Repository: accumulo
Updated Branches:
refs/heads/1.7 99c734c8c -> 5bd993bae
refs/heads/master fba068b7b -> 0b7d8eeae
ACCUMULO-3881 Fix *ProxyITs to work with Kerberos enabled.
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/198c5fb8
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/198c5fb8
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/198c5fb8
Branch: refs/heads/1.7
Commit: 198c5fb8f7a21eb869528e2050e69479796541ab
Parents: 99c734c
Author: Josh Elser <el...@apache.org>
Authored: Tue Jun 2 16:44:52 2015 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Tue Jun 2 16:48:44 2015 -0400
----------------------------------------------------------------------
.../java/org/apache/accumulo/proxy/Proxy.java | 8 +-
.../apache/accumulo/proxy/TestProxyClient.java | 21 +
.../accumulo/harness/SharedMiniClusterIT.java | 6 +-
.../apache/accumulo/proxy/SimpleProxyBase.java | 485 +++++++++++++++----
4 files changed, 430 insertions(+), 90 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
----------------------------------------------------------------------
diff --git a/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java b/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
index 55431fa..2290106 100644
--- a/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
+++ b/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
@@ -178,6 +178,11 @@ public class Proxy implements KeywordExecutable {
}
public static ServerAddress createProxyServer(HostAndPort address, TProtocolFactory protocolFactory, Properties properties) throws Exception {
+ return createProxyServer(address, protocolFactory, properties, ClientConfiguration.loadDefault());
+ }
+
+ public static ServerAddress createProxyServer(HostAndPort address, TProtocolFactory protocolFactory, Properties properties, ClientConfiguration clientConf)
+ throws Exception {
final int numThreads = Integer.parseInt(properties.getProperty(THRIFT_THREAD_POOL_SIZE_KEY, THRIFT_THREAD_POOL_SIZE_DEFAULT));
final long maxFrameSize = AccumuloConfiguration.getMemoryInBytes(properties.getProperty(THRIFT_MAX_FRAME_SIZE_KEY, THRIFT_MAX_FRAME_SIZE_DEFAULT));
final int simpleTimerThreadpoolSize = Integer.parseInt(Property.GENERAL_SIMPLETIMER_THREADPOOL_SIZE.getDefaultValue());
@@ -205,7 +210,6 @@ public class Proxy implements KeywordExecutable {
serverType = ThriftServerType.get(serverTypeStr);
}
- ClientConfiguration clientConf = ClientConfiguration.loadDefault();
SslConnectionParams sslParams = null;
SaslServerConnectionParams saslParams = null;
switch (serverType) {
@@ -213,7 +217,7 @@ public class Proxy implements KeywordExecutable {
sslParams = SslConnectionParams.forClient(ClientContext.convertClientConfig(clientConf));
break;
case SASL:
- if (!clientConf.getBoolean(ClientProperty.INSTANCE_RPC_SASL_ENABLED.getKey())) {
+ if (!clientConf.getBoolean(ClientProperty.INSTANCE_RPC_SASL_ENABLED.getKey(), false)) {
// ACCUMULO-3651 Changed level to error and added FATAL to message for slf4j capability
log.error("FATAL: SASL thrift server was requested but it is disabled in client configuration");
throw new RuntimeException("SASL is not enabled in configuration");
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
----------------------------------------------------------------------
diff --git a/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java b/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
index fb23484..4894f13 100644
--- a/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
+++ b/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
@@ -26,17 +26,22 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import javax.security.sasl.SaslException;
+
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.accumulo.core.rpc.UGIAssumingTransport;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.ColumnUpdate;
import org.apache.accumulo.proxy.thrift.Key;
import org.apache.accumulo.proxy.thrift.ScanResult;
import org.apache.accumulo.proxy.thrift.TimeType;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TSaslClientTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
@@ -59,6 +64,22 @@ public class TestProxyClient {
transport.open();
}
+ public TestProxyClient(String host, int port, TProtocolFactory protoFactory, String proxyPrimary, UserGroupInformation ugi) throws SaslException,
+ TTransportException {
+ TSocket socket = new TSocket(host, port);
+ TSaslClientTransport saslTransport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, host, Collections.singletonMap("javax.security.sasl.qop",
+ "auth"), null, socket);
+
+ transport = new UGIAssumingTransport(saslTransport, ugi);
+
+ // UGI transport will perform the doAs for us
+ transport.open();
+
+ AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
+ final TProtocol protocol = protoFactory.getProtocol(transport);
+ proxy = factory.getClient(protocol);
+ }
+
public synchronized void close() {
if (null != transport) {
transport.close();
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java b/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
index 98ebddc..4a2501f 100644
--- a/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
+++ b/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
@@ -48,7 +48,7 @@ import org.slf4j.LoggerFactory;
*/
public abstract class SharedMiniClusterIT extends AccumuloIT implements ClusterUsers {
private static final Logger log = LoggerFactory.getLogger(SharedMiniClusterIT.class);
- private static final String TRUE = Boolean.toString(true);
+ public static final String TRUE = Boolean.toString(true);
private static String principal = "root";
private static String rootPassword;
@@ -159,6 +159,10 @@ public abstract class SharedMiniClusterIT extends AccumuloIT implements ClusterU
}
}
+ public static TestingKdc getKdc() {
+ return krb;
+ }
+
@Override
public ClusterUser getAdminUser() {
if (null == krb) {
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java b/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
index 8895e9e..86051f6 100644
--- a/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
+++ b/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
@@ -26,8 +26,8 @@ import static org.junit.Assert.fail;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
+import java.net.InetAddress;
import java.nio.ByteBuffer;
-import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -41,8 +41,11 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
+import org.apache.accumulo.cluster.ClusterUser;
+import org.apache.accumulo.core.client.ClientConfiguration;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.security.tokens.KerberosToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.conf.DefaultConfiguration;
import org.apache.accumulo.core.conf.Property;
@@ -58,7 +61,9 @@ import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.util.ByteBufferUtil;
import org.apache.accumulo.core.util.UtilWaitThread;
import org.apache.accumulo.examples.simple.constraints.NumericValueConstraint;
+import org.apache.accumulo.harness.MiniClusterHarness;
import org.apache.accumulo.harness.SharedMiniClusterIT;
+import org.apache.accumulo.harness.TestingKdc;
import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl;
import org.apache.accumulo.proxy.thrift.AccumuloProxy.Client;
import org.apache.accumulo.proxy.thrift.AccumuloSecurityException;
@@ -97,11 +102,14 @@ import org.apache.accumulo.proxy.thrift.UnknownWriter;
import org.apache.accumulo.proxy.thrift.WriterOptions;
import org.apache.accumulo.server.util.PortUtils;
import org.apache.accumulo.test.functional.SlowIterator;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.thrift.TApplicationException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TProtocolFactory;
@@ -136,6 +144,8 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
private static Map<String,String> properties = new HashMap<>();
private static ByteBuffer creds = null;
+ private static String hostname, proxyPrincipal, proxyPrimary, clientPrincipal;
+ private static File proxyKeytab, clientKeytab;
// Implementations can set this
static TProtocolFactory factory = null;
@@ -144,6 +154,10 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
Iterators.size(c.createScanner(MetadataTable.NAME, Authorizations.EMPTY).iterator());
}
+ private static boolean isKerberosEnabled() {
+ return SharedMiniClusterIT.TRUE.equals(System.getProperty(MiniClusterHarness.USE_KERBEROS_FOR_IT_OPTION));
+ }
+
/**
* Does the actual test setup, invoked by the concrete test class
*/
@@ -154,20 +168,60 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
Instance inst = c.getInstance();
waitForAccumulo(c);
+ hostname = InetAddress.getLocalHost().getCanonicalHostName();
+
Properties props = new Properties();
props.put("instance", inst.getInstanceName());
props.put("zookeepers", inst.getZooKeepers());
- props.put("tokenClass", PasswordToken.class.getName());
- // Avoid issues with locally installed client configuration files with custom properties
- File emptyFile = Files.createTempFile(null, null).toFile();
- emptyFile.deleteOnExit();
- props.put("clientConfigurationFile", emptyFile.toString());
- properties.put("password", SharedMiniClusterIT.getRootPassword());
- properties.put("clientConfigurationFile", emptyFile.toString());
+ final String tokenClass;
+ if (isKerberosEnabled()) {
+ tokenClass = KerberosToken.class.getName();
+ TestingKdc kdc = getKdc();
+
+ // Create a principal+keytab for the proxy
+ proxyKeytab = new File(kdc.getKeytabDir(), "proxy.keytab");
+ hostname = InetAddress.getLocalHost().getCanonicalHostName();
+ // Set the primary because the client needs to know it
+ proxyPrimary = "proxy";
+ // Qualify with an instance
+ proxyPrincipal = proxyPrimary + "/" + hostname;
+ kdc.createPrincipal(proxyKeytab, proxyPrincipal);
+ // Tack on the realm too
+ proxyPrincipal = kdc.qualifyUser(proxyPrincipal);
+
+ props.setProperty("kerberosPrincipal", proxyPrincipal);
+ props.setProperty("kerberosKeytab", proxyKeytab.getCanonicalPath());
+ props.setProperty("thriftServerType", "sasl");
+
+ // Enabled kerberos auth
+ Configuration conf = new Configuration(false);
+ conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
+ UserGroupInformation.setConfiguration(conf);
+
+ // Login for the Proxy itself
+ UserGroupInformation.loginUserFromKeytab(proxyPrincipal, proxyKeytab.getAbsolutePath());
+
+ // User for tests
+ ClusterUser user = kdc.getRootUser();
+ clientPrincipal = user.getPrincipal();
+ clientKeytab = user.getKeytab();
+ } else {
+ clientPrincipal = "root";
+ tokenClass = PasswordToken.class.getName();
+ properties.put("password", SharedMiniClusterIT.getRootPassword());
+ hostname = "localhost";
+ }
+
+ props.put("tokenClass", tokenClass);
+
+ ClientConfiguration clientConfig = SharedMiniClusterIT.getCluster().getClientConfig();
+ String clientConfPath = new File(SharedMiniClusterIT.getCluster().getConfig().getConfDir(), "client.conf").getAbsolutePath();
+ props.put("clientConfigurationFile", clientConfPath);
+ properties.put("clientConfigurationFile", clientConfPath);
proxyPort = PortUtils.getRandomFreePort();
- proxyServer = Proxy.createProxyServer(HostAndPort.fromParts("localhost", proxyPort), factory, props).server;
+ proxyServer = Proxy.createProxyServer(HostAndPort.fromParts(hostname, proxyPort), factory, props, clientConfig).server;
while (!proxyServer.isServing())
UtilWaitThread.sleep(100);
}
@@ -186,16 +240,44 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@Before
public void setup() throws Exception {
// Create a new client for each test
- proxyClient = new TestProxyClient("localhost", proxyPort, factory);
- client = proxyClient.proxy();
- creds = client.login("root", properties);
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ proxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
+ client = proxyClient.proxy();
+ creds = client.login(clientPrincipal, properties);
+
+ TestingKdc kdc = getKdc();
+ final ClusterUser user = kdc.getClientPrincipal(0);
+ // Create another user
+ client.createLocalUser(creds, user.getPrincipal(), s2bb("unused"));
+ // Login in as that user we just created
+ UserGroupInformation.loginUserFromKeytab(user.getPrincipal(), user.getKeytab().getAbsolutePath());
+ final UserGroupInformation badUgi = UserGroupInformation.getCurrentUser();
+ // Get a "Credentials" object for the proxy
+ TestProxyClient badClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, badUgi);
+ try {
+ Client badProxy = badClient.proxy();
+ badLogin = badProxy.login(user.getPrincipal(), properties);
+ } finally {
+ badClient.close();
+ }
- // Create 'user'
- client.createLocalUser(creds, "user", s2bb(SharedMiniClusterIT.getRootPassword()));
- // Log in as 'user'
- badLogin = client.login("user", properties);
- // Drop 'user', invalidating the credentials
- client.dropLocalUser(creds, "user");
+ // Log back in as the test user
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ // Drop test user, invalidating the credentials (not to mention not having the krb credentials anymore)
+ client.dropLocalUser(creds, user.getPrincipal());
+ } else {
+ proxyClient = new TestProxyClient(hostname, proxyPort, factory);
+ client = proxyClient.proxy();
+ creds = client.login("root", properties);
+
+ // Create 'user'
+ client.createLocalUser(creds, "user", s2bb(SharedMiniClusterIT.getRootPassword()));
+ // Log in as 'user'
+ badLogin = client.login("user", properties);
+ // Drop 'user', invalidating the credentials
+ client.dropLocalUser(creds, "user");
+ }
// Create a general table to be used
table = getUniqueNames(1)[0];
@@ -205,6 +287,9 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@After
public void teardown() throws Exception {
if (null != table) {
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ }
try {
if (client.tableExists(creds, table)) {
client.deleteTable(creds, table);
@@ -392,9 +477,18 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
client.testClassLoad(badLogin, DevNull.class.getName(), SortedKeyValueIterator.class.getName());
}
- @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ @Test(timeout = 5000)
public void authenticateUserLoginFailure() throws Exception {
- client.authenticateUser(badLogin, "root", s2pp(SharedMiniClusterIT.getRootPassword()));
+ if (!isKerberosEnabled()) {
+ try {
+ // Not really a relevant test for kerberos
+ client.authenticateUser(badLogin, "root", s2pp(SharedMiniClusterIT.getRootPassword()));
+ fail("Expected AccumuloSecurityException");
+ } catch (AccumuloSecurityException e) {
+ // Expected
+ return;
+ }
+ }
}
@Test(expected = AccumuloSecurityException.class, timeout = 5000)
@@ -897,13 +991,25 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@Override
public void run() {
String scanner;
+ TestProxyClient proxyClient2 = null;
try {
- Client client2 = new TestProxyClient("localhost", proxyPort, factory).proxy();
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
+ } else {
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
+ }
+
+ Client client2 = proxyClient2.proxy();
scanner = client2.createScanner(creds, "slow", null);
client2.nextK(scanner, 10);
client2.closeScanner(scanner);
} catch (Exception e) {
throw new RuntimeException(e);
+ } finally {
+ if (null != proxyClient2) {
+ proxyClient2.close();
+ }
}
}
};
@@ -915,7 +1021,7 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
for (String tserver : client.getTabletServers(creds)) {
List<ActiveScan> scansForServer = client.getActiveScans(creds, tserver);
for (ActiveScan scan : scansForServer) {
- if ("root".equals(scan.getUser())) {
+ if (clientPrincipal.equals(scan.getUser())) {
scans.add(scan);
}
}
@@ -927,12 +1033,12 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
}
t.join();
- assertFalse(scans.isEmpty());
+ assertFalse("Expected to find scans, but found none", scans.isEmpty());
boolean found = false;
Map<String,String> map = null;
for (int i = 0; i < scans.size() && !found; i++) {
ActiveScan scan = scans.get(i);
- if ("root".equals(scan.getUser())) {
+ if (clientPrincipal.equals(scan.getUser())) {
assertTrue(ScanState.RUNNING.equals(scan.getState()) || ScanState.QUEUED.equals(scan.getState()));
assertEquals(ScanType.SINGLE, scan.getType());
assertEquals("slow", scan.getTable());
@@ -970,11 +1076,22 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
Thread t = new Thread() {
@Override
public void run() {
+ TestProxyClient proxyClient2 = null;
try {
- Client client2 = new TestProxyClient("localhost", proxyPort, factory).proxy();
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
+ } else {
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
+ }
+ Client client2 = proxyClient2.proxy();
client2.compactTable(creds, "slow", null, null, null, true, true, null);
} catch (Exception e) {
throw new RuntimeException(e);
+ } finally {
+ if (null != proxyClient2) {
+ proxyClient2.close();
+ }
}
}
};
@@ -1027,19 +1144,34 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@Test
public void userAuthentication() throws Exception {
- // check password
- assertTrue(client.authenticateUser(creds, "root", s2pp(SharedMiniClusterIT.getRootPassword())));
- assertFalse(client.authenticateUser(creds, "root", s2pp("")));
+ if (isKerberosEnabled()) {
+ assertTrue(client.authenticateUser(creds, clientPrincipal, Collections.<String,String> emptyMap()));
+ // Can't really authenticate "badly" at the application level w/ kerberos. It's going to fail to even set up an RPC
+ } else {
+ // check password
+ assertTrue(client.authenticateUser(creds, "root", s2pp(SharedMiniClusterIT.getRootPassword())));
+ assertFalse(client.authenticateUser(creds, "root", s2pp("")));
+ }
}
@Test
public void userManagement() throws Exception {
- String user = getUniqueNames(1)[0];
+
+ String user;
+ ClusterUser otherClient = null;
+ ByteBuffer password = s2bb("password");
+ if (isKerberosEnabled()) {
+ otherClient = getKdc().getClientPrincipal(1);
+ user = otherClient.getPrincipal();
+ } else {
+ user = getUniqueNames(1)[0];
+ }
+
// create a user
- client.createLocalUser(creds, user, s2bb("password"));
+ client.createLocalUser(creds, user, password);
// change auths
Set<String> users = client.listLocalUsers(creds);
- Set<String> expectedUsers = new HashSet<String>(Arrays.asList("root", user));
+ Set<String> expectedUsers = new HashSet<String>(Arrays.asList(clientPrincipal, user));
assertTrue("Did not find all expected users: " + expectedUsers, users.containsAll(expectedUsers));
HashSet<ByteBuffer> auths = new HashSet<ByteBuffer>(Arrays.asList(s2bb("A"), s2bb("B")));
client.changeUserAuthorizations(creds, user, auths);
@@ -1047,70 +1179,182 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
assertEquals(auths, new HashSet<ByteBuffer>(update));
// change password
- client.changeLocalUserPassword(creds, user, s2bb(""));
- assertTrue(client.authenticateUser(creds, user, s2pp("")));
+ if (!isKerberosEnabled()) {
+ password = s2bb("");
+ client.changeLocalUserPassword(creds, user, password);
+ assertTrue(client.authenticateUser(creds, user, s2pp(password.toString())));
+ }
- // check login with new password
- client.login(user, s2pp(""));
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ // Re-login in and make a new connection. Can't use the previous one
+
+ TestProxyClient otherProxyClient = null;
+ try {
+ otherProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
+ otherProxyClient.proxy().login(user, Collections.<String,String> emptyMap());
+ } finally {
+ if (null != otherProxyClient) {
+ otherProxyClient.close();
+ }
+ }
+ } else {
+ // check login with new password
+ client.login(user, s2pp(password.toString()));
+ }
}
@Test
public void userPermissions() throws Exception {
String userName = getUniqueNames(1)[0];
- // create a user
- client.createLocalUser(creds, userName, s2bb("password"));
-
- ByteBuffer user = client.login(userName, s2pp("password"));
+ ClusterUser otherClient = null;
+ ByteBuffer password = s2bb("password");
+ ByteBuffer user;
+
+ TestProxyClient origProxyClient = null;
+ Client origClient = null;
+ TestProxyClient userProxyClient = null;
+ Client userClient = null;
+
+ if (isKerberosEnabled()) {
+ otherClient = getKdc().getClientPrincipal(1);
+ userName = otherClient.getPrincipal();
+
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ // Re-login in and make a new connection. Can't use the previous one
+
+ userProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
+
+ origProxyClient = proxyClient;
+ origClient = client;
+ userClient = client = userProxyClient.proxy();
+
+ user = client.login(userName, Collections.<String,String> emptyMap());
+ } else {
+ userName = getUniqueNames(1)[0];
+ // create a user
+ client.createLocalUser(creds, userName, password);
+ user = client.login(userName, s2pp(password.toString()));
+ }
// check permission failure
try {
client.createTable(user, "fail", true, TimeType.MILLIS);
fail("should not create the table");
} catch (AccumuloSecurityException ex) {
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
assertFalse(client.listTables(creds).contains("fail"));
}
// grant permissions and test
assertFalse(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
client.grantSystemPermission(creds, userName, SystemPermission.CREATE_TABLE);
assertTrue(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
client.createTable(user, "success", true, TimeType.MILLIS);
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
client.listTables(creds).contains("succcess");
// revoke permissions
client.revokeSystemPermission(creds, userName, SystemPermission.CREATE_TABLE);
assertFalse(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
try {
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
client.createTable(user, "fail", true, TimeType.MILLIS);
fail("should not create the table");
} catch (AccumuloSecurityException ex) {
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
assertFalse(client.listTables(creds).contains("fail"));
}
// denied!
try {
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
String scanner = client.createScanner(user, table, null);
client.nextK(scanner, 100);
fail("stooge should not read table test");
} catch (AccumuloSecurityException ex) {}
+
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
// grant
assertFalse(client.hasTablePermission(creds, userName, table, TablePermission.READ));
client.grantTablePermission(creds, userName, table, TablePermission.READ);
assertTrue(client.hasTablePermission(creds, userName, table, TablePermission.READ));
+
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
String scanner = client.createScanner(user, table, null);
client.nextK(scanner, 10);
client.closeScanner(scanner);
+
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
// revoke
client.revokeTablePermission(creds, userName, table, TablePermission.READ);
assertFalse(client.hasTablePermission(creds, userName, table, TablePermission.READ));
try {
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
scanner = client.createScanner(user, table, null);
client.nextK(scanner, 100);
fail("stooge should not read table test");
} catch (AccumuloSecurityException ex) {}
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
// delete user
client.dropLocalUser(creds, userName);
Set<String> users = client.listLocalUsers(creds);
assertFalse("Should not see user after they are deleted", users.contains(userName));
+
+ if (isKerberosEnabled()) {
+ userProxyClient.close();
+ proxyClient = origProxyClient;
+ client = origClient;
+ }
}
@Test
@@ -1563,7 +1807,7 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
String scid = client.createScanner(creds, table, new ScanOptions());
ScanResult keyValues = client.nextK(scid, expected.length + 1);
- assertEquals(expected.length, keyValues.results.size());
+ assertEquals("Saw " + keyValues.results, expected.length, keyValues.results.size());
assertFalse(keyValues.more);
for (int i = 0; i < keyValues.results.size(); i++) {
@@ -1793,71 +2037,138 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
fail("conditional writer not closed");
} catch (UnknownWriter uk) {}
- // run test with colvis
- client.createLocalUser(creds, "cwuser", s2bb("bestpasswordever"));
- client.changeUserAuthorizations(creds, "cwuser", Collections.singleton(s2bb("A")));
- client.grantTablePermission(creds, "cwuser", table, TablePermission.WRITE);
- client.grantTablePermission(creds, "cwuser", table, TablePermission.READ);
+ String principal;
+ ClusterUser cwuser = null;
+ if (isKerberosEnabled()) {
+ cwuser = getKdc().getClientPrincipal(1);
+ principal = cwuser.getPrincipal();
+ client.createLocalUser(creds, principal, s2bb("unused"));
+
+ } else {
+ principal = "cwuser";
+ // run test with colvis
+ client.createLocalUser(creds, principal, s2bb("bestpasswordever"));
+ }
- ByteBuffer cwuCreds = client.login("cwuser", Collections.singletonMap("password", "bestpasswordever"));
+ client.changeUserAuthorizations(creds, principal, Collections.singleton(s2bb("A")));
+ client.grantTablePermission(creds, principal, table, TablePermission.WRITE);
+ client.grantTablePermission(creds, principal, table, TablePermission.READ);
+
+ TestProxyClient cwuserProxyClient = null;
+ Client origClient = null;
+ Map<String,String> cwProperties;
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ final UserGroupInformation cwuserUgi = UserGroupInformation.getCurrentUser();
+ // Re-login in and make a new connection. Can't use the previous one
+ cwuserProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, cwuserUgi);
+ origClient = client;
+ client = cwuserProxyClient.proxy();
+ cwProperties = Collections.emptyMap();
+ } else {
+ cwProperties = Collections.singletonMap("password", "bestpasswordever");
+ }
- cwid = client.createConditionalWriter(cwuCreds, table, new ConditionalWriterOptions().setAuthorizations(Collections.singleton(s2bb("A"))));
+ try {
+ ByteBuffer cwCreds = client.login(principal, cwProperties);
- updates.clear();
- updates.put(
- s2bb("00348"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A")))), Arrays.asList(newColUpdate("data", "seq", "1"),
- newColUpdate("data", "c", "1").setColVisibility(s2bb("A")))));
- updates.put(s2bb("00349"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("B")))), Arrays.asList(newColUpdate("data", "seq", "1"))));
+ cwid = client.createConditionalWriter(cwCreds, table, new ConditionalWriterOptions().setAuthorizations(Collections.singleton(s2bb("A"))));
- results = client.updateRowsConditionally(cwid, updates);
+ updates.clear();
+ updates.put(
+ s2bb("00348"),
+ new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A")))), Arrays.asList(newColUpdate("data", "seq", "1"),
+ newColUpdate("data", "c", "1").setColVisibility(s2bb("A")))));
+ updates
+ .put(
+ s2bb("00349"),
+ new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("B")))), Arrays.asList(newColUpdate("data", "seq",
+ "1"))));
- assertEquals(2, results.size());
- assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
- assertEquals(ConditionalStatus.INVISIBLE_VISIBILITY, results.get(s2bb("00349")));
+ results = client.updateRowsConditionally(cwid, updates);
- assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
- {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
+ assertEquals(2, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
+ assertEquals(ConditionalStatus.INVISIBLE_VISIBILITY, results.get(s2bb("00349")));
- updates.clear();
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+ // Verify that the original user can't see the updates with visibilities set
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
- updates.clear();
- updates.put(
- s2bb("00348"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("0"))), Arrays.asList(
- newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ client = cwuserProxyClient.proxy();
+ }
- results = client.updateRowsConditionally(cwid, updates);
+ updates.clear();
- assertEquals(1, results.size());
- assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00348")));
+ updates.clear();
+ updates.put(s2bb("00348"), new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("0"))),
+ Arrays.asList(newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
- assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
- {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
+ results = client.updateRowsConditionally(cwid, updates);
- updates.clear();
- updates.put(
- s2bb("00348"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("1"))), Arrays.asList(
- newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00348")));
- results = client.updateRowsConditionally(cwid, updates);
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
- assertEquals(1, results.size());
- assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
+ // Same results as the original user
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
- assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
- {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "2"}}, table);
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ client = cwuserProxyClient.proxy();
+ }
- client.closeConditionalWriter(cwid);
- try {
- client.updateRowsConditionally(cwid, updates);
- fail("conditional writer not closed");
- } catch (UnknownWriter uk) {}
+ updates.clear();
+ updates.put(s2bb("00348"), new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("1"))),
+ Arrays.asList(newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
- client.dropLocalUser(creds, "cwuser");
+ results = client.updateRowsConditionally(cwid, updates);
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
+
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "2"}}, table);
+
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ client = cwuserProxyClient.proxy();
+ }
+
+ client.closeConditionalWriter(cwid);
+ try {
+ client.updateRowsConditionally(cwid, updates);
+ fail("conditional writer not closed");
+ } catch (UnknownWriter uk) {}
+ } finally {
+ if (isKerberosEnabled()) {
+ // Close the other client
+ if (null != cwuserProxyClient) {
+ cwuserProxyClient.close();
+ }
+
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ // Re-login and restore the original client
+ client = origClient;
+ }
+ client.dropLocalUser(creds, principal);
+ }
}
private void checkKey(String row, String cf, String cq, String val, KeyValue keyValue) {
[2/7] accumulo git commit: ACCUMULO-3881 Fix *ProxyITs to work with
Kerberos enabled.
Posted by el...@apache.org.
ACCUMULO-3881 Fix *ProxyITs to work with Kerberos enabled.
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/198c5fb8
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/198c5fb8
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/198c5fb8
Branch: refs/heads/master
Commit: 198c5fb8f7a21eb869528e2050e69479796541ab
Parents: 99c734c
Author: Josh Elser <el...@apache.org>
Authored: Tue Jun 2 16:44:52 2015 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Tue Jun 2 16:48:44 2015 -0400
----------------------------------------------------------------------
.../java/org/apache/accumulo/proxy/Proxy.java | 8 +-
.../apache/accumulo/proxy/TestProxyClient.java | 21 +
.../accumulo/harness/SharedMiniClusterIT.java | 6 +-
.../apache/accumulo/proxy/SimpleProxyBase.java | 485 +++++++++++++++----
4 files changed, 430 insertions(+), 90 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
----------------------------------------------------------------------
diff --git a/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java b/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
index 55431fa..2290106 100644
--- a/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
+++ b/proxy/src/main/java/org/apache/accumulo/proxy/Proxy.java
@@ -178,6 +178,11 @@ public class Proxy implements KeywordExecutable {
}
public static ServerAddress createProxyServer(HostAndPort address, TProtocolFactory protocolFactory, Properties properties) throws Exception {
+ return createProxyServer(address, protocolFactory, properties, ClientConfiguration.loadDefault());
+ }
+
+ public static ServerAddress createProxyServer(HostAndPort address, TProtocolFactory protocolFactory, Properties properties, ClientConfiguration clientConf)
+ throws Exception {
final int numThreads = Integer.parseInt(properties.getProperty(THRIFT_THREAD_POOL_SIZE_KEY, THRIFT_THREAD_POOL_SIZE_DEFAULT));
final long maxFrameSize = AccumuloConfiguration.getMemoryInBytes(properties.getProperty(THRIFT_MAX_FRAME_SIZE_KEY, THRIFT_MAX_FRAME_SIZE_DEFAULT));
final int simpleTimerThreadpoolSize = Integer.parseInt(Property.GENERAL_SIMPLETIMER_THREADPOOL_SIZE.getDefaultValue());
@@ -205,7 +210,6 @@ public class Proxy implements KeywordExecutable {
serverType = ThriftServerType.get(serverTypeStr);
}
- ClientConfiguration clientConf = ClientConfiguration.loadDefault();
SslConnectionParams sslParams = null;
SaslServerConnectionParams saslParams = null;
switch (serverType) {
@@ -213,7 +217,7 @@ public class Proxy implements KeywordExecutable {
sslParams = SslConnectionParams.forClient(ClientContext.convertClientConfig(clientConf));
break;
case SASL:
- if (!clientConf.getBoolean(ClientProperty.INSTANCE_RPC_SASL_ENABLED.getKey())) {
+ if (!clientConf.getBoolean(ClientProperty.INSTANCE_RPC_SASL_ENABLED.getKey(), false)) {
// ACCUMULO-3651 Changed level to error and added FATAL to message for slf4j capability
log.error("FATAL: SASL thrift server was requested but it is disabled in client configuration");
throw new RuntimeException("SASL is not enabled in configuration");
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
----------------------------------------------------------------------
diff --git a/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java b/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
index fb23484..4894f13 100644
--- a/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
+++ b/proxy/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
@@ -26,17 +26,22 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import javax.security.sasl.SaslException;
+
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.accumulo.core.rpc.UGIAssumingTransport;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.ColumnUpdate;
import org.apache.accumulo.proxy.thrift.Key;
import org.apache.accumulo.proxy.thrift.ScanResult;
import org.apache.accumulo.proxy.thrift.TimeType;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TSaslClientTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
@@ -59,6 +64,22 @@ public class TestProxyClient {
transport.open();
}
+ public TestProxyClient(String host, int port, TProtocolFactory protoFactory, String proxyPrimary, UserGroupInformation ugi) throws SaslException,
+ TTransportException {
+ TSocket socket = new TSocket(host, port);
+ TSaslClientTransport saslTransport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, host, Collections.singletonMap("javax.security.sasl.qop",
+ "auth"), null, socket);
+
+ transport = new UGIAssumingTransport(saslTransport, ugi);
+
+ // UGI transport will perform the doAs for us
+ transport.open();
+
+ AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
+ final TProtocol protocol = protoFactory.getProtocol(transport);
+ proxy = factory.getClient(protocol);
+ }
+
public synchronized void close() {
if (null != transport) {
transport.close();
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java b/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
index 98ebddc..4a2501f 100644
--- a/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
+++ b/test/src/test/java/org/apache/accumulo/harness/SharedMiniClusterIT.java
@@ -48,7 +48,7 @@ import org.slf4j.LoggerFactory;
*/
public abstract class SharedMiniClusterIT extends AccumuloIT implements ClusterUsers {
private static final Logger log = LoggerFactory.getLogger(SharedMiniClusterIT.class);
- private static final String TRUE = Boolean.toString(true);
+ public static final String TRUE = Boolean.toString(true);
private static String principal = "root";
private static String rootPassword;
@@ -159,6 +159,10 @@ public abstract class SharedMiniClusterIT extends AccumuloIT implements ClusterU
}
}
+ public static TestingKdc getKdc() {
+ return krb;
+ }
+
@Override
public ClusterUser getAdminUser() {
if (null == krb) {
http://git-wip-us.apache.org/repos/asf/accumulo/blob/198c5fb8/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java b/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
index 8895e9e..86051f6 100644
--- a/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
+++ b/test/src/test/java/org/apache/accumulo/proxy/SimpleProxyBase.java
@@ -26,8 +26,8 @@ import static org.junit.Assert.fail;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
+import java.net.InetAddress;
import java.nio.ByteBuffer;
-import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -41,8 +41,11 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
+import org.apache.accumulo.cluster.ClusterUser;
+import org.apache.accumulo.core.client.ClientConfiguration;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.security.tokens.KerberosToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.conf.DefaultConfiguration;
import org.apache.accumulo.core.conf.Property;
@@ -58,7 +61,9 @@ import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.util.ByteBufferUtil;
import org.apache.accumulo.core.util.UtilWaitThread;
import org.apache.accumulo.examples.simple.constraints.NumericValueConstraint;
+import org.apache.accumulo.harness.MiniClusterHarness;
import org.apache.accumulo.harness.SharedMiniClusterIT;
+import org.apache.accumulo.harness.TestingKdc;
import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl;
import org.apache.accumulo.proxy.thrift.AccumuloProxy.Client;
import org.apache.accumulo.proxy.thrift.AccumuloSecurityException;
@@ -97,11 +102,14 @@ import org.apache.accumulo.proxy.thrift.UnknownWriter;
import org.apache.accumulo.proxy.thrift.WriterOptions;
import org.apache.accumulo.server.util.PortUtils;
import org.apache.accumulo.test.functional.SlowIterator;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.thrift.TApplicationException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TProtocolFactory;
@@ -136,6 +144,8 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
private static Map<String,String> properties = new HashMap<>();
private static ByteBuffer creds = null;
+ private static String hostname, proxyPrincipal, proxyPrimary, clientPrincipal;
+ private static File proxyKeytab, clientKeytab;
// Implementations can set this
static TProtocolFactory factory = null;
@@ -144,6 +154,10 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
Iterators.size(c.createScanner(MetadataTable.NAME, Authorizations.EMPTY).iterator());
}
+ private static boolean isKerberosEnabled() {
+ return SharedMiniClusterIT.TRUE.equals(System.getProperty(MiniClusterHarness.USE_KERBEROS_FOR_IT_OPTION));
+ }
+
/**
* Does the actual test setup, invoked by the concrete test class
*/
@@ -154,20 +168,60 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
Instance inst = c.getInstance();
waitForAccumulo(c);
+ hostname = InetAddress.getLocalHost().getCanonicalHostName();
+
Properties props = new Properties();
props.put("instance", inst.getInstanceName());
props.put("zookeepers", inst.getZooKeepers());
- props.put("tokenClass", PasswordToken.class.getName());
- // Avoid issues with locally installed client configuration files with custom properties
- File emptyFile = Files.createTempFile(null, null).toFile();
- emptyFile.deleteOnExit();
- props.put("clientConfigurationFile", emptyFile.toString());
- properties.put("password", SharedMiniClusterIT.getRootPassword());
- properties.put("clientConfigurationFile", emptyFile.toString());
+ final String tokenClass;
+ if (isKerberosEnabled()) {
+ tokenClass = KerberosToken.class.getName();
+ TestingKdc kdc = getKdc();
+
+ // Create a principal+keytab for the proxy
+ proxyKeytab = new File(kdc.getKeytabDir(), "proxy.keytab");
+ hostname = InetAddress.getLocalHost().getCanonicalHostName();
+ // Set the primary because the client needs to know it
+ proxyPrimary = "proxy";
+ // Qualify with an instance
+ proxyPrincipal = proxyPrimary + "/" + hostname;
+ kdc.createPrincipal(proxyKeytab, proxyPrincipal);
+ // Tack on the realm too
+ proxyPrincipal = kdc.qualifyUser(proxyPrincipal);
+
+ props.setProperty("kerberosPrincipal", proxyPrincipal);
+ props.setProperty("kerberosKeytab", proxyKeytab.getCanonicalPath());
+ props.setProperty("thriftServerType", "sasl");
+
+ // Enabled kerberos auth
+ Configuration conf = new Configuration(false);
+ conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
+ UserGroupInformation.setConfiguration(conf);
+
+ // Login for the Proxy itself
+ UserGroupInformation.loginUserFromKeytab(proxyPrincipal, proxyKeytab.getAbsolutePath());
+
+ // User for tests
+ ClusterUser user = kdc.getRootUser();
+ clientPrincipal = user.getPrincipal();
+ clientKeytab = user.getKeytab();
+ } else {
+ clientPrincipal = "root";
+ tokenClass = PasswordToken.class.getName();
+ properties.put("password", SharedMiniClusterIT.getRootPassword());
+ hostname = "localhost";
+ }
+
+ props.put("tokenClass", tokenClass);
+
+ ClientConfiguration clientConfig = SharedMiniClusterIT.getCluster().getClientConfig();
+ String clientConfPath = new File(SharedMiniClusterIT.getCluster().getConfig().getConfDir(), "client.conf").getAbsolutePath();
+ props.put("clientConfigurationFile", clientConfPath);
+ properties.put("clientConfigurationFile", clientConfPath);
proxyPort = PortUtils.getRandomFreePort();
- proxyServer = Proxy.createProxyServer(HostAndPort.fromParts("localhost", proxyPort), factory, props).server;
+ proxyServer = Proxy.createProxyServer(HostAndPort.fromParts(hostname, proxyPort), factory, props, clientConfig).server;
while (!proxyServer.isServing())
UtilWaitThread.sleep(100);
}
@@ -186,16 +240,44 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@Before
public void setup() throws Exception {
// Create a new client for each test
- proxyClient = new TestProxyClient("localhost", proxyPort, factory);
- client = proxyClient.proxy();
- creds = client.login("root", properties);
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ proxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
+ client = proxyClient.proxy();
+ creds = client.login(clientPrincipal, properties);
+
+ TestingKdc kdc = getKdc();
+ final ClusterUser user = kdc.getClientPrincipal(0);
+ // Create another user
+ client.createLocalUser(creds, user.getPrincipal(), s2bb("unused"));
+ // Login in as that user we just created
+ UserGroupInformation.loginUserFromKeytab(user.getPrincipal(), user.getKeytab().getAbsolutePath());
+ final UserGroupInformation badUgi = UserGroupInformation.getCurrentUser();
+ // Get a "Credentials" object for the proxy
+ TestProxyClient badClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, badUgi);
+ try {
+ Client badProxy = badClient.proxy();
+ badLogin = badProxy.login(user.getPrincipal(), properties);
+ } finally {
+ badClient.close();
+ }
- // Create 'user'
- client.createLocalUser(creds, "user", s2bb(SharedMiniClusterIT.getRootPassword()));
- // Log in as 'user'
- badLogin = client.login("user", properties);
- // Drop 'user', invalidating the credentials
- client.dropLocalUser(creds, "user");
+ // Log back in as the test user
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ // Drop test user, invalidating the credentials (not to mention not having the krb credentials anymore)
+ client.dropLocalUser(creds, user.getPrincipal());
+ } else {
+ proxyClient = new TestProxyClient(hostname, proxyPort, factory);
+ client = proxyClient.proxy();
+ creds = client.login("root", properties);
+
+ // Create 'user'
+ client.createLocalUser(creds, "user", s2bb(SharedMiniClusterIT.getRootPassword()));
+ // Log in as 'user'
+ badLogin = client.login("user", properties);
+ // Drop 'user', invalidating the credentials
+ client.dropLocalUser(creds, "user");
+ }
// Create a general table to be used
table = getUniqueNames(1)[0];
@@ -205,6 +287,9 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@After
public void teardown() throws Exception {
if (null != table) {
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ }
try {
if (client.tableExists(creds, table)) {
client.deleteTable(creds, table);
@@ -392,9 +477,18 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
client.testClassLoad(badLogin, DevNull.class.getName(), SortedKeyValueIterator.class.getName());
}
- @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ @Test(timeout = 5000)
public void authenticateUserLoginFailure() throws Exception {
- client.authenticateUser(badLogin, "root", s2pp(SharedMiniClusterIT.getRootPassword()));
+ if (!isKerberosEnabled()) {
+ try {
+ // Not really a relevant test for kerberos
+ client.authenticateUser(badLogin, "root", s2pp(SharedMiniClusterIT.getRootPassword()));
+ fail("Expected AccumuloSecurityException");
+ } catch (AccumuloSecurityException e) {
+ // Expected
+ return;
+ }
+ }
}
@Test(expected = AccumuloSecurityException.class, timeout = 5000)
@@ -897,13 +991,25 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@Override
public void run() {
String scanner;
+ TestProxyClient proxyClient2 = null;
try {
- Client client2 = new TestProxyClient("localhost", proxyPort, factory).proxy();
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
+ } else {
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
+ }
+
+ Client client2 = proxyClient2.proxy();
scanner = client2.createScanner(creds, "slow", null);
client2.nextK(scanner, 10);
client2.closeScanner(scanner);
} catch (Exception e) {
throw new RuntimeException(e);
+ } finally {
+ if (null != proxyClient2) {
+ proxyClient2.close();
+ }
}
}
};
@@ -915,7 +1021,7 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
for (String tserver : client.getTabletServers(creds)) {
List<ActiveScan> scansForServer = client.getActiveScans(creds, tserver);
for (ActiveScan scan : scansForServer) {
- if ("root".equals(scan.getUser())) {
+ if (clientPrincipal.equals(scan.getUser())) {
scans.add(scan);
}
}
@@ -927,12 +1033,12 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
}
t.join();
- assertFalse(scans.isEmpty());
+ assertFalse("Expected to find scans, but found none", scans.isEmpty());
boolean found = false;
Map<String,String> map = null;
for (int i = 0; i < scans.size() && !found; i++) {
ActiveScan scan = scans.get(i);
- if ("root".equals(scan.getUser())) {
+ if (clientPrincipal.equals(scan.getUser())) {
assertTrue(ScanState.RUNNING.equals(scan.getState()) || ScanState.QUEUED.equals(scan.getState()));
assertEquals(ScanType.SINGLE, scan.getType());
assertEquals("slow", scan.getTable());
@@ -970,11 +1076,22 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
Thread t = new Thread() {
@Override
public void run() {
+ TestProxyClient proxyClient2 = null;
try {
- Client client2 = new TestProxyClient("localhost", proxyPort, factory).proxy();
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
+ } else {
+ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
+ }
+ Client client2 = proxyClient2.proxy();
client2.compactTable(creds, "slow", null, null, null, true, true, null);
} catch (Exception e) {
throw new RuntimeException(e);
+ } finally {
+ if (null != proxyClient2) {
+ proxyClient2.close();
+ }
}
}
};
@@ -1027,19 +1144,34 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
@Test
public void userAuthentication() throws Exception {
- // check password
- assertTrue(client.authenticateUser(creds, "root", s2pp(SharedMiniClusterIT.getRootPassword())));
- assertFalse(client.authenticateUser(creds, "root", s2pp("")));
+ if (isKerberosEnabled()) {
+ assertTrue(client.authenticateUser(creds, clientPrincipal, Collections.<String,String> emptyMap()));
+ // Can't really authenticate "badly" at the application level w/ kerberos. It's going to fail to even set up an RPC
+ } else {
+ // check password
+ assertTrue(client.authenticateUser(creds, "root", s2pp(SharedMiniClusterIT.getRootPassword())));
+ assertFalse(client.authenticateUser(creds, "root", s2pp("")));
+ }
}
@Test
public void userManagement() throws Exception {
- String user = getUniqueNames(1)[0];
+
+ String user;
+ ClusterUser otherClient = null;
+ ByteBuffer password = s2bb("password");
+ if (isKerberosEnabled()) {
+ otherClient = getKdc().getClientPrincipal(1);
+ user = otherClient.getPrincipal();
+ } else {
+ user = getUniqueNames(1)[0];
+ }
+
// create a user
- client.createLocalUser(creds, user, s2bb("password"));
+ client.createLocalUser(creds, user, password);
// change auths
Set<String> users = client.listLocalUsers(creds);
- Set<String> expectedUsers = new HashSet<String>(Arrays.asList("root", user));
+ Set<String> expectedUsers = new HashSet<String>(Arrays.asList(clientPrincipal, user));
assertTrue("Did not find all expected users: " + expectedUsers, users.containsAll(expectedUsers));
HashSet<ByteBuffer> auths = new HashSet<ByteBuffer>(Arrays.asList(s2bb("A"), s2bb("B")));
client.changeUserAuthorizations(creds, user, auths);
@@ -1047,70 +1179,182 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
assertEquals(auths, new HashSet<ByteBuffer>(update));
// change password
- client.changeLocalUserPassword(creds, user, s2bb(""));
- assertTrue(client.authenticateUser(creds, user, s2pp("")));
+ if (!isKerberosEnabled()) {
+ password = s2bb("");
+ client.changeLocalUserPassword(creds, user, password);
+ assertTrue(client.authenticateUser(creds, user, s2pp(password.toString())));
+ }
- // check login with new password
- client.login(user, s2pp(""));
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ // Re-login in and make a new connection. Can't use the previous one
+
+ TestProxyClient otherProxyClient = null;
+ try {
+ otherProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
+ otherProxyClient.proxy().login(user, Collections.<String,String> emptyMap());
+ } finally {
+ if (null != otherProxyClient) {
+ otherProxyClient.close();
+ }
+ }
+ } else {
+ // check login with new password
+ client.login(user, s2pp(password.toString()));
+ }
}
@Test
public void userPermissions() throws Exception {
String userName = getUniqueNames(1)[0];
- // create a user
- client.createLocalUser(creds, userName, s2bb("password"));
-
- ByteBuffer user = client.login(userName, s2pp("password"));
+ ClusterUser otherClient = null;
+ ByteBuffer password = s2bb("password");
+ ByteBuffer user;
+
+ TestProxyClient origProxyClient = null;
+ Client origClient = null;
+ TestProxyClient userProxyClient = null;
+ Client userClient = null;
+
+ if (isKerberosEnabled()) {
+ otherClient = getKdc().getClientPrincipal(1);
+ userName = otherClient.getPrincipal();
+
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ // Re-login in and make a new connection. Can't use the previous one
+
+ userProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
+
+ origProxyClient = proxyClient;
+ origClient = client;
+ userClient = client = userProxyClient.proxy();
+
+ user = client.login(userName, Collections.<String,String> emptyMap());
+ } else {
+ userName = getUniqueNames(1)[0];
+ // create a user
+ client.createLocalUser(creds, userName, password);
+ user = client.login(userName, s2pp(password.toString()));
+ }
// check permission failure
try {
client.createTable(user, "fail", true, TimeType.MILLIS);
fail("should not create the table");
} catch (AccumuloSecurityException ex) {
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
assertFalse(client.listTables(creds).contains("fail"));
}
// grant permissions and test
assertFalse(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
client.grantSystemPermission(creds, userName, SystemPermission.CREATE_TABLE);
assertTrue(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
client.createTable(user, "success", true, TimeType.MILLIS);
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
client.listTables(creds).contains("succcess");
// revoke permissions
client.revokeSystemPermission(creds, userName, SystemPermission.CREATE_TABLE);
assertFalse(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
try {
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
client.createTable(user, "fail", true, TimeType.MILLIS);
fail("should not create the table");
} catch (AccumuloSecurityException ex) {
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
assertFalse(client.listTables(creds).contains("fail"));
}
// denied!
try {
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
String scanner = client.createScanner(user, table, null);
client.nextK(scanner, 100);
fail("stooge should not read table test");
} catch (AccumuloSecurityException ex) {}
+
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
// grant
assertFalse(client.hasTablePermission(creds, userName, table, TablePermission.READ));
client.grantTablePermission(creds, userName, table, TablePermission.READ);
assertTrue(client.hasTablePermission(creds, userName, table, TablePermission.READ));
+
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
String scanner = client.createScanner(user, table, null);
client.nextK(scanner, 10);
client.closeScanner(scanner);
+
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
// revoke
client.revokeTablePermission(creds, userName, table, TablePermission.READ);
assertFalse(client.hasTablePermission(creds, userName, table, TablePermission.READ));
try {
+ if (isKerberosEnabled()) {
+ // Switch back to the extra user
+ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
+ client = userClient;
+ }
scanner = client.createScanner(user, table, null);
client.nextK(scanner, 100);
fail("stooge should not read table test");
} catch (AccumuloSecurityException ex) {}
+ if (isKerberosEnabled()) {
+ // Switch back to original client
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
// delete user
client.dropLocalUser(creds, userName);
Set<String> users = client.listLocalUsers(creds);
assertFalse("Should not see user after they are deleted", users.contains(userName));
+
+ if (isKerberosEnabled()) {
+ userProxyClient.close();
+ proxyClient = origProxyClient;
+ client = origClient;
+ }
}
@Test
@@ -1563,7 +1807,7 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
String scid = client.createScanner(creds, table, new ScanOptions());
ScanResult keyValues = client.nextK(scid, expected.length + 1);
- assertEquals(expected.length, keyValues.results.size());
+ assertEquals("Saw " + keyValues.results, expected.length, keyValues.results.size());
assertFalse(keyValues.more);
for (int i = 0; i < keyValues.results.size(); i++) {
@@ -1793,71 +2037,138 @@ public abstract class SimpleProxyBase extends SharedMiniClusterIT {
fail("conditional writer not closed");
} catch (UnknownWriter uk) {}
- // run test with colvis
- client.createLocalUser(creds, "cwuser", s2bb("bestpasswordever"));
- client.changeUserAuthorizations(creds, "cwuser", Collections.singleton(s2bb("A")));
- client.grantTablePermission(creds, "cwuser", table, TablePermission.WRITE);
- client.grantTablePermission(creds, "cwuser", table, TablePermission.READ);
+ String principal;
+ ClusterUser cwuser = null;
+ if (isKerberosEnabled()) {
+ cwuser = getKdc().getClientPrincipal(1);
+ principal = cwuser.getPrincipal();
+ client.createLocalUser(creds, principal, s2bb("unused"));
+
+ } else {
+ principal = "cwuser";
+ // run test with colvis
+ client.createLocalUser(creds, principal, s2bb("bestpasswordever"));
+ }
- ByteBuffer cwuCreds = client.login("cwuser", Collections.singletonMap("password", "bestpasswordever"));
+ client.changeUserAuthorizations(creds, principal, Collections.singleton(s2bb("A")));
+ client.grantTablePermission(creds, principal, table, TablePermission.WRITE);
+ client.grantTablePermission(creds, principal, table, TablePermission.READ);
+
+ TestProxyClient cwuserProxyClient = null;
+ Client origClient = null;
+ Map<String,String> cwProperties;
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ final UserGroupInformation cwuserUgi = UserGroupInformation.getCurrentUser();
+ // Re-login in and make a new connection. Can't use the previous one
+ cwuserProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, cwuserUgi);
+ origClient = client;
+ client = cwuserProxyClient.proxy();
+ cwProperties = Collections.emptyMap();
+ } else {
+ cwProperties = Collections.singletonMap("password", "bestpasswordever");
+ }
- cwid = client.createConditionalWriter(cwuCreds, table, new ConditionalWriterOptions().setAuthorizations(Collections.singleton(s2bb("A"))));
+ try {
+ ByteBuffer cwCreds = client.login(principal, cwProperties);
- updates.clear();
- updates.put(
- s2bb("00348"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A")))), Arrays.asList(newColUpdate("data", "seq", "1"),
- newColUpdate("data", "c", "1").setColVisibility(s2bb("A")))));
- updates.put(s2bb("00349"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("B")))), Arrays.asList(newColUpdate("data", "seq", "1"))));
+ cwid = client.createConditionalWriter(cwCreds, table, new ConditionalWriterOptions().setAuthorizations(Collections.singleton(s2bb("A"))));
- results = client.updateRowsConditionally(cwid, updates);
+ updates.clear();
+ updates.put(
+ s2bb("00348"),
+ new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A")))), Arrays.asList(newColUpdate("data", "seq", "1"),
+ newColUpdate("data", "c", "1").setColVisibility(s2bb("A")))));
+ updates
+ .put(
+ s2bb("00349"),
+ new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("B")))), Arrays.asList(newColUpdate("data", "seq",
+ "1"))));
- assertEquals(2, results.size());
- assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
- assertEquals(ConditionalStatus.INVISIBLE_VISIBILITY, results.get(s2bb("00349")));
+ results = client.updateRowsConditionally(cwid, updates);
- assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
- {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
+ assertEquals(2, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
+ assertEquals(ConditionalStatus.INVISIBLE_VISIBILITY, results.get(s2bb("00349")));
- updates.clear();
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+ // Verify that the original user can't see the updates with visibilities set
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
- updates.clear();
- updates.put(
- s2bb("00348"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("0"))), Arrays.asList(
- newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ client = cwuserProxyClient.proxy();
+ }
- results = client.updateRowsConditionally(cwid, updates);
+ updates.clear();
- assertEquals(1, results.size());
- assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00348")));
+ updates.clear();
+ updates.put(s2bb("00348"), new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("0"))),
+ Arrays.asList(newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
- assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
- {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
+ results = client.updateRowsConditionally(cwid, updates);
- updates.clear();
- updates.put(
- s2bb("00348"),
- new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("1"))), Arrays.asList(
- newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00348")));
- results = client.updateRowsConditionally(cwid, updates);
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
- assertEquals(1, results.size());
- assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
+ // Same results as the original user
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "1"}}, table);
- assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
- {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "2"}}, table);
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ client = cwuserProxyClient.proxy();
+ }
- client.closeConditionalWriter(cwid);
- try {
- client.updateRowsConditionally(cwid, updates);
- fail("conditional writer not closed");
- } catch (UnknownWriter uk) {}
+ updates.clear();
+ updates.put(s2bb("00348"), new ConditionalUpdates(Arrays.asList(new Condition(new Column(s2bb("data"), s2bb("c"), s2bb("A"))).setValue(s2bb("1"))),
+ Arrays.asList(newColUpdate("data", "seq", "2"), newColUpdate("data", "c", "2").setColVisibility(s2bb("A")))));
- client.dropLocalUser(creds, "cwuser");
+ results = client.updateRowsConditionally(cwid, updates);
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
+
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ client = origClient;
+ }
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}, {"00348", "data", "seq", "2"}}, table);
+
+ if (isKerberosEnabled()) {
+ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
+ client = cwuserProxyClient.proxy();
+ }
+
+ client.closeConditionalWriter(cwid);
+ try {
+ client.updateRowsConditionally(cwid, updates);
+ fail("conditional writer not closed");
+ } catch (UnknownWriter uk) {}
+ } finally {
+ if (isKerberosEnabled()) {
+ // Close the other client
+ if (null != cwuserProxyClient) {
+ cwuserProxyClient.close();
+ }
+
+ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
+ // Re-login and restore the original client
+ client = origClient;
+ }
+ client.dropLocalUser(creds, principal);
+ }
}
private void checkKey(String row, String cf, String cq, String val, KeyValue keyValue) {
[6/7] accumulo git commit: Merge branch '1.7'
Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/0b7d8eea/test/src/test/java/org/apache/accumulo/test/proxy/SimpleProxyBase.java
----------------------------------------------------------------------
diff --cc test/src/test/java/org/apache/accumulo/test/proxy/SimpleProxyBase.java
index 8344156,0000000..8359c7f
mode 100644,000000..100644
--- a/test/src/test/java/org/apache/accumulo/test/proxy/SimpleProxyBase.java
+++ b/test/src/test/java/org/apache/accumulo/test/proxy/SimpleProxyBase.java
@@@ -1,1962 -1,0 +1,2273 @@@
+/*
+ * 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.accumulo.test.proxy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
++import java.net.InetAddress;
+import java.nio.ByteBuffer;
- import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+
++import org.apache.accumulo.cluster.ClusterUser;
++import org.apache.accumulo.core.client.ClientConfiguration;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
++import org.apache.accumulo.core.client.security.tokens.KerberosToken;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.accumulo.core.conf.DefaultConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.file.FileOperations;
+import org.apache.accumulo.core.file.FileSKVWriter;
+import org.apache.accumulo.core.iterators.DevNull;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.iterators.user.SummingCombiner;
+import org.apache.accumulo.core.iterators.user.VersioningIterator;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.ByteBufferUtil;
+import org.apache.accumulo.core.util.UtilWaitThread;
+import org.apache.accumulo.examples.simple.constraints.NumericValueConstraint;
++import org.apache.accumulo.harness.MiniClusterHarness;
+import org.apache.accumulo.harness.SharedMiniClusterIT;
++import org.apache.accumulo.harness.TestingKdc;
+import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl;
+import org.apache.accumulo.proxy.Proxy;
+import org.apache.accumulo.proxy.thrift.AccumuloProxy.Client;
+import org.apache.accumulo.proxy.thrift.AccumuloSecurityException;
+import org.apache.accumulo.proxy.thrift.ActiveCompaction;
+import org.apache.accumulo.proxy.thrift.ActiveScan;
+import org.apache.accumulo.proxy.thrift.BatchScanOptions;
+import org.apache.accumulo.proxy.thrift.Column;
+import org.apache.accumulo.proxy.thrift.ColumnUpdate;
+import org.apache.accumulo.proxy.thrift.CompactionReason;
+import org.apache.accumulo.proxy.thrift.CompactionStrategyConfig;
+import org.apache.accumulo.proxy.thrift.CompactionType;
+import org.apache.accumulo.proxy.thrift.Condition;
+import org.apache.accumulo.proxy.thrift.ConditionalStatus;
+import org.apache.accumulo.proxy.thrift.ConditionalUpdates;
+import org.apache.accumulo.proxy.thrift.ConditionalWriterOptions;
+import org.apache.accumulo.proxy.thrift.DiskUsage;
+import org.apache.accumulo.proxy.thrift.IteratorScope;
+import org.apache.accumulo.proxy.thrift.IteratorSetting;
+import org.apache.accumulo.proxy.thrift.Key;
+import org.apache.accumulo.proxy.thrift.KeyValue;
+import org.apache.accumulo.proxy.thrift.MutationsRejectedException;
+import org.apache.accumulo.proxy.thrift.PartialKey;
+import org.apache.accumulo.proxy.thrift.Range;
+import org.apache.accumulo.proxy.thrift.ScanColumn;
+import org.apache.accumulo.proxy.thrift.ScanOptions;
+import org.apache.accumulo.proxy.thrift.ScanResult;
+import org.apache.accumulo.proxy.thrift.ScanState;
+import org.apache.accumulo.proxy.thrift.ScanType;
+import org.apache.accumulo.proxy.thrift.SystemPermission;
+import org.apache.accumulo.proxy.thrift.TableExistsException;
+import org.apache.accumulo.proxy.thrift.TableNotFoundException;
+import org.apache.accumulo.proxy.thrift.TablePermission;
+import org.apache.accumulo.proxy.thrift.TimeType;
+import org.apache.accumulo.proxy.thrift.UnknownScanner;
+import org.apache.accumulo.proxy.thrift.UnknownWriter;
+import org.apache.accumulo.proxy.thrift.WriterOptions;
+import org.apache.accumulo.server.util.PortUtils;
+import org.apache.accumulo.test.functional.SlowIterator;
++import org.apache.hadoop.conf.Configuration;
++import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.Text;
++import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.thrift.TApplicationException;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TProtocolFactory;
+import org.apache.thrift.server.TServer;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Iterators;
+import com.google.common.net.HostAndPort;
+
+/**
+ * Call every method on the proxy and try to verify that it works.
+ */
+public abstract class SimpleProxyBase extends SharedMiniClusterIT {
+ private static final Logger log = LoggerFactory.getLogger(SimpleProxyBase.class);
+
+ @Override
+ protected int defaultTimeoutSeconds() {
+ return 60;
+ }
+
+ private static final long ZOOKEEPER_PROPAGATION_TIME = 10 * 1000;
+ private static TServer proxyServer;
+ private static int proxyPort;
+
+ private TestProxyClient proxyClient;
+ private org.apache.accumulo.proxy.thrift.AccumuloProxy.Client client;
+
+ private static Map<String,String> properties = new HashMap<>();
+ private static ByteBuffer creds = null;
++ private static String hostname, proxyPrincipal, proxyPrimary, clientPrincipal;
++ private static File proxyKeytab, clientKeytab;
+
+ // Implementations can set this
+ static TProtocolFactory factory = null;
+
+ private static void waitForAccumulo(Connector c) throws Exception {
+ Iterators.size(c.createScanner(MetadataTable.NAME, Authorizations.EMPTY).iterator());
+ }
+
++ private static boolean isKerberosEnabled() {
++ return SharedMiniClusterIT.TRUE.equals(System.getProperty(MiniClusterHarness.USE_KERBEROS_FOR_IT_OPTION));
++ }
++
+ /**
+ * Does the actual test setup, invoked by the concrete test class
+ */
+ public static void setUpProxy() throws Exception {
+ assertNotNull("Implementations must initialize the TProtocolFactory", factory);
+
+ Connector c = SharedMiniClusterIT.getConnector();
+ Instance inst = c.getInstance();
+ waitForAccumulo(c);
+
++ hostname = InetAddress.getLocalHost().getCanonicalHostName();
++
+ Properties props = new Properties();
+ props.put("instance", inst.getInstanceName());
+ props.put("zookeepers", inst.getZooKeepers());
- props.put("tokenClass", PasswordToken.class.getName());
- // Avoid issues with locally installed client configuration files with custom properties
- File emptyFile = Files.createTempFile(null, null).toFile();
- emptyFile.deleteOnExit();
- props.put("clientConfigurationFile", emptyFile.toString());
+
- properties.put("password", SharedMiniClusterIT.getRootPassword());
- properties.put("clientConfigurationFile", emptyFile.toString());
++ final String tokenClass;
++ if (isKerberosEnabled()) {
++ tokenClass = KerberosToken.class.getName();
++ TestingKdc kdc = getKdc();
++
++ // Create a principal+keytab for the proxy
++ proxyKeytab = new File(kdc.getKeytabDir(), "proxy.keytab");
++ hostname = InetAddress.getLocalHost().getCanonicalHostName();
++ // Set the primary because the client needs to know it
++ proxyPrimary = "proxy";
++ // Qualify with an instance
++ proxyPrincipal = proxyPrimary + "/" + hostname;
++ kdc.createPrincipal(proxyKeytab, proxyPrincipal);
++ // Tack on the realm too
++ proxyPrincipal = kdc.qualifyUser(proxyPrincipal);
++
++ props.setProperty("kerberosPrincipal", proxyPrincipal);
++ props.setProperty("kerberosKeytab", proxyKeytab.getCanonicalPath());
++ props.setProperty("thriftServerType", "sasl");
++
++ // Enabled kerberos auth
++ Configuration conf = new Configuration(false);
++ conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
++ UserGroupInformation.setConfiguration(conf);
++
++ // Login for the Proxy itself
++ UserGroupInformation.loginUserFromKeytab(proxyPrincipal, proxyKeytab.getAbsolutePath());
++
++ // User for tests
++ ClusterUser user = kdc.getRootUser();
++ clientPrincipal = user.getPrincipal();
++ clientKeytab = user.getKeytab();
++ } else {
++ clientPrincipal = "root";
++ tokenClass = PasswordToken.class.getName();
++ properties.put("password", SharedMiniClusterIT.getRootPassword());
++ hostname = "localhost";
++ }
++
++ props.put("tokenClass", tokenClass);
++
++ ClientConfiguration clientConfig = SharedMiniClusterIT.getCluster().getClientConfig();
++ String clientConfPath = new File(SharedMiniClusterIT.getCluster().getConfig().getConfDir(), "client.conf").getAbsolutePath();
++ props.put("clientConfigurationFile", clientConfPath);
++ properties.put("clientConfigurationFile", clientConfPath);
+
+ proxyPort = PortUtils.getRandomFreePort();
- proxyServer = Proxy.createProxyServer(HostAndPort.fromParts("localhost", proxyPort), factory, props).server;
++ proxyServer = Proxy.createProxyServer(HostAndPort.fromParts(hostname, proxyPort), factory, props, clientConfig).server;
+ while (!proxyServer.isServing())
+ UtilWaitThread.sleep(100);
+ }
+
+ @AfterClass
+ public static void tearDownProxy() throws Exception {
+ if (null != proxyServer) {
+ proxyServer.stop();
+ }
+ }
+
+ final IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "200"));
+ String table;
+ ByteBuffer badLogin;
+
+ @Before
+ public void setup() throws Exception {
+ // Create a new client for each test
- proxyClient = new TestProxyClient("localhost", proxyPort, factory);
- client = proxyClient.proxy();
- creds = client.login("root", properties);
++ if (isKerberosEnabled()) {
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ proxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
++ client = proxyClient.proxy();
++ creds = client.login(clientPrincipal, properties);
++
++ TestingKdc kdc = getKdc();
++ final ClusterUser user = kdc.getClientPrincipal(0);
++ // Create another user
++ client.createLocalUser(creds, user.getPrincipal(), s2bb("unused"));
++ // Login in as that user we just created
++ UserGroupInformation.loginUserFromKeytab(user.getPrincipal(), user.getKeytab().getAbsolutePath());
++ final UserGroupInformation badUgi = UserGroupInformation.getCurrentUser();
++ // Get a "Credentials" object for the proxy
++ TestProxyClient badClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, badUgi);
++ try {
++ Client badProxy = badClient.proxy();
++ badLogin = badProxy.login(user.getPrincipal(), properties);
++ } finally {
++ badClient.close();
++ }
+
- // Create 'user'
- client.createLocalUser(creds, "user", s2bb(SharedMiniClusterIT.getRootPassword()));
- // Log in as 'user'
- badLogin = client.login("user", properties);
- // Drop 'user', invalidating the credentials
- client.dropLocalUser(creds, "user");
++ // Log back in as the test user
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ // Drop test user, invalidating the credentials (not to mention not having the krb credentials anymore)
++ client.dropLocalUser(creds, user.getPrincipal());
++ } else {
++ proxyClient = new TestProxyClient(hostname, proxyPort, factory);
++ client = proxyClient.proxy();
++ creds = client.login("root", properties);
++
++ // Create 'user'
++ client.createLocalUser(creds, "user", s2bb(SharedMiniClusterIT.getRootPassword()));
++ // Log in as 'user'
++ badLogin = client.login("user", properties);
++ // Drop 'user', invalidating the credentials
++ client.dropLocalUser(creds, "user");
++ }
+
+ // Create a general table to be used
+ table = getUniqueNames(1)[0];
+ client.createTable(creds, table, true, TimeType.MILLIS);
+ }
+
+ @After
+ public void teardown() throws Exception {
+ if (null != table) {
++ if (isKerberosEnabled()) {
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ }
+ try {
+ if (client.tableExists(creds, table)) {
+ client.deleteTable(creds, table);
+ }
+ } catch (Exception e) {
+ log.warn("Failed to delete test table", e);
+ }
+ }
+
+ // Close the transport after the test
+ if (null != proxyClient) {
+ proxyClient.close();
+ }
+ }
+
+ /*
+ * Set a lower timeout for tests that should fail fast
+ */
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void addConstraintLoginFailure() throws Exception {
+ client.addConstraint(badLogin, table, NumericValueConstraint.class.getName());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void addSplitsLoginFailure() throws Exception {
+ client.addSplits(badLogin, table, Collections.singleton(s2bb("1")));
+ }
+
+ @Test(expected = TApplicationException.class, timeout = 5000)
+ public void clearLocatorCacheLoginFailure() throws Exception {
+ client.clearLocatorCache(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void compactTableLoginFailure() throws Exception {
+ client.compactTable(badLogin, table, null, null, null, true, false, null);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void cancelCompactionLoginFailure() throws Exception {
+ client.cancelCompaction(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void createTableLoginFailure() throws Exception {
+ client.createTable(badLogin, table, false, TimeType.MILLIS);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void deleteTableLoginFailure() throws Exception {
+ client.deleteTable(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void deleteRowsLoginFailure() throws Exception {
+ client.deleteRows(badLogin, table, null, null);
+ }
+
+ @Test(expected = TApplicationException.class, timeout = 5000)
+ public void tableExistsLoginFailure() throws Exception {
+ client.tableExists(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void flustTableLoginFailure() throws Exception {
+ client.flushTable(badLogin, table, null, null, false);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getLocalityGroupsLoginFailure() throws Exception {
+ client.getLocalityGroups(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getMaxRowLoginFailure() throws Exception {
+ client.getMaxRow(badLogin, table, Collections.<ByteBuffer> emptySet(), null, false, null, false);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getTablePropertiesLoginFailure() throws Exception {
+ client.getTableProperties(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void listSplitsLoginFailure() throws Exception {
+ client.listSplits(badLogin, table, 10000);
+ }
+
+ @Test(expected = TApplicationException.class, timeout = 5000)
+ public void listTablesLoginFailure() throws Exception {
+ client.listTables(badLogin);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void listConstraintsLoginFailure() throws Exception {
+ client.listConstraints(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void mergeTabletsLoginFailure() throws Exception {
+ client.mergeTablets(badLogin, table, null, null);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void offlineTableLoginFailure() throws Exception {
+ client.offlineTable(badLogin, table, false);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void onlineTableLoginFailure() throws Exception {
+ client.onlineTable(badLogin, table, false);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void removeConstraintLoginFailure() throws Exception {
+ client.removeConstraint(badLogin, table, 0);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void removeTablePropertyLoginFailure() throws Exception {
+ client.removeTableProperty(badLogin, table, Property.TABLE_FILE_MAX.getKey());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void renameTableLoginFailure() throws Exception {
+ client.renameTable(badLogin, table, "someTableName");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void setLocalityGroupsLoginFailure() throws Exception {
+ Map<String,Set<String>> groups = new HashMap<String,Set<String>>();
+ groups.put("group1", Collections.singleton("cf1"));
+ groups.put("group2", Collections.singleton("cf2"));
+ client.setLocalityGroups(badLogin, table, groups);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void setTablePropertyLoginFailure() throws Exception {
+ client.setTableProperty(badLogin, table, Property.TABLE_FILE_MAX.getKey(), "0");
+ }
+
+ @Test(expected = TException.class, timeout = 5000)
+ public void tableIdMapLoginFailure() throws Exception {
+ client.tableIdMap(badLogin);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getSiteConfigurationLoginFailure() throws Exception {
+ client.getSiteConfiguration(badLogin);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getSystemConfigurationLoginFailure() throws Exception {
+ client.getSystemConfiguration(badLogin);
+ }
+
+ @Test(expected = TException.class, timeout = 5000)
+ public void getTabletServersLoginFailure() throws Exception {
+ client.getTabletServers(badLogin);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getActiveScansLoginFailure() throws Exception {
+ client.getActiveScans(badLogin, "fake");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getActiveCompactionsLoginFailure() throws Exception {
+ client.getActiveCompactions(badLogin, "fakse");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void removePropertyLoginFailure() throws Exception {
+ client.removeProperty(badLogin, "table.split.threshold");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void setPropertyLoginFailure() throws Exception {
+ client.setProperty(badLogin, "table.split.threshold", "500M");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void testClassLoadLoginFailure() throws Exception {
+ client.testClassLoad(badLogin, DevNull.class.getName(), SortedKeyValueIterator.class.getName());
+ }
+
- @Test(expected = AccumuloSecurityException.class, timeout = 5000)
++ @Test(timeout = 5000)
+ public void authenticateUserLoginFailure() throws Exception {
- client.authenticateUser(badLogin, "root", s2pp(SharedMiniClusterIT.getRootPassword()));
++ if (!isKerberosEnabled()) {
++ try {
++ // Not really a relevant test for kerberos
++ client.authenticateUser(badLogin, "root", s2pp(SharedMiniClusterIT.getRootPassword()));
++ fail("Expected AccumuloSecurityException");
++ } catch (AccumuloSecurityException e) {
++ // Expected
++ return;
++ }
++ }
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void changeUserAuthorizationsLoginFailure() throws Exception {
+ HashSet<ByteBuffer> auths = new HashSet<ByteBuffer>(Arrays.asList(s2bb("A"), s2bb("B")));
+ client.changeUserAuthorizations(badLogin, "stooge", auths);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void changePasswordLoginFailure() throws Exception {
+ client.changeLocalUserPassword(badLogin, "stooge", s2bb(""));
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void createUserLoginFailure() throws Exception {
+ client.createLocalUser(badLogin, "stooge", s2bb("password"));
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void dropUserLoginFailure() throws Exception {
+ client.dropLocalUser(badLogin, "stooge");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getUserAuthorizationsLoginFailure() throws Exception {
+ client.getUserAuthorizations(badLogin, "stooge");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void grantSystemPermissionLoginFailure() throws Exception {
+ client.grantSystemPermission(badLogin, "stooge", SystemPermission.CREATE_TABLE);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void grantTablePermissionLoginFailure() throws Exception {
+ client.grantTablePermission(badLogin, "root", table, TablePermission.WRITE);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void hasSystemPermissionLoginFailure() throws Exception {
+ client.hasSystemPermission(badLogin, "stooge", SystemPermission.CREATE_TABLE);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void hasTablePermission() throws Exception {
+ client.hasTablePermission(badLogin, "root", table, TablePermission.WRITE);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void listLocalUsersLoginFailure() throws Exception {
+ client.listLocalUsers(badLogin);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void revokeSystemPermissionLoginFailure() throws Exception {
+ client.revokeSystemPermission(badLogin, "stooge", SystemPermission.CREATE_TABLE);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void revokeTablePermissionLoginFailure() throws Exception {
+ client.revokeTablePermission(badLogin, "root", table, TablePermission.ALTER_TABLE);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void createScannerLoginFailure() throws Exception {
+ client.createScanner(badLogin, table, new ScanOptions());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void createBatchScannerLoginFailure() throws Exception {
+ client.createBatchScanner(badLogin, table, new BatchScanOptions());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void updateAndFlushLoginFailure() throws Exception {
+ client.updateAndFlush(badLogin, table, new HashMap<ByteBuffer,List<ColumnUpdate>>());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void createWriterLoginFailure() throws Exception {
+ client.createWriter(badLogin, table, new WriterOptions());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void attachIteratorLoginFailure() throws Exception {
+ client.attachIterator(badLogin, "slow", setting, EnumSet.allOf(IteratorScope.class));
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void checkIteratorLoginFailure() throws Exception {
+ client.checkIteratorConflicts(badLogin, table, setting, EnumSet.allOf(IteratorScope.class));
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void cloneTableLoginFailure() throws Exception {
+ client.cloneTable(badLogin, table, table + "_clone", false, null, null);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void exportTableLoginFailure() throws Exception {
+ client.exportTable(badLogin, table, "/tmp");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void importTableLoginFailure() throws Exception {
+ client.importTable(badLogin, "testify", "/tmp");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void getIteratorSettingLoginFailure() throws Exception {
+ client.getIteratorSetting(badLogin, table, "foo", IteratorScope.SCAN);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void listIteratorsLoginFailure() throws Exception {
+ client.listIterators(badLogin, table);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void removeIteratorLoginFailure() throws Exception {
+ client.removeIterator(badLogin, table, "name", EnumSet.allOf(IteratorScope.class));
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void splitRangeByTabletsLoginFailure() throws Exception {
+ client.splitRangeByTablets(badLogin, table, client.getRowRange(ByteBuffer.wrap("row".getBytes())), 10);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void importDirectoryLoginFailure() throws Exception {
+ MiniAccumuloClusterImpl cluster = SharedMiniClusterIT.getCluster();
+ Path base = cluster.getTemporaryPath();
+ Path importDir = new Path(base, "importDir");
+ Path failuresDir = new Path(base, "failuresDir");
+ assertTrue(cluster.getFileSystem().mkdirs(importDir));
+ assertTrue(cluster.getFileSystem().mkdirs(failuresDir));
+ client.importDirectory(badLogin, table, importDir.toString(), failuresDir.toString(), true);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void pingTabletServerLoginFailure() throws Exception {
+ client.pingTabletServer(badLogin, "fake");
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void loginFailure() throws Exception {
+ client.login("badUser", properties);
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void testTableClassLoadLoginFailure() throws Exception {
+ client.testTableClassLoad(badLogin, table, VersioningIterator.class.getName(), SortedKeyValueIterator.class.getName());
+ }
+
+ @Test(expected = AccumuloSecurityException.class, timeout = 5000)
+ public void createConditionalWriterLoginFailure() throws Exception {
+ client.createConditionalWriter(badLogin, table, new ConditionalWriterOptions());
+ }
+
+ @Test
+ public void tableNotFound() throws Exception {
+ final String doesNotExist = "doesNotExists";
+ try {
+ client.addConstraint(creds, doesNotExist, NumericValueConstraint.class.getName());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.addSplits(creds, doesNotExist, Collections.<ByteBuffer> emptySet());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ final IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "200"));
+ try {
+ client.attachIterator(creds, doesNotExist, setting, EnumSet.allOf(IteratorScope.class));
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.cancelCompaction(creds, doesNotExist);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.checkIteratorConflicts(creds, doesNotExist, setting, EnumSet.allOf(IteratorScope.class));
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.clearLocatorCache(creds, doesNotExist);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ final String TABLE_TEST = getUniqueNames(1)[0];
+ client.cloneTable(creds, doesNotExist, TABLE_TEST, false, null, null);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.compactTable(creds, doesNotExist, null, null, null, true, false, null);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.createBatchScanner(creds, doesNotExist, new BatchScanOptions());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.createScanner(creds, doesNotExist, new ScanOptions());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.createWriter(creds, doesNotExist, new WriterOptions());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.deleteRows(creds, doesNotExist, null, null);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.deleteTable(creds, doesNotExist);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.exportTable(creds, doesNotExist, "/tmp");
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.flushTable(creds, doesNotExist, null, null, false);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.getIteratorSetting(creds, doesNotExist, "foo", IteratorScope.SCAN);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.getLocalityGroups(creds, doesNotExist);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.getMaxRow(creds, doesNotExist, Collections.<ByteBuffer> emptySet(), null, false, null, false);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.getTableProperties(creds, doesNotExist);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.grantTablePermission(creds, "root", doesNotExist, TablePermission.WRITE);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.hasTablePermission(creds, "root", doesNotExist, TablePermission.WRITE);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ MiniAccumuloClusterImpl cluster = SharedMiniClusterIT.getCluster();
+ Path base = cluster.getTemporaryPath();
+ Path importDir = new Path(base, "importDir");
+ Path failuresDir = new Path(base, "failuresDir");
+ assertTrue(cluster.getFileSystem().mkdirs(importDir));
+ assertTrue(cluster.getFileSystem().mkdirs(failuresDir));
+ client.importDirectory(creds, doesNotExist, importDir.toString(), failuresDir.toString(), true);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.listConstraints(creds, doesNotExist);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.listSplits(creds, doesNotExist, 10000);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.mergeTablets(creds, doesNotExist, null, null);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.offlineTable(creds, doesNotExist, false);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.onlineTable(creds, doesNotExist, false);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.removeConstraint(creds, doesNotExist, 0);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.removeIterator(creds, doesNotExist, "name", EnumSet.allOf(IteratorScope.class));
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.removeTableProperty(creds, doesNotExist, Property.TABLE_FILE_MAX.getKey());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.renameTable(creds, doesNotExist, "someTableName");
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.revokeTablePermission(creds, "root", doesNotExist, TablePermission.ALTER_TABLE);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.setTableProperty(creds, doesNotExist, Property.TABLE_FILE_MAX.getKey(), "0");
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.splitRangeByTablets(creds, doesNotExist, client.getRowRange(ByteBuffer.wrap("row".getBytes())), 10);
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.updateAndFlush(creds, doesNotExist, new HashMap<ByteBuffer,List<ColumnUpdate>>());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.getDiskUsage(creds, Collections.singleton(doesNotExist));
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.testTableClassLoad(creds, doesNotExist, VersioningIterator.class.getName(), SortedKeyValueIterator.class.getName());
+ fail("exception not thrown");
+ } catch (TableNotFoundException ex) {}
+ try {
+ client.createConditionalWriter(creds, doesNotExist, new ConditionalWriterOptions());
+ } catch (TableNotFoundException ex) {}
+ }
+
+ @Test
+ public void testExists() throws Exception {
+ client.createTable(creds, "ett1", false, TimeType.MILLIS);
+ client.createTable(creds, "ett2", false, TimeType.MILLIS);
+ try {
+ client.createTable(creds, "ett1", false, TimeType.MILLIS);
+ fail("exception not thrown");
+ } catch (TableExistsException tee) {}
+ try {
+ client.renameTable(creds, "ett1", "ett2");
+ fail("exception not thrown");
+ } catch (TableExistsException tee) {}
+ try {
+ client.cloneTable(creds, "ett1", "ett2", false, new HashMap<String,String>(), new HashSet<String>());
+ fail("exception not thrown");
+ } catch (TableExistsException tee) {}
+ }
+
+ @Test
+ public void testUnknownScanner() throws Exception {
+ String scanner = client.createScanner(creds, table, null);
+ assertFalse(client.hasNext(scanner));
+ client.closeScanner(scanner);
+
+ try {
+ client.hasNext(scanner);
+ fail("exception not thrown");
+ } catch (UnknownScanner us) {}
+
+ try {
+ client.closeScanner(scanner);
+ fail("exception not thrown");
+ } catch (UnknownScanner us) {}
+
+ try {
+ client.nextEntry("99999999");
+ fail("exception not thrown");
+ } catch (UnknownScanner us) {}
+ try {
+ client.nextK("99999999", 6);
+ fail("exception not thrown");
+ } catch (UnknownScanner us) {}
+ try {
+ client.hasNext("99999999");
+ fail("exception not thrown");
+ } catch (UnknownScanner us) {}
+ try {
+ client.hasNext(UUID.randomUUID().toString());
+ fail("exception not thrown");
+ } catch (UnknownScanner us) {}
+ }
+
+ @Test
+ public void testUnknownWriter() throws Exception {
+ String writer = client.createWriter(creds, table, null);
+ client.update(writer, mutation("row0", "cf", "cq", "value"));
+ client.flush(writer);
+ client.update(writer, mutation("row2", "cf", "cq", "value2"));
+ client.closeWriter(writer);
+
+ // this is a oneway call, so it does not throw exceptions
+ client.update(writer, mutation("row2", "cf", "cq", "value2"));
+
+ try {
+ client.flush(writer);
+ fail("exception not thrown");
+ } catch (UnknownWriter uw) {}
+ try {
+ client.flush("99999");
+ fail("exception not thrown");
+ } catch (UnknownWriter uw) {}
+ try {
+ client.flush(UUID.randomUUID().toString());
+ fail("exception not thrown");
+ } catch (UnknownWriter uw) {}
+ try {
+ client.closeWriter("99999");
+ fail("exception not thrown");
+ } catch (UnknownWriter uw) {}
+ }
+
+ @Test
+ public void testDelete() throws Exception {
+ client.updateAndFlush(creds, table, mutation("row0", "cf", "cq", "value"));
+
+ assertScan(new String[][] {{"row0", "cf", "cq", "value"}}, table);
+
+ ColumnUpdate upd = new ColumnUpdate(s2bb("cf"), s2bb("cq"));
+ upd.setDeleteCell(false);
+ Map<ByteBuffer,List<ColumnUpdate>> notDelete = Collections.singletonMap(s2bb("row0"), Collections.singletonList(upd));
+ client.updateAndFlush(creds, table, notDelete);
+ String scanner = client.createScanner(creds, table, null);
+ ScanResult entries = client.nextK(scanner, 10);
+ client.closeScanner(scanner);
+ assertFalse(entries.more);
+ assertEquals("Results: " + entries.results, 1, entries.results.size());
+
+ upd = new ColumnUpdate(s2bb("cf"), s2bb("cq"));
+ upd.setDeleteCell(true);
+ Map<ByteBuffer,List<ColumnUpdate>> delete = Collections.singletonMap(s2bb("row0"), Collections.singletonList(upd));
+
+ client.updateAndFlush(creds, table, delete);
+
+ assertScan(new String[][] {}, table);
+ }
+
+ @Test
+ public void testSystemProperties() throws Exception {
+ Map<String,String> cfg = client.getSiteConfiguration(creds);
+
+ // set a property in zookeeper
+ client.setProperty(creds, "table.split.threshold", "500M");
+
+ // check that we can read it
+ for (int i = 0; i < 5; i++) {
+ cfg = client.getSystemConfiguration(creds);
+ if ("500M".equals(cfg.get("table.split.threshold")))
+ break;
+ UtilWaitThread.sleep(200);
+ }
+ assertEquals("500M", cfg.get("table.split.threshold"));
+
+ // unset the setting, check that it's not what it was
+ client.removeProperty(creds, "table.split.threshold");
+ for (int i = 0; i < 5; i++) {
+ cfg = client.getSystemConfiguration(creds);
+ if (!"500M".equals(cfg.get("table.split.threshold")))
+ break;
+ UtilWaitThread.sleep(200);
+ }
+ assertNotEquals("500M", cfg.get("table.split.threshold"));
+ }
+
+ @Test
+ public void pingTabletServers() throws Exception {
+ int tservers = 0;
+ for (String tserver : client.getTabletServers(creds)) {
+ client.pingTabletServer(creds, tserver);
+ tservers++;
+ }
+ assertTrue(tservers > 0);
+ }
+
+ @Test
+ public void testSiteConfiguration() throws Exception {
+ // get something we know is in the site config
+ MiniAccumuloClusterImpl cluster = SharedMiniClusterIT.getCluster();
+ Map<String,String> cfg = client.getSiteConfiguration(creds);
+ assertTrue(cfg.get("instance.dfs.dir").startsWith(cluster.getConfig().getAccumuloDir().getAbsolutePath()));
+ }
+
+ @Test
+ public void testClassLoad() throws Exception {
+ // try to load some classes via the proxy
+ assertTrue(client.testClassLoad(creds, DevNull.class.getName(), SortedKeyValueIterator.class.getName()));
+ assertFalse(client.testClassLoad(creds, "foo.bar", SortedKeyValueIterator.class.getName()));
+ }
+
+ @Test
+ public void attachIteratorsWithScans() throws Exception {
+ if (client.tableExists(creds, "slow")) {
+ client.deleteTable(creds, "slow");
+ }
+
+ // create a table that's very slow, so we can look for scans
+ client.createTable(creds, "slow", true, TimeType.MILLIS);
+ IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "250"));
+ client.attachIterator(creds, "slow", setting, EnumSet.allOf(IteratorScope.class));
+
+ // Should take 10 seconds to read every record
+ for (int i = 0; i < 40; i++) {
+ client.updateAndFlush(creds, "slow", mutation("row" + i, "cf", "cq", "value"));
+ }
+
+ // scan
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ String scanner;
++ TestProxyClient proxyClient2 = null;
+ try {
- Client client2 = new TestProxyClient("localhost", proxyPort, factory).proxy();
++ if (isKerberosEnabled()) {
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
++ } else {
++ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
++ }
++
++ Client client2 = proxyClient2.proxy();
+ scanner = client2.createScanner(creds, "slow", null);
+ client2.nextK(scanner, 10);
+ client2.closeScanner(scanner);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
++ } finally {
++ if (null != proxyClient2) {
++ proxyClient2.close();
++ }
+ }
+ }
+ };
+ t.start();
+
+ // look for the scan many times
+ List<ActiveScan> scans = new ArrayList<ActiveScan>();
+ for (int i = 0; i < 100 && scans.isEmpty(); i++) {
+ for (String tserver : client.getTabletServers(creds)) {
+ List<ActiveScan> scansForServer = client.getActiveScans(creds, tserver);
+ for (ActiveScan scan : scansForServer) {
- if ("root".equals(scan.getUser())) {
++ if (clientPrincipal.equals(scan.getUser())) {
+ scans.add(scan);
+ }
+ }
+
+ if (!scans.isEmpty())
+ break;
+ UtilWaitThread.sleep(100);
+ }
+ }
+ t.join();
+
- assertFalse(scans.isEmpty());
++ assertFalse("Expected to find scans, but found none", scans.isEmpty());
+ boolean found = false;
+ Map<String,String> map = null;
+ for (int i = 0; i < scans.size() && !found; i++) {
+ ActiveScan scan = scans.get(i);
- if ("root".equals(scan.getUser())) {
++ if (clientPrincipal.equals(scan.getUser())) {
+ assertTrue(ScanState.RUNNING.equals(scan.getState()) || ScanState.QUEUED.equals(scan.getState()));
+ assertEquals(ScanType.SINGLE, scan.getType());
+ assertEquals("slow", scan.getTable());
+
+ map = client.tableIdMap(creds);
+ assertEquals(map.get("slow"), scan.getExtent().tableId);
+ assertTrue(scan.getExtent().endRow == null);
+ assertTrue(scan.getExtent().prevEndRow == null);
+ found = true;
+ }
+ }
+
+ assertTrue("Could not find a scan against the 'slow' table", found);
+ }
+
+ @Test
+ public void attachIteratorWithCompactions() throws Exception {
+ if (client.tableExists(creds, "slow")) {
+ client.deleteTable(creds, "slow");
+ }
+
+ // create a table that's very slow, so we can look for compactions
+ client.createTable(creds, "slow", true, TimeType.MILLIS);
+ IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "250"));
+ client.attachIterator(creds, "slow", setting, EnumSet.allOf(IteratorScope.class));
+
+ // Should take 10 seconds to read every record
+ for (int i = 0; i < 40; i++) {
+ client.updateAndFlush(creds, "slow", mutation("row" + i, "cf", "cq", "value"));
+ }
+
+ Map<String,String> map = client.tableIdMap(creds);
+
+ // start a compaction
+ Thread t = new Thread() {
+ @Override
+ public void run() {
++ TestProxyClient proxyClient2 = null;
+ try {
- Client client2 = new TestProxyClient("localhost", proxyPort, factory).proxy();
++ if (isKerberosEnabled()) {
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, UserGroupInformation.getCurrentUser());
++ } else {
++ proxyClient2 = new TestProxyClient(hostname, proxyPort, factory);
++ }
++ Client client2 = proxyClient2.proxy();
+ client2.compactTable(creds, "slow", null, null, null, true, true, null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
++ } finally {
++ if (null != proxyClient2) {
++ proxyClient2.close();
++ }
+ }
+ }
+ };
+ t.start();
+
+ final String desiredTableId = map.get("slow");
+
+ // Make sure we can find the slow table
+ assertNotNull(desiredTableId);
+
+ // try to catch it in the act
+ List<ActiveCompaction> compactions = new ArrayList<ActiveCompaction>();
+ for (int i = 0; i < 100 && compactions.isEmpty(); i++) {
+ // Iterate over the tservers
+ for (String tserver : client.getTabletServers(creds)) {
+ // And get the compactions on each
+ List<ActiveCompaction> compactionsOnServer = client.getActiveCompactions(creds, tserver);
+ for (ActiveCompaction compact : compactionsOnServer) {
+ // There might be other compactions occurring (e.g. on METADATA) in which
+ // case we want to prune out those that aren't for our slow table
+ if (desiredTableId.equals(compact.getExtent().tableId)) {
+ compactions.add(compact);
+ }
+ }
+
+ // If we found a compaction for the table we wanted, so we can stop looking
+ if (!compactions.isEmpty())
+ break;
+ }
+ UtilWaitThread.sleep(10);
+ }
+ t.join();
+
+ // verify the compaction information
+ assertFalse(compactions.isEmpty());
+ for (ActiveCompaction c : compactions) {
+ if (desiredTableId.equals(c.getExtent().tableId)) {
+ assertTrue(c.inputFiles.isEmpty());
+ assertEquals(CompactionType.MINOR, c.getType());
+ assertEquals(CompactionReason.USER, c.getReason());
+ assertEquals("", c.localityGroup);
+ assertTrue(c.outputFile.contains("default_tablet"));
+
+ return;
+ }
+ }
+
+ fail("Expection to find running compaction for table 'slow' but did not find one");
+ }
+
+ @Test
+ public void userAuthentication() throws Exception {
- // check password
- assertTrue(client.authenticateUser(creds, "root", s2pp(SharedMiniClusterIT.getRootPassword())));
- assertFalse(client.authenticateUser(creds, "root", s2pp("")));
++ if (isKerberosEnabled()) {
++ assertTrue(client.authenticateUser(creds, clientPrincipal, Collections.<String,String> emptyMap()));
++ // Can't really authenticate "badly" at the application level w/ kerberos. It's going to fail to even set up an RPC
++ } else {
++ // check password
++ assertTrue(client.authenticateUser(creds, "root", s2pp(SharedMiniClusterIT.getRootPassword())));
++ assertFalse(client.authenticateUser(creds, "root", s2pp("")));
++ }
+ }
+
+ @Test
+ public void userManagement() throws Exception {
- String user = getUniqueNames(1)[0];
++
++ String user;
++ ClusterUser otherClient = null;
++ ByteBuffer password = s2bb("password");
++ if (isKerberosEnabled()) {
++ otherClient = getKdc().getClientPrincipal(1);
++ user = otherClient.getPrincipal();
++ } else {
++ user = getUniqueNames(1)[0];
++ }
++
+ // create a user
- client.createLocalUser(creds, user, s2bb("password"));
++ client.createLocalUser(creds, user, password);
+ // change auths
+ Set<String> users = client.listLocalUsers(creds);
- Set<String> expectedUsers = new HashSet<String>(Arrays.asList("root", user));
++ Set<String> expectedUsers = new HashSet<String>(Arrays.asList(clientPrincipal, user));
+ assertTrue("Did not find all expected users: " + expectedUsers, users.containsAll(expectedUsers));
+ HashSet<ByteBuffer> auths = new HashSet<ByteBuffer>(Arrays.asList(s2bb("A"), s2bb("B")));
+ client.changeUserAuthorizations(creds, user, auths);
+ List<ByteBuffer> update = client.getUserAuthorizations(creds, user);
+ assertEquals(auths, new HashSet<ByteBuffer>(update));
+
+ // change password
- client.changeLocalUserPassword(creds, user, s2bb(""));
- assertTrue(client.authenticateUser(creds, user, s2pp("")));
++ if (!isKerberosEnabled()) {
++ password = s2bb("");
++ client.changeLocalUserPassword(creds, user, password);
++ assertTrue(client.authenticateUser(creds, user, s2pp(password.toString())));
++ }
+
- // check login with new password
- client.login(user, s2pp(""));
++ if (isKerberosEnabled()) {
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
++ // Re-login in and make a new connection. Can't use the previous one
++
++ TestProxyClient otherProxyClient = null;
++ try {
++ otherProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
++ otherProxyClient.proxy().login(user, Collections.<String,String> emptyMap());
++ } finally {
++ if (null != otherProxyClient) {
++ otherProxyClient.close();
++ }
++ }
++ } else {
++ // check login with new password
++ client.login(user, s2pp(password.toString()));
++ }
+ }
+
+ @Test
+ public void userPermissions() throws Exception {
+ String userName = getUniqueNames(1)[0];
- // create a user
- client.createLocalUser(creds, userName, s2bb("password"));
-
- ByteBuffer user = client.login(userName, s2pp("password"));
++ ClusterUser otherClient = null;
++ ByteBuffer password = s2bb("password");
++ ByteBuffer user;
++
++ TestProxyClient origProxyClient = null;
++ Client origClient = null;
++ TestProxyClient userProxyClient = null;
++ Client userClient = null;
++
++ if (isKerberosEnabled()) {
++ otherClient = getKdc().getClientPrincipal(1);
++ userName = otherClient.getPrincipal();
++
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
++ // Re-login in and make a new connection. Can't use the previous one
++
++ userProxyClient = new TestProxyClient(hostname, proxyPort, factory, proxyPrimary, ugi);
++
++ origProxyClient = proxyClient;
++ origClient = client;
++ userClient = client = userProxyClient.proxy();
++
++ user = client.login(userName, Collections.<String,String> emptyMap());
++ } else {
++ userName = getUniqueNames(1)[0];
++ // create a user
++ client.createLocalUser(creds, userName, password);
++ user = client.login(userName, s2pp(password.toString()));
++ }
+
+ // check permission failure
+ try {
+ client.createTable(user, "fail", true, TimeType.MILLIS);
+ fail("should not create the table");
+ } catch (AccumuloSecurityException ex) {
++ if (isKerberosEnabled()) {
++ // Switch back to original client
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ client = origClient;
++ }
+ assertFalse(client.listTables(creds).contains("fail"));
+ }
+ // grant permissions and test
+ assertFalse(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
+ client.grantSystemPermission(creds, userName, SystemPermission.CREATE_TABLE);
+ assertTrue(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
++ if (isKerberosEnabled()) {
++ // Switch back to the extra user
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ client = userClient;
++ }
+ client.createTable(user, "success", true, TimeType.MILLIS);
++ if (isKerberosEnabled()) {
++ // Switch back to original client
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ client = origClient;
++ }
+ client.listTables(creds).contains("succcess");
+
+ // revoke permissions
+ client.revokeSystemPermission(creds, userName, SystemPermission.CREATE_TABLE);
+ assertFalse(client.hasSystemPermission(creds, userName, SystemPermission.CREATE_TABLE));
+ try {
++ if (isKerberosEnabled()) {
++ // Switch back to the extra user
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ client = userClient;
++ }
+ client.createTable(user, "fail", true, TimeType.MILLIS);
+ fail("should not create the table");
+ } catch (AccumuloSecurityException ex) {
++ if (isKerberosEnabled()) {
++ // Switch back to original client
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ client = origClient;
++ }
+ assertFalse(client.listTables(creds).contains("fail"));
+ }
+ // denied!
+ try {
++ if (isKerberosEnabled()) {
++ // Switch back to the extra user
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ client = userClient;
++ }
+ String scanner = client.createScanner(user, table, null);
+ client.nextK(scanner, 100);
+ fail("stooge should not read table test");
+ } catch (AccumuloSecurityException ex) {}
++
++ if (isKerberosEnabled()) {
++ // Switch back to original client
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ client = origClient;
++ }
++
+ // grant
+ assertFalse(client.hasTablePermission(creds, userName, table, TablePermission.READ));
+ client.grantTablePermission(creds, userName, table, TablePermission.READ);
+ assertTrue(client.hasTablePermission(creds, userName, table, TablePermission.READ));
++
++ if (isKerberosEnabled()) {
++ // Switch back to the extra user
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ client = userClient;
++ }
+ String scanner = client.createScanner(user, table, null);
+ client.nextK(scanner, 10);
+ client.closeScanner(scanner);
++
++ if (isKerberosEnabled()) {
++ // Switch back to original client
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ client = origClient;
++ }
++
+ // revoke
+ client.revokeTablePermission(creds, userName, table, TablePermission.READ);
+ assertFalse(client.hasTablePermission(creds, userName, table, TablePermission.READ));
+ try {
++ if (isKerberosEnabled()) {
++ // Switch back to the extra user
++ UserGroupInformation.loginUserFromKeytab(otherClient.getPrincipal(), otherClient.getKeytab().getAbsolutePath());
++ client = userClient;
++ }
+ scanner = client.createScanner(user, table, null);
+ client.nextK(scanner, 100);
+ fail("stooge should not read table test");
+ } catch (AccumuloSecurityException ex) {}
+
++ if (isKerberosEnabled()) {
++ // Switch back to original client
++ UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
++ client = origClient;
++ }
++
+ // delete user
+ client.dropLocalUser(creds, userName);
+ Set<String> users = client.listLocalUsers(creds);
+ assertFalse("Should not see user after they are deleted", users.contains(userName));
++
++ if (isKerberosEnabled()) {
++ userProxyClient.close();
++ proxyClient = origProxyClient;
++ client = origClient;
++ }
+ }
+
+ @Test
+ public void testBatchWriter() throws Exception {
+ client.addConstraint(creds, table, NumericValueConstraint.class.getName());
+ // zookeeper propagation time
+ UtilWaitThread.sleep(ZOOKEEPER_PROPAGATION_TIME);
+
+ WriterOptions writerOptions = new WriterOptions();
+ writerOptions.setLatencyMs(10000);
+ writerOptions.setMaxMemory(2);
+ writerOptions.setThreads(1);
+ writerOptions.setTimeoutMs(100000);
+
+ Map<String,Integer> constraints = client.listConstraints(creds, table);
+ while (!constraints.containsKey(NumericValueConstraint.class.getName())) {
+ log.info("Constraints don't contain NumericValueConstraint");
+ Thread.sleep(2000);
+ constraints = client.listConstraints(creds, table);
+ }
+
+ boolean success = false;
+ for (int i = 0; i < 15; i++) {
+ String batchWriter = client.createWriter(creds, table, writerOptions);
+ client.update(batchWriter, mutation("row1", "cf", "cq", "x"));
+ client.update(batchWriter, mutation("row1", "cf", "cq", "x"));
+ try {
+ client.flush(batchWriter);
+ log.debug("Constraint failed to fire. Waiting and retrying");
+ Thread.sleep(5000);
+ continue;
+ } catch (MutationsRejectedException ex) {}
+ try {
+ client.closeWriter(batchWriter);
+ log.debug("Constraint failed to fire. Waiting and retrying");
+ Thread.sleep(5000);
+ continue;
+ } catch (MutationsRejectedException e) {}
+ success = true;
+ break;
+ }
+
+ if (!success) {
+ fail("constraint did not fire");
+ }
+
+ client.removeConstraint(creds, table, 2);
+
+ constraints = client.listConstraints(creds, table);
+ while (constraints.containsKey(NumericValueConstraint.class.getName())) {
+ log.info("Constraints still contains NumericValueConstraint");
+ Thread.sleep(2000);
+ constraints = client.listConstraints(creds, table);
+ }
+
+ assertScan(new String[][] {}, table);
+
+ UtilWaitThread.sleep(ZOOKEEPER_PROPAGATION_TIME);
+
+ writerOptions = new WriterOptions();
+ writerOptions.setLatencyMs(10000);
+ writerOptions.setMaxMemory(3000);
+ writerOptions.setThreads(1);
+ writerOptions.setTimeoutMs(100000);
+
+ success = false;
+ for (int i = 0; i < 15; i++) {
+ try {
+ String batchWriter = client.createWriter(creds, table, writerOptions);
+
+ client.update(batchWriter, mutation("row1", "cf", "cq", "x"));
+ client.flush(batchWriter);
+ client.closeWriter(batchWriter);
+ success = true;
+ break;
+ } catch (MutationsRejectedException e) {
+ log.info("Mutations were rejected, assuming constraint is still active", e);
+ Thread.sleep(5000);
+ }
+ }
+
+ if (!success) {
+ fail("Failed to successfully write data after constraint was removed");
+ }
+
+ assertScan(new String[][] {{"row1", "cf", "cq", "x"}}, table);
+
+ client.deleteTable(creds, table);
+ }
+
+ @Test
+ public void testTableConstraints() throws Exception {
+ log.debug("Setting NumericValueConstraint on " + table);
+
+ // constraints
+ client.addConstraint(creds, table, NumericValueConstraint.class.getName());
+
+ // zookeeper propagation time
+ Thread.sleep(ZOOKEEPER_PROPAGATION_TIME);
+
+ log.debug("Attempting to verify client-side that constraints are observed");
+
+ Map<String,Integer> constraints = client.listConstraints(creds, table);
+ while (!constraints.containsKey(NumericValueConstraint.class.getName())) {
+ log.debug("Constraints don't contain NumericValueConstraint");
+ Thread.sleep(2000);
+ constraints = client.listConstraints(creds, table);
+ }
+
+ assertEquals(2, client.listConstraints(creds, table).size());
+ log.debug("Verified client-side that constraints exist");
+
+ // Write data that satisfies the constraint
+ client.updateAndFlush(creds, table, mutation("row1", "cf", "cq", "123"));
+
+ log.debug("Successfully wrote data that satisfies the constraint");
+ log.debug("Trying to write data that the constraint should reject");
+
+ // Expect failure on data that fails the constraint
+ while (true) {
+ try {
+ client.updateAndFlush(creds, table, mutation("row1", "cf", "cq", "x"));
+ log.debug("Expected mutation to be rejected, but was not. Waiting and retrying");
+ Thread.sleep(5000);
+ } catch (MutationsRejectedException ex) {
+ break;
+ }
+ }
+
+ log.debug("Saw expected failure on data which fails the constraint");
+
+ log.debug("Removing constraint from table");
+ client.removeConstraint(creds, table, 2);
+
+ UtilWaitThread.sleep(ZOOKEEPER_PROPAGATION_TIME);
+
+ constraints = client.listConstraints(creds, table);
+ while (constraints.containsKey(NumericValueConstraint.class.getName())) {
+ log.debug("Constraints contains NumericValueConstraint");
+ Thread.sleep(2000);
+ constraints = client.listConstraints(creds, table);
+ }
+
+ assertEquals(1, client.listConstraints(creds, table).size());
+ log.debug("Verified client-side that the constraint was removed");
+
+ log.debug("Attempting to write mutation that should succeed after constraints was removed");
+ // Make sure we can write the data after we removed the constraint
+ while (true) {
+ try {
+ client.updateAndFlush(creds, table, mutation("row1", "cf", "cq", "x"));
+ break;
+ } catch (MutationsRejectedException ex) {
+ log.debug("Expected mutation accepted, but was not. Waiting and retrying");
+ Thread.sleep(5000);
+ }
+ }
+
+ log.debug("Verifying that record can be read from the table");
+ assertScan(new String[][] {{"row1", "cf", "cq", "x"}}, table);
+ }
+
+ @Test
+ public void tableMergesAndSplits() throws Exception {
+ // add some splits
+ client.addSplits(creds, table, new HashSet<ByteBuffer>(Arrays.asList(s2bb("a"), s2bb("m"), s2bb("z"))));
+ List<ByteBuffer> splits = client.listSplits(creds, table, 1);
+ assertEquals(Arrays.asList(s2bb("m")), splits);
+
+ // Merge some of the splits away
+ client.mergeTablets(creds, table, null, s2bb("m"));
+ splits = client.listSplits(creds, table, 10);
+ assertEquals(Arrays.asList(s2bb("m"), s2bb("z")), splits);
+
+ // Merge the entire table
+ client.mergeTablets(creds, table, null, null);
+ splits = client.listSplits(creds, table, 10);
+ List<ByteBuffer> empty = Collections.emptyList();
+
+ // No splits after merge on whole table
+ assertEquals(empty, splits);
+ }
+
+ @Test
+ public void iteratorFunctionality() throws Exception {
+ // iterators
+ HashMap<String,String> options = new HashMap<String,String>();
+ options.put("type", "STRING");
+ options.put("columns", "cf");
+ IteratorSetting setting = new IteratorSetting(10, table, SummingCombiner.class.getName(), options);
+ client.attachIterator(creds, table, setting, EnumSet.allOf(IteratorScope.class));
+ for (int i = 0; i < 10; i++) {
+ client.updateAndFlush(creds, table, mutation("row1", "cf", "cq", "1"));
+ }
+ // 10 updates of "1" in the value w/ SummingCombiner should return value of "10"
+ assertScan(new String[][] {{"row1", "cf", "cq", "10"}}, table);
+
+ try {
+ client.checkIteratorConflicts(creds, table, setting, EnumSet.allOf(IteratorScope.class));
+ fail("checkIteratorConflicts did not throw an exception");
+ } catch (Exception ex) {
+ // Expected
+ }
+ client.deleteRows(creds, table, null, null);
+ client.removeIterator(creds, table, "test", EnumSet.allOf(IteratorScope.class));
+ String expected[][] = new String[10][];
+ for (int i = 0; i < 10; i++) {
+ client.updateAndFlush(creds, table, mutation("row" + i, "cf", "cq", "" + i));
+ expected[i] = new String[] {"row" + i, "cf", "cq", "" + i};
+ client.flushTable(creds, table, null, null, true);
+ }
+ assertScan(expected, table);
+ }
+
+ @Test
+ public void cloneTable() throws Exception {
+ String TABLE_TEST2 = getUniqueNames(2)[1];
+
+ String expected[][] = new String[10][];
+ for (int i = 0; i < 10; i++) {
+ client.updateAndFlush(creds, table, mutation("row" + i, "cf", "cq", "" + i));
+ expected[i] = new String[] {"row" + i, "cf", "cq", "" + i};
+ client.flushTable(creds, table, null, null, true);
+ }
+ assertScan(expected, table);
+
+ // clone
+ client.cloneTable(creds, table, TABLE_TEST2, true, null, null);
+ assertScan(expected, TABLE_TEST2);
+ client.deleteTable(creds, TABLE_TEST2);
+ }
+
+ @Test
+ public void clearLocatorCache() throws Exception {
+ // don't know how to test this, call it just for fun
+ client.clearLocatorCache(creds, table);
+ }
+
+ @Test
+ public void compactTable() throws Exception {
+ String expected[][] = new String[10][];
+ for (int i = 0; i < 10; i++) {
+ client.updateAndFlush(creds, table, mutation("row" + i, "cf", "cq", "" + i));
+ expected[i] = new String[] {"row" + i, "cf", "cq", "" + i};
+ client.flushTable(creds, table, null, null, true);
+ }
+ assertScan(expected, table);
+
+ // compact
+ client.compactTable(creds, table, null, null, null, true, true, null);
+ assertEquals(1, countFiles(table));
+ assertScan(expected, table);
+ }
+
+ @Test
+ public void diskUsage() throws Exception {
+ String TABLE_TEST2 = getUniqueNames(2)[1];
+
+ // Write some data
+ String expected[][] = new String[10][];
+ for (int i = 0; i < 10; i++) {
+ client.updateAndFlush(creds, table, mutation("row" + i, "cf", "cq", "" + i));
+ expected[i] = new String[] {"row" + i, "cf", "cq", "" + i};
+ client.flushTable(creds, table, null, null, true);
+ }
+ assertScan(expected, table);
+
+ // compact
+ client.compactTable(creds, table, null, null, null, true, true, null);
+ assertEquals(1, countFiles(table));
+ assertScan(expected, table);
+
+ // Clone the table
+ client.cloneTable(creds, table, TABLE_TEST2, true, null, null);
+ Set<String> tablesToScan = new HashSet<String>();
+ tablesToScan.add(table);
+ tablesToScan.add(TABLE_TEST2);
+ tablesToScan.add("foo");
+
+ client.createTable(creds, "foo", true, TimeType.MILLIS);
+
+ // get disk usage
+ List<DiskUsage> diskUsage = (client.getDiskUsage(creds, tablesToScan));
+ assertEquals(2, diskUsage.size());
+ // The original table and the clone are lumped together (they share the same files)
+ assertEquals(2, diskUsage.get(0).getTables().size());
+ // The empty table we created
+ assertEquals(1, diskUsage.get(1).getTables().size());
+
+ // Compact the clone so it writes its own files instead of referring to the original
+ client.compactTable(creds, TABLE_TEST2, null, null, null, true, true, null);
+
+ diskUsage = (client.getDiskUsage(creds, tablesToScan));
+ assertEquals(3, diskUsage.size());
+ // The original
+ assertEquals(1, diskUsage.get(0).getTables().size());
+ // The clone w/ its own files now
+ assertEquals(1, diskUsage.get(1).getTables().size());
+ // The empty table
+ assertEquals(1, diskUsage.get(2).getTables().size());
+ client.deleteTable(creds, "foo");
+ client.deleteTable(creds, TABLE_TEST2);
+ }
+
+ @Test
+ public void importExportTable() throws Exception {
+ // Write some data
+ String expected[][] = new String[10][];
+ for (int i = 0; i < 10; i++) {
+ client.updateAndFlush(creds, table, mutation("row" + i, "cf", "cq", "" + i));
+ expected[i] = new String[] {"row" + i, "cf", "cq", "" + i};
+ client.flushTable(creds, table, null, null, true);
+ }
+ assertScan(expected, table);
+
+ // export/import
+ MiniAccumuloClusterImpl cluster = SharedMiniClusterIT.getCluster();
+ FileSystem fs = cluster.getFileSystem();
+ Path base = cluster.getTemporaryPath();
+ Path dir = new Path(base, "test");
+ assertTrue(fs.mkdirs(dir));
+ Path destDir = new Path(base, "test_dest");
+ assertTrue(fs.mkdirs(destDir));
+ client.offlineTable(creds, table, false);
+ client.exportTable(creds, table, dir.toString());
+ // copy files to a new location
+ FSDataInputStream is = fs.open(new Path(dir, "distcp.txt"));
+ try (BufferedReader r = new BufferedReader(new InputStreamReader(is))) {
+ while (true) {
+ String line = r.readLine();
+ if (line == null)
+ break;
+ Path srcPath = new Path(line);
+ FileUtil.copy(fs, srcPath, fs, destDir, false, fs.getConf());
+ }
+ }
+ client.deleteTable(creds, table);
+ client.importTable(creds, "testify", destDir.toString());
+ assertScan(expected, "testify");
+ client.deleteTable(creds, "testify");
+
+ try {
+ // ACCUMULO-1558 a second import from the same dir should fail, the first import moved the files
+ client.importTable(creds, "testify2", destDir.toString());
+ fail();
+ } catch (Exception e) {}
+
+ assertFalse(client.listTables(creds).contains("testify2"));
+ }
+
+ @Test
+ public void localityGroups() throws Exception {
+ Map<String,Set<String>> groups = new HashMap<String,Set<String>>();
+ groups.put("group1", Collections.singleton("cf1"));
+ groups.put("group2", Collections.singleton("cf2"));
+ client.setLocalityGroups(creds, table, groups);
+ assertEquals(groups, client.getLocalityGroups(creds, table));
+ }
+
+ @Test
+ public void tableProperties() throws Exception {
+ Map<String,String> systemProps = client.getSystemConfiguration(creds);
+ String systemTableSplitThreshold = systemProps.get("table.split.threshold");
+
+ Map<String,String> orig = client.getTableProperties(creds, table);
+ client.setTableProperty(creds, table, "table.split.threshold", "500M");
+
+ // Get the new table property value
+ Map<String,String> update = client.getTableProperties(creds, table);
+ assertEquals(update.get("table.split.threshold"), "500M");
+
+ // Table level properties shouldn't affect system level values
+ assertEquals(systemTableSplitThreshold, client.getSystemConfiguration(creds).get("table.split.threshold"));
+
+ client.removeTableProperty(creds, table, "table.split.threshold");
+ update = client.getTableProperties(creds, table);
+ assertEquals(orig, update);
+ }
+
+ @Test
+ public void tableRenames() throws Exception {
+ // rename table
+ Map<String,String> tables = client.tableIdMap(creds);
+ client.renameTable(creds, table, "bar");
+ Map<String,String> tables2 = client.tableIdMap(creds);
+ assertEquals(tables.get(table), tables2.get("bar"));
+ // table exists
+ assertTrue(client.tableExists(creds, "bar"));
+ assertFalse(client.tableExists(creds, table));
+ client.renameTable(creds, "bar", table);
+ }
+
+ @Test
+ public void bulkImport() throws Exception {
+ MiniAccumuloClusterImpl cluster = SharedMiniClusterIT.getCluster();
+ FileSystem fs = cluster.getFileSystem();
+ Path base = cluster.getTemporaryPath();
+ Path dir = new Path(base, "test");
+ assertTrue(fs.mkdirs(dir));
+
+ // Write an RFile
+ String filename = dir + "/bulk/import/rfile.rf";
+ FileSKVWriter writer = FileOperations.getInstance().openWriter(filename, fs, fs.getConf(), DefaultConfiguration.getInstance());
+ writer.startDefaultLocalityGroup();
+ writer.append(new org.apache.accumulo.core.data.Key(new Text("a"), new Text("b"), new Text("c")), new Value("value".getBytes()));
+ writer.close();
+
+ // Create failures directory
+ fs.mkdirs(new Path(dir + "/bulk/fail"));
+
+ // Run the bulk import
+ client.importDirectory(creds, table, dir + "/bulk/import", dir + "/bulk/fail", true);
+
+ // Make sure we find the data
+ String scanner = client.createScanner(creds, table, null);
+ ScanResult more = client.nextK(scanner, 100);
+ client.closeScanner(scanner);
+ assertEquals(1, more.results.size());
+ ByteBuffer maxRow = client.getMaxRow(creds, table, null, null, false, null, false);
+ assertEquals(s2bb("a"), maxRow);
+ }
+
+ @Test
+ public void testTableClassLoad() throws Exception {
+ assertFalse(client.testTableClassLoad(creds, table, "abc123", SortedKeyValueIterator.class.getName()));
+ assertTrue(client.testTableClassLoad(creds, table, VersioningIterator.class.getName(), SortedKeyValueIterator.class.getName()));
+ }
+
+ private Condition newCondition(String cf, String cq) {
+ return new Condition(new Column(s2bb(cf), s2bb(cq), s2bb("")));
+ }
+
+ private Condition newCondition(String cf, String cq, String val) {
+ return newCondition(cf, cq).setValue(s2bb(val));
+ }
+
+ private Condition newCondition(String cf, String cq, long ts, String val) {
+ return newCondition(cf, cq).setValue(s2bb(val)).setTimestamp(ts);
+ }
+
+ private ColumnUpdate newColUpdate(String cf, String cq, String val) {
+ return new ColumnUpdate(s2bb(cf), s2bb(cq)).setValue(s2bb(val));
+ }
+
+ private ColumnUpdate newColUpdate(String cf, String cq, long ts, String val) {
+ return new ColumnUpdate(s2bb(cf), s2bb(cq)).setTimestamp(ts).setValue(s2bb(val));
+ }
+
+ private void assertScan(String[][] expected, String table) throws Exception {
+ String scid = client.createScanner(creds, table, new ScanOptions());
+ ScanResult keyValues = client.nextK(scid, expected.length + 1);
+
- assertEquals(expected.length, keyValues.results.size());
++ assertEquals("Saw " + keyValues.results, expected.length, keyValues.results.size());
+ assertFalse(keyValues.more);
+
+ for (int i = 0; i < keyValues.results.size(); i++) {
+ checkKey(expected[i][0], expected[i][1], expected[i][2], expected[i][3], keyValues.results.get(i));
+ }
+
+ client.closeScanner(scid);
+ }
+
+ @Test
+ public void testConditionalWriter() throws Exception {
+ log.debug("Adding constraint {} to {}", table, NumericValueConstraint.class.getName());
+ client.addConstraint(creds, table, NumericValueConstraint.class.getName());
+ UtilWaitThread.sleep(ZOOKEEPER_PROPAGATION_TIME);
+
+ while (!client.listConstraints(creds, table).containsKey(NumericValueConstraint.class.getName())) {
+ log.info("Failed to see constraint");
+ Thread.sleep(1000);
+ }
+
+ String cwid = client.createConditionalWriter(creds, table, new ConditionalWriterOptions());
+
+ Map<ByteBuffer,ConditionalUpdates> updates = new HashMap<ByteBuffer,ConditionalUpdates>();
+
+ updates.put(
+ s2bb("00345"),
+ new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq")), Arrays.asList(newColUpdate("meta", "seq", 10, "1"),
+ newColUpdate("data", "img", "73435435"))));
+
+ Map<ByteBuffer,ConditionalStatus> results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00345")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "73435435"}, {"00345", "meta", "seq", "1"}}, table);
+
+ // test not setting values on conditions
+ updates.clear();
+
+ updates.put(s2bb("00345"), new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq")), Arrays.asList(newColUpdate("meta", "seq", "2"))));
+ updates.put(s2bb("00346"), new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq")), Arrays.asList(newColUpdate("meta", "seq", "1"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(2, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00345")));
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00346")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "73435435"}, {"00345", "meta", "seq", "1"}, {"00346", "meta", "seq", "1"}}, table);
+
+ // test setting values on conditions
+ updates.clear();
+
+ updates.put(
+ s2bb("00345"),
+ new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq", "1")), Arrays.asList(newColUpdate("meta", "seq", 20, "2"),
+ newColUpdate("data", "img", "567890"))));
+
+ updates.put(s2bb("00346"), new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq", "2")), Arrays.asList(newColUpdate("meta", "seq", "3"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(2, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00345")));
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00346")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "567890"}, {"00345", "meta", "seq", "2"}, {"00346", "meta", "seq", "1"}}, table);
+
+ // test setting timestamp on condition to a non-existant version
+ updates.clear();
+
+ updates.put(
+ s2bb("00345"),
+ new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq", 10, "2")), Arrays.asList(newColUpdate("meta", "seq", 30, "3"),
+ newColUpdate("data", "img", "1234567890"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00345")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "567890"}, {"00345", "meta", "seq", "2"}, {"00346", "meta", "seq", "1"}}, table);
+
+ // test setting timestamp to an existing version
+
+ updates.clear();
+
+ updates.put(
+ s2bb("00345"),
+ new ConditionalUpdates(Arrays.asList(newCondition("meta", "seq", 20, "2")), Arrays.asList(newColUpdate("meta", "seq", 30, "3"),
+ newColUpdate("data", "img", "1234567890"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00345")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"}}, table);
+
+ // run test w/ condition that has iterators
+ // following should fail w/o iterator
+ client.updateAndFlush(creds, table, Collections.singletonMap(s2bb("00347"), Arrays.asList(newColUpdate("data", "count", "1"))));
+ client.updateAndFlush(creds, table, Collections.singletonMap(s2bb("00347"), Arrays.asList(newColUpdate("data", "count", "1"))));
+ client.updateAndFlush(creds, table, Collections.singletonMap(s2bb("00347"), Arrays.asList(newColUpdate("data", "count", "1"))));
+
+ updates.clear();
+ updates.put(s2bb("00347"),
+ new ConditionalUpdates(Arrays.asList(newCondition("data", "count", "3")), Arrays.asList(newColUpdate("data", "img", "1234567890"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00347")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "1"}}, table);
+
+ // following test w/ iterator setup should succeed
+ Condition iterCond = newCondition("data", "count", "3");
+ Map<String,String> props = new HashMap<String,String>();
+ props.put("type", "STRING");
+ props.put("columns", "data:count");
+ IteratorSetting is = new IteratorSetting(1, "sumc", SummingCombiner.class.getName(), props);
+ iterCond.setIterators(Arrays.asList(is));
+
+ updates.clear();
+ updates.put(s2bb("00347"), new ConditionalUpdates(Arrays.asList(iterCond), Arrays.asList(newColUpdate("data", "img", "1234567890"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00347")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "1"}, {"00347", "data", "img", "1234567890"}}, table);
+
+ ConditionalStatus status = null;
+ for (int i = 0; i < 30; i++) {
+ // test a mutation that violated a constraint
+ updates.clear();
+ updates.put(s2bb("00347"),
+ new ConditionalUpdates(Arrays.asList(newCondition("data", "img", "1234567890")), Arrays.asList(newColUpdate("data", "count", "A"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ status = results.get(s2bb("00347"));
+ if (ConditionalStatus.VIOLATED != status) {
+ log.info("ConditionalUpdate was not rejected by server due to table constraint. Sleeping and retrying");
+ Thread.sleep(5000);
+ continue;
+ }
+
+ assertEquals(ConditionalStatus.VIOLATED, status);
+ break;
+ }
+
+ // Final check to make sure we succeeded and didn't exceed the retries
+ assertEquals(ConditionalStatus.VIOLATED, status);
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "1"}, {"00347", "data", "img", "1234567890"}}, table);
+
+ // run test with two conditions
+ // both conditions should fail
+ updates.clear();
+ updates.put(
+ s2bb("00347"),
+ new ConditionalUpdates(Arrays.asList(newCondition("data", "img", "565"), newCondition("data", "count", "2")), Arrays.asList(
+ newColUpdate("data", "count", "3"), newColUpdate("data", "img", "0987654321"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00347")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "1"}, {"00347", "data", "img", "1234567890"}}, table);
+
+ // one condition should fail
+ updates.clear();
+ updates.put(
+ s2bb("00347"),
+ new ConditionalUpdates(Arrays.asList(newCondition("data", "img", "1234567890"), newCondition("data", "count", "2")), Arrays.asList(
+ newColUpdate("data", "count", "3"), newColUpdate("data", "img", "0987654321"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00347")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "1"}, {"00347", "data", "img", "1234567890"}}, table);
+
+ // one condition should fail
+ updates.clear();
+ updates.put(
+ s2bb("00347"),
+ new ConditionalUpdates(Arrays.asList(newCondition("data", "img", "565"), newCondition("data", "count", "1")), Arrays.asList(
+ newColUpdate("data", "count", "3"), newColUpdate("data", "img", "0987654321"))));
+
+ results = client.updateRowsConditionally(cwid, updates);
+
+ assertEquals(1, results.size());
+ assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00347")));
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "1"}, {"00347", "data", "img", "1234567890"}}, table);
+
+ // both conditions should succeed
+
+ ConditionalStatus result = client.updateRowConditionally(
+ creds,
+ table,
+ s2bb("00347"),
+ new ConditionalUpdates(Arrays.asList(newCondition("data", "img", "1234567890"), newCondition("data", "count", "1")), Arrays.asList(
+ newColUpdate("data", "count", "3"), newColUpdate("data", "img", "0987654321"))));
+
+ assertEquals(ConditionalStatus.ACCEPTED, result);
+
+ assertScan(new String[][] { {"00345", "data", "img", "1234567890"}, {"00345", "meta", "seq", "3"}, {"00346", "meta", "seq", "1"},
+ {"00347", "data", "count", "3"}, {"00347", "data", "img", "0987654321"}}, table);
+
+ client.closeConditionalWriter(cwid);
+ try {
+ client.updateRowsConditionally(cwid, updates);
+ fail("conditional writer not closed");
+ } catch (UnknownWriter uk) {}
+
- // run test with colvis
- client.createLocalUser(creds, "cwuser", s2bb("bestpasswordever"));
- client.changeUserAuthorizations(creds, "cwuser", Collections.singleton(s2bb("A")));
- client.grantTablePermission(creds, "cwuser", table, TablePermission.WRITE);
- client.grantTablePermission(creds, "cwuser", table, TablePermission.READ);
++ String principal;
++ ClusterUser cwuser = null;
++ if (isKerberosEnabled()) {
++ cwuser = getKdc().getClientPrincipal(1);
++ principal = cwuser.getPrincipal();
++ client.createLocalUser(creds, principal, s2bb("unused"));
++
++ } else {
++ principal = "cwuser";
++ // run test with colvis
++ client.createLocalUser(creds, principal, s2bb("bestpasswordever"));
++ }
+
- ByteBuffer cwuCreds = client.login("cwuser", Collections.singletonMap("password", "bestpasswordever"));
++ client.changeUserAuthorizations(creds, principal, Collections.singleton(s2bb("A")));
++ client.grantTablePermission(creds, principal, table, TablePermission.WRITE);
++ client.grantTablePermission(creds, principal, table, TablePermission.READ);
++
++ TestProxyClient cwuserProxyClient = null;
++ Client origClient = null;
++ Map<String,String> cwProperties;
++ if (isKerberosEnabled()) {
++ UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
++ final UserG
<TRUNCATED>
[4/7] accumulo git commit: ACCUMULO-3882 Use provided
ClientConfiguration
Posted by el...@apache.org.
ACCUMULO-3882 Use provided ClientConfiguration
Avoids a locally installed clientconfiguration file
from breaking the test.
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/5bd993ba
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/5bd993ba
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/5bd993ba
Branch: refs/heads/1.7
Commit: 5bd993bae0040bf7179565ca8a2fedf2cf210d9f
Parents: 198c5fb
Author: Josh Elser <el...@apache.org>
Authored: Tue Jun 2 17:09:49 2015 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Tue Jun 2 17:22:13 2015 -0400
----------------------------------------------------------------------
.../org/apache/accumulo/test/AccumuloOutputFormatIT.java | 6 +++---
test/src/test/java/org/apache/accumulo/test/VolumeIT.java | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/accumulo/blob/5bd993ba/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java b/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
index 9d00584..a2f522e 100644
--- a/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
@@ -82,8 +82,8 @@ public class AccumuloOutputFormatIT {
@Test
public void testMapred() throws Exception {
-
- ZooKeeperInstance instance = new ZooKeeperInstance(accumulo.getInstanceName(), accumulo.getZooKeepers());
+ ClientConfiguration clientConfig = accumulo.getClientConfig();
+ ZooKeeperInstance instance = new ZooKeeperInstance(clientConfig);
Connector connector = instance.getConnector("root", new PasswordToken(secret));
// create a table and put some data in it
connector.tableOperations().create(TABLE);
@@ -98,7 +98,7 @@ public class AccumuloOutputFormatIT {
batchConfig.setMaxMemory(Long.MAX_VALUE);
AccumuloOutputFormat outputFormat = new AccumuloOutputFormat();
AccumuloOutputFormat.setBatchWriterOptions(job, batchConfig);
- AccumuloOutputFormat.setZooKeeperInstance(job, new ClientConfiguration().withInstance(instance.getInstanceName()).withZkHosts(instance.getZooKeepers()));
+ AccumuloOutputFormat.setZooKeeperInstance(job, clientConfig);
AccumuloOutputFormat.setConnectorInfo(job, "root", new PasswordToken(secret));
RecordWriter<Text,Mutation> writer = outputFormat.getRecordWriter(null, job, "Test", null);
http://git-wip-us.apache.org/repos/asf/accumulo/blob/5bd993ba/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/VolumeIT.java b/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
index d9b9429..d4b3b61 100644
--- a/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
@@ -263,7 +263,7 @@ public class VolumeIT extends ConfigurableMacIT {
String[] tableNames = getUniqueNames(2);
// grab this before shutting down cluster
- String uuid = new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers()).getInstanceID();
+ String uuid = new ZooKeeperInstance(cluster.getClientConfig()).getInstanceID();
verifyVolumesUsed(tableNames[0], false, v1, v2);
@@ -306,7 +306,7 @@ public class VolumeIT extends ConfigurableMacIT {
String[] tableNames = getUniqueNames(2);
// grab this before shutting down cluster
- String uuid = new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers()).getInstanceID();
+ String uuid = new ZooKeeperInstance(cluster.getClientConfig()).getInstanceID();
verifyVolumesUsed(tableNames[0], false, v1, v2);
@@ -464,7 +464,7 @@ public class VolumeIT extends ConfigurableMacIT {
// check that root tablet is not on volume 1
ZooReader zreader = new ZooReader(cluster.getZooKeepers(), 30000);
- String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers())) + RootTable.ZROOT_TABLET_PATH;
+ String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getClientConfig())) + RootTable.ZROOT_TABLET_PATH;
String rootTabletDir = new String(zreader.getData(zpath, false, null), UTF_8);
Assert.assertTrue(rootTabletDir.startsWith(v2.toString()));
@@ -525,7 +525,7 @@ public class VolumeIT extends ConfigurableMacIT {
// check that root tablet is not on volume 1 or 2
ZooReader zreader = new ZooReader(cluster.getZooKeepers(), 30000);
- String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers())) + RootTable.ZROOT_TABLET_PATH;
+ String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getClientConfig())) + RootTable.ZROOT_TABLET_PATH;
String rootTabletDir = new String(zreader.getData(zpath, false, null), UTF_8);
Assert.assertTrue(rootTabletDir.startsWith(v8.toString()) || rootTabletDir.startsWith(v9.toString()));
[5/7] accumulo git commit: Merge branch '1.7'
Posted by el...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/0b7d8eea/test/src/test/java/org/apache/accumulo/test/proxy/TestProxyClient.java
----------------------------------------------------------------------
diff --cc test/src/test/java/org/apache/accumulo/test/proxy/TestProxyClient.java
index 5529d37,0000000..ff92795
mode 100644,000000..100644
--- a/test/src/test/java/org/apache/accumulo/test/proxy/TestProxyClient.java
+++ b/test/src/test/java/org/apache/accumulo/test/proxy/TestProxyClient.java
@@@ -1,183 -1,0 +1,204 @@@
+/*
+ * 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.accumulo.test.proxy;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
++import javax.security.sasl.SaslException;
++
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
++import org.apache.accumulo.core.rpc.UGIAssumingTransport;
+import org.apache.accumulo.proxy.Util;
+import org.apache.accumulo.proxy.thrift.AccumuloProxy;
+import org.apache.accumulo.proxy.thrift.ColumnUpdate;
+import org.apache.accumulo.proxy.thrift.Key;
+import org.apache.accumulo.proxy.thrift.ScanResult;
+import org.apache.accumulo.proxy.thrift.TimeType;
++import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.thrift.protocol.TCompactProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.protocol.TProtocolFactory;
+import org.apache.thrift.transport.TFramedTransport;
++import org.apache.thrift.transport.TSaslClientTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+
+public class TestProxyClient {
+
+ protected AccumuloProxy.Client proxy;
+ protected TTransport transport;
+
+ public TestProxyClient(String host, int port) throws TTransportException {
+ this(host, port, new TCompactProtocol.Factory());
+ }
+
+ public TestProxyClient(String host, int port, TProtocolFactory protoFactory) throws TTransportException {
+ final TSocket socket = new TSocket(host, port);
+ socket.setTimeout(600000);
+ transport = new TFramedTransport(socket);
+ final TProtocol protocol = protoFactory.getProtocol(transport);
+ proxy = new AccumuloProxy.Client(protocol);
+ transport.open();
+ }
+
++ public TestProxyClient(String host, int port, TProtocolFactory protoFactory, String proxyPrimary, UserGroupInformation ugi) throws SaslException,
++ TTransportException {
++ TSocket socket = new TSocket(host, port);
++ TSaslClientTransport saslTransport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, host, Collections.singletonMap("javax.security.sasl.qop",
++ "auth"), null, socket);
++
++ transport = new UGIAssumingTransport(saslTransport, ugi);
++
++ // UGI transport will perform the doAs for us
++ transport.open();
++
++ AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
++ final TProtocol protocol = protoFactory.getProtocol(transport);
++ proxy = factory.getClient(protocol);
++ }
++
+ public synchronized void close() {
+ if (null != transport) {
+ transport.close();
+ transport = null;
+ }
+ }
+
+ public AccumuloProxy.Client proxy() {
+ return proxy;
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ TestProxyClient tpc = new TestProxyClient("localhost", 42424);
+ String principal = "root";
+ Map<String,String> props = new TreeMap<String,String>();
+ props.put("password", "secret");
+
+ System.out.println("Logging in");
+ ByteBuffer login = tpc.proxy.login(principal, props);
+
+ System.out.println("Creating user: ");
+ if (!tpc.proxy().listLocalUsers(login).contains("testuser")) {
+ tpc.proxy().createLocalUser(login, "testuser", ByteBuffer.wrap("testpass".getBytes(UTF_8)));
+ }
+ System.out.println("UserList: " + tpc.proxy().listLocalUsers(login));
+
+ System.out.println("Listing: " + tpc.proxy().listTables(login));
+
+ System.out.println("Deleting: ");
+ String testTable = "testtableOMGOMGOMG";
+
+ System.out.println("Creating: ");
+
+ if (tpc.proxy().tableExists(login, testTable))
+ tpc.proxy().deleteTable(login, testTable);
+
+ tpc.proxy().createTable(login, testTable, true, TimeType.MILLIS);
+
+ System.out.println("Listing: " + tpc.proxy().listTables(login));
+
+ System.out.println("Writing: ");
+ Date start = new Date();
+ Date then = new Date();
+ int maxInserts = 1000000;
+ String format = "%1$05d";
+ Map<ByteBuffer,List<ColumnUpdate>> mutations = new HashMap<ByteBuffer,List<ColumnUpdate>>();
+ for (int i = 0; i < maxInserts; i++) {
+ String result = String.format(format, i);
+ ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap(("cf" + i).getBytes(UTF_8)), ByteBuffer.wrap(("cq" + i).getBytes(UTF_8)));
+ update.setValue(Util.randStringBuffer(10));
+ mutations.put(ByteBuffer.wrap(result.getBytes(UTF_8)), Collections.singletonList(update));
+
+ if (i % 1000 == 0) {
+ tpc.proxy().updateAndFlush(login, testTable, mutations);
+ mutations.clear();
+ }
+ }
+ tpc.proxy().updateAndFlush(login, testTable, mutations);
+ Date end = new Date();
+ System.out.println(" End of writing: " + (end.getTime() - start.getTime()));
+
+ tpc.proxy().deleteTable(login, testTable);
+ tpc.proxy().createTable(login, testTable, true, TimeType.MILLIS);
+
+ // Thread.sleep(1000);
+
+ System.out.println("Writing async: ");
+ start = new Date();
+ then = new Date();
+ mutations.clear();
+ String writer = tpc.proxy().createWriter(login, testTable, null);
+ for (int i = 0; i < maxInserts; i++) {
+ String result = String.format(format, i);
+ Key pkey = new Key();
+ pkey.setRow(result.getBytes(UTF_8));
+ ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap(("cf" + i).getBytes(UTF_8)), ByteBuffer.wrap(("cq" + i).getBytes(UTF_8)));
+ update.setValue(Util.randStringBuffer(10));
+ mutations.put(ByteBuffer.wrap(result.getBytes(UTF_8)), Collections.singletonList(update));
+ tpc.proxy().update(writer, mutations);
+ mutations.clear();
+ }
+
+ end = new Date();
+ System.out.println(" End of writing: " + (end.getTime() - start.getTime()));
+ start = end;
+ System.out.println("Closing...");
+ tpc.proxy().closeWriter(writer);
+ end = new Date();
+ System.out.println(" End of closing: " + (end.getTime() - start.getTime()));
+
+ System.out.println("Reading: ");
+
+ String regex = "cf1.*";
+
+ IteratorSetting is = new IteratorSetting(50, regex, RegExFilter.class);
+ RegExFilter.setRegexs(is, null, regex, null, null, false);
+
+ String cookie = tpc.proxy().createScanner(login, testTable, null);
+
+ int i = 0;
+ start = new Date();
+ then = new Date();
+ boolean hasNext = true;
+
+ int k = 1000;
+ while (hasNext) {
+ ScanResult kvList = tpc.proxy().nextK(cookie, k);
+
+ Date now = new Date();
+ System.out.println(i + " " + (now.getTime() - then.getTime()));
+ then = now;
+
+ i += kvList.getResultsSize();
+ // for (TKeyValue kv:kvList.getResults()) System.out.println(new Key(kv.getKey()));
+ hasNext = kvList.isMore();
+ }
+ end = new Date();
+ System.out.println("Total entries: " + i + " total time " + (end.getTime() - start.getTime()));
+ }
+}
[7/7] accumulo git commit: Merge branch '1.7'
Posted by el...@apache.org.
Merge branch '1.7'
Conflicts:
test/src/test/java/org/apache/accumulo/test/proxy/TestProxyClient.java
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/0b7d8eea
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/0b7d8eea
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/0b7d8eea
Branch: refs/heads/master
Commit: 0b7d8eeae0a66e6b3e5401a171b458d1679b8f9c
Parents: fba068b 5bd993b
Author: Josh Elser <el...@apache.org>
Authored: Tue Jun 2 17:40:11 2015 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Tue Jun 2 17:40:11 2015 -0400
----------------------------------------------------------------------
.../java/org/apache/accumulo/proxy/Proxy.java | 8 +-
.../accumulo/harness/SharedMiniClusterIT.java | 6 +-
.../accumulo/test/AccumuloOutputFormatIT.java | 6 +-
.../java/org/apache/accumulo/test/VolumeIT.java | 8 +-
.../accumulo/test/proxy/SimpleProxyBase.java | 485 +++++++++++++++----
.../accumulo/test/proxy/TestProxyClient.java | 21 +
6 files changed, 437 insertions(+), 97 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/accumulo/blob/0b7d8eea/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
----------------------------------------------------------------------
[3/7] accumulo git commit: ACCUMULO-3882 Use provided
ClientConfiguration
Posted by el...@apache.org.
ACCUMULO-3882 Use provided ClientConfiguration
Avoids a locally installed clientconfiguration file
from breaking the test.
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/5bd993ba
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/5bd993ba
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/5bd993ba
Branch: refs/heads/master
Commit: 5bd993bae0040bf7179565ca8a2fedf2cf210d9f
Parents: 198c5fb
Author: Josh Elser <el...@apache.org>
Authored: Tue Jun 2 17:09:49 2015 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Tue Jun 2 17:22:13 2015 -0400
----------------------------------------------------------------------
.../org/apache/accumulo/test/AccumuloOutputFormatIT.java | 6 +++---
test/src/test/java/org/apache/accumulo/test/VolumeIT.java | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/accumulo/blob/5bd993ba/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java b/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
index 9d00584..a2f522e 100644
--- a/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/AccumuloOutputFormatIT.java
@@ -82,8 +82,8 @@ public class AccumuloOutputFormatIT {
@Test
public void testMapred() throws Exception {
-
- ZooKeeperInstance instance = new ZooKeeperInstance(accumulo.getInstanceName(), accumulo.getZooKeepers());
+ ClientConfiguration clientConfig = accumulo.getClientConfig();
+ ZooKeeperInstance instance = new ZooKeeperInstance(clientConfig);
Connector connector = instance.getConnector("root", new PasswordToken(secret));
// create a table and put some data in it
connector.tableOperations().create(TABLE);
@@ -98,7 +98,7 @@ public class AccumuloOutputFormatIT {
batchConfig.setMaxMemory(Long.MAX_VALUE);
AccumuloOutputFormat outputFormat = new AccumuloOutputFormat();
AccumuloOutputFormat.setBatchWriterOptions(job, batchConfig);
- AccumuloOutputFormat.setZooKeeperInstance(job, new ClientConfiguration().withInstance(instance.getInstanceName()).withZkHosts(instance.getZooKeepers()));
+ AccumuloOutputFormat.setZooKeeperInstance(job, clientConfig);
AccumuloOutputFormat.setConnectorInfo(job, "root", new PasswordToken(secret));
RecordWriter<Text,Mutation> writer = outputFormat.getRecordWriter(null, job, "Test", null);
http://git-wip-us.apache.org/repos/asf/accumulo/blob/5bd993ba/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/VolumeIT.java b/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
index d9b9429..d4b3b61 100644
--- a/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/VolumeIT.java
@@ -263,7 +263,7 @@ public class VolumeIT extends ConfigurableMacIT {
String[] tableNames = getUniqueNames(2);
// grab this before shutting down cluster
- String uuid = new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers()).getInstanceID();
+ String uuid = new ZooKeeperInstance(cluster.getClientConfig()).getInstanceID();
verifyVolumesUsed(tableNames[0], false, v1, v2);
@@ -306,7 +306,7 @@ public class VolumeIT extends ConfigurableMacIT {
String[] tableNames = getUniqueNames(2);
// grab this before shutting down cluster
- String uuid = new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers()).getInstanceID();
+ String uuid = new ZooKeeperInstance(cluster.getClientConfig()).getInstanceID();
verifyVolumesUsed(tableNames[0], false, v1, v2);
@@ -464,7 +464,7 @@ public class VolumeIT extends ConfigurableMacIT {
// check that root tablet is not on volume 1
ZooReader zreader = new ZooReader(cluster.getZooKeepers(), 30000);
- String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers())) + RootTable.ZROOT_TABLET_PATH;
+ String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getClientConfig())) + RootTable.ZROOT_TABLET_PATH;
String rootTabletDir = new String(zreader.getData(zpath, false, null), UTF_8);
Assert.assertTrue(rootTabletDir.startsWith(v2.toString()));
@@ -525,7 +525,7 @@ public class VolumeIT extends ConfigurableMacIT {
// check that root tablet is not on volume 1 or 2
ZooReader zreader = new ZooReader(cluster.getZooKeepers(), 30000);
- String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getInstanceName(), cluster.getZooKeepers())) + RootTable.ZROOT_TABLET_PATH;
+ String zpath = ZooUtil.getRoot(new ZooKeeperInstance(cluster.getClientConfig())) + RootTable.ZROOT_TABLET_PATH;
String rootTabletDir = new String(zreader.getData(zpath, false, null), UTF_8);
Assert.assertTrue(rootTabletDir.startsWith(v8.toString()) || rootTabletDir.startsWith(v9.toString()));