use of org.apache.accumulo.proxy.thrift.ConditionalUpdates in project accumulo by apache.
the class ProxyServer method updateRowsConditionally.
@Override
public Map<ByteBuffer, ConditionalStatus> updateRowsConditionally(String conditionalWriter, Map<ByteBuffer, ConditionalUpdates> updates) throws UnknownWriter, org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
ConditionalWriter cw = conditionalWriterCache.getIfPresent(UUID.fromString(conditionalWriter));
if (cw == null) {
throw new UnknownWriter();
}
try {
HashMap<Text, ColumnVisibility> vizMap = new HashMap<>();
ArrayList<ConditionalMutation> cmuts = new ArrayList<>(updates.size());
for (Entry<ByteBuffer, ConditionalUpdates> cu : updates.entrySet()) {
ConditionalMutation cmut = new ConditionalMutation(ByteBufferUtil.toBytes(cu.getKey()));
for (Condition tcond : cu.getValue().conditions) {
org.apache.accumulo.core.data.Condition cond = new org.apache.accumulo.core.data.Condition(tcond.column.getColFamily(), tcond.column.getColQualifier());
if (tcond.getColumn().getColVisibility() != null && tcond.getColumn().getColVisibility().length > 0) {
cond.setVisibility(getCahcedCV(vizMap, tcond.getColumn().getColVisibility()));
}
if (tcond.isSetValue())
cond.setValue(tcond.getValue());
if (tcond.isSetTimestamp())
cond.setTimestamp(tcond.getTimestamp());
if (tcond.isSetIterators()) {
cond.setIterators(getIteratorSettings(tcond.getIterators()).toArray(new IteratorSetting[tcond.getIterators().size()]));
}
cmut.addCondition(cond);
}
addUpdatesToMutation(vizMap, cmut, cu.getValue().updates);
cmuts.add(cmut);
}
Iterator<Result> results = cw.write(cmuts.iterator());
HashMap<ByteBuffer, ConditionalStatus> resultMap = new HashMap<>();
while (results.hasNext()) {
Result result = results.next();
ByteBuffer row = ByteBuffer.wrap(result.getMutation().getRow());
ConditionalStatus status = ConditionalStatus.valueOf(result.getStatus().name());
resultMap.put(row, status);
}
return resultMap;
} catch (Exception e) {
handleException(e);
return null;
}
}
use of org.apache.accumulo.proxy.thrift.ConditionalUpdates in project accumulo by apache.
the class SimpleProxyBase method testConditionalWriter.
@Test
public void testConditionalWriter() throws Exception {
log.debug("Adding constraint {} to {}", tableName, NumericValueConstraint.class.getName());
client.addConstraint(creds, tableName, NumericValueConstraint.class.getName());
sleepUninterruptibly(ZOOKEEPER_PROPAGATION_TIME, TimeUnit.MILLISECONDS);
// Take the table offline and online to force a config update
client.offlineTable(creds, tableName, true);
client.onlineTable(creds, tableName, true);
while (!client.listConstraints(creds, tableName).containsKey(NumericValueConstraint.class.getName())) {
log.info("Failed to see constraint");
Thread.sleep(1000);
}
String cwid = client.createConditionalWriter(creds, tableName, new ConditionalWriterOptions());
Map<ByteBuffer, ConditionalUpdates> updates = new HashMap<>();
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" } }, tableName);
// 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" } }, tableName);
// 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" } }, tableName);
// 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" } }, tableName);
// 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" } }, tableName);
// run test w/ condition that has iterators
// following should fail w/o iterator
client.updateAndFlush(creds, tableName, Collections.singletonMap(s2bb("00347"), Arrays.asList(newColUpdate("data", "count", "1"))));
client.updateAndFlush(creds, tableName, Collections.singletonMap(s2bb("00347"), Arrays.asList(newColUpdate("data", "count", "1"))));
client.updateAndFlush(creds, tableName, 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" } }, tableName);
// following test w/ iterator setup should succeed
Condition iterCond = newCondition("data", "count", "3");
Map<String, String> props = new HashMap<>();
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" } }, tableName);
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" } }, tableName);
// 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" } }, tableName);
// 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" } }, tableName);
// 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" } }, tableName);
// both conditions should succeed
ConditionalStatus result = client.updateRowConditionally(creds, tableName, 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" } }, tableName);
client.closeConditionalWriter(cwid);
try {
client.updateRowsConditionally(cwid, updates);
fail("conditional writer not closed");
} catch (UnknownWriter uk) {
}
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"));
}
client.changeUserAuthorizations(creds, principal, Collections.singleton(s2bb("A")));
client.grantTablePermission(creds, principal, tableName, TablePermission.WRITE);
client.grantTablePermission(creds, principal, tableName, 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");
}
try {
ByteBuffer cwCreds = client.login(principal, cwProperties);
cwid = client.createConditionalWriter(cwCreds, tableName, new ConditionalWriterOptions().setAuthorizations(Collections.singleton(s2bb("A"))));
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"))));
results = client.updateRowsConditionally(cwid, updates);
assertEquals(2, results.size());
assertEquals(ConditionalStatus.ACCEPTED, results.get(s2bb("00348")));
assertEquals(ConditionalStatus.INVISIBLE_VISIBILITY, results.get(s2bb("00349")));
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" } }, tableName);
if (isKerberosEnabled()) {
UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
client = cwuserProxyClient.proxy();
}
updates.clear();
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")))));
results = client.updateRowsConditionally(cwid, updates);
assertEquals(1, results.size());
assertEquals(ConditionalStatus.REJECTED, results.get(s2bb("00348")));
if (isKerberosEnabled()) {
UserGroupInformation.loginUserFromKeytab(clientPrincipal, clientKeytab.getAbsolutePath());
client = origClient;
}
// 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" } }, tableName);
if (isKerberosEnabled()) {
UserGroupInformation.loginUserFromKeytab(cwuser.getPrincipal(), cwuser.getKeytab().getAbsolutePath());
client = cwuserProxyClient.proxy();
}
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")))));
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" } }, tableName);
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);
}
}
use of org.apache.accumulo.proxy.thrift.ConditionalUpdates in project accumulo by apache.
the class ProxyDurabilityIT method testDurability.
@Test
public void testDurability() throws Exception {
Connector c = getConnector();
Properties props = new Properties();
// Avoid issues with locally installed client configuration files with custom properties
File emptyFile = Files.createTempFile(null, null).toFile();
emptyFile.deleteOnExit();
props.put("instance", c.getInstance().getInstanceName());
props.put("zookeepers", c.getInstance().getZooKeepers());
props.put("tokenClass", PasswordToken.class.getName());
props.put("clientConfigurationFile", emptyFile.toString());
TJSONProtocol.Factory protocol = new TJSONProtocol.Factory();
int proxyPort = PortUtils.getRandomFreePort();
final TServer proxyServer = Proxy.createProxyServer(HostAndPort.fromParts("localhost", proxyPort), protocol, props).server;
while (!proxyServer.isServing()) sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
Client client = new TestProxyClient("localhost", proxyPort, protocol).proxy();
Map<String, String> properties = new TreeMap<>();
properties.put("password", ROOT_PASSWORD);
ByteBuffer login = client.login("root", properties);
String tableName = getUniqueNames(1)[0];
client.createTable(login, tableName, true, TimeType.MILLIS);
assertTrue(c.tableOperations().exists(tableName));
WriterOptions options = new WriterOptions();
options.setDurability(Durability.NONE);
String writer = client.createWriter(login, tableName, options);
Map<ByteBuffer, List<ColumnUpdate>> cells = new TreeMap<>();
ColumnUpdate column = new ColumnUpdate(bytes("cf"), bytes("cq"));
column.setValue("value".getBytes());
cells.put(bytes("row"), Collections.singletonList(column));
client.update(writer, cells);
client.closeWriter(writer);
assertEquals(1, count(tableName));
restartTServer();
assertEquals(0, count(tableName));
ConditionalWriterOptions cfg = new ConditionalWriterOptions();
cfg.setDurability(Durability.SYNC);
String cwriter = client.createConditionalWriter(login, tableName, cfg);
ConditionalUpdates updates = new ConditionalUpdates();
updates.addToConditions(new Condition(new Column(bytes("cf"), bytes("cq"), bytes(""))));
updates.addToUpdates(column);
Map<ByteBuffer, ConditionalStatus> status = client.updateRowsConditionally(cwriter, Collections.singletonMap(bytes("row"), updates));
assertEquals(ConditionalStatus.ACCEPTED, status.get(bytes("row")));
assertEquals(1, count(tableName));
restartTServer();
assertEquals(1, count(tableName));
proxyServer.stop();
}
Aggregations