use of org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException in project accumulo by apache.
the class ManagerClientServiceHandler method waitForFlush.
@Override
public void waitForFlush(TInfo tinfo, TCredentials c, String tableIdStr, ByteBuffer startRowBB, ByteBuffer endRowBB, long flushID, long maxLoops) throws ThriftSecurityException, ThriftTableOperationException {
TableId tableId = TableId.of(tableIdStr);
NamespaceId namespaceId = getNamespaceIdFromTableId(TableOperation.FLUSH, tableId);
if (!manager.security.canFlush(c, tableId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
Text startRow = ByteBufferUtil.toText(startRowBB);
Text endRow = ByteBufferUtil.toText(endRowBB);
if (endRow != null && startRow != null && startRow.compareTo(endRow) >= 0)
throw new ThriftTableOperationException(tableId.canonical(), null, TableOperation.FLUSH, TableOperationExceptionType.BAD_RANGE, "start row must be less than end row");
Set<TServerInstance> serversToFlush = new HashSet<>(manager.tserverSet.getCurrentServers());
for (long l = 0; l < maxLoops; l++) {
for (TServerInstance instance : serversToFlush) {
try {
final TServerConnection server = manager.tserverSet.getConnection(instance);
if (server != null)
server.flush(manager.managerLock, tableId, ByteBufferUtil.toBytes(startRowBB), ByteBufferUtil.toBytes(endRowBB));
} catch (TException ex) {
Manager.log.error(ex.toString());
}
}
if (tableId.equals(RootTable.ID))
// this code does not properly handle the root tablet. See #798
break;
if (l == maxLoops - 1)
break;
sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
serversToFlush.clear();
try (TabletsMetadata tablets = TabletsMetadata.builder(manager.getContext()).forTable(tableId).overlapping(startRow, endRow).fetch(FLUSH_ID, LOCATION, LOGS, PREV_ROW).build()) {
int tabletsToWaitFor = 0;
int tabletCount = 0;
for (TabletMetadata tablet : tablets) {
int logs = tablet.getLogs().size();
// when tablet is not online and has no logs, there is no reason to wait for it
if ((tablet.hasCurrent() || logs > 0) && tablet.getFlushId().orElse(-1) < flushID) {
tabletsToWaitFor++;
if (tablet.hasCurrent())
serversToFlush.add(tablet.getLocation());
}
tabletCount++;
}
if (tabletsToWaitFor == 0)
break;
if (tabletCount == 0 && !manager.getContext().tableNodeExists(tableId))
throw new ThriftTableOperationException(tableId.canonical(), null, TableOperation.FLUSH, TableOperationExceptionType.NOTFOUND, null);
} catch (TabletDeletedException e) {
Manager.log.debug("Failed to scan {} table to wait for flush {}", MetadataTable.NAME, tableId, e);
}
}
}
use of org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException in project accumulo by apache.
the class ManagerClientServiceHandler method removeSystemProperty.
@Override
public void removeSystemProperty(TInfo info, TCredentials c, String property) throws ThriftSecurityException {
if (!manager.security.canPerformSystemActions(c))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
try {
SystemPropUtil.removeSystemProperty(manager.getContext(), property);
updatePlugins(property);
} catch (Exception e) {
Manager.log.error("Problem removing config property in zookeeper", e);
throw new RuntimeException(e.getMessage());
}
}
use of org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException in project accumulo by apache.
the class ThriftClientHandler method flush.
@Override
public void flush(TInfo tinfo, TCredentials credentials, String lock, String tableId, ByteBuffer startRow, ByteBuffer endRow) {
try {
checkPermission(credentials, lock, "flush");
} catch (ThriftSecurityException e) {
log.error("Caller doesn't have permission to flush a table", e);
throw new RuntimeException(e);
}
ArrayList<Tablet> tabletsToFlush = new ArrayList<>();
KeyExtent ke = new KeyExtent(TableId.of(tableId), ByteBufferUtil.toText(endRow), ByteBufferUtil.toText(startRow));
for (Tablet tablet : server.getOnlineTablets().values()) {
if (ke.overlaps(tablet.getExtent())) {
tabletsToFlush.add(tablet);
}
}
Long flushID = null;
for (Tablet tablet : tabletsToFlush) {
if (flushID == null) {
// it for each tablet
try {
flushID = tablet.getFlushID();
} catch (NoNodeException e) {
// table was probably deleted
log.info("Asked to flush table that has no flush id {} {}", ke, e.getMessage());
return;
}
}
tablet.flush(flushID);
}
}
use of org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException in project accumulo by apache.
the class ThriftClientHandler method loadTablet.
@Override
public void loadTablet(TInfo tinfo, TCredentials credentials, String lock, final TKeyExtent textent) {
try {
checkPermission(credentials, lock, "loadTablet");
} catch (ThriftSecurityException e) {
log.error("Caller doesn't have permission to load a tablet", e);
throw new RuntimeException(e);
}
final KeyExtent extent = KeyExtent.fromThrift(textent);
synchronized (server.unopenedTablets) {
synchronized (server.openingTablets) {
synchronized (server.onlineTablets) {
// Checking if the current tablet is in any of the sets
// below is not a strong enough check to catch all overlapping tablets
// when splits and fix splits are occurring
Set<KeyExtent> unopenedOverlapping = KeyExtent.findOverlapping(extent, server.unopenedTablets);
Set<KeyExtent> openingOverlapping = KeyExtent.findOverlapping(extent, server.openingTablets);
Set<KeyExtent> onlineOverlapping = KeyExtent.findOverlapping(extent, server.getOnlineTablets());
Set<KeyExtent> all = new HashSet<>();
all.addAll(unopenedOverlapping);
all.addAll(openingOverlapping);
all.addAll(onlineOverlapping);
if (!all.isEmpty()) {
// ignore any tablets that have recently split, for error logging
for (KeyExtent e2 : onlineOverlapping) {
Tablet tablet = server.getOnlineTablet(e2);
if (System.currentTimeMillis() - tablet.getSplitCreationTime() < RECENTLY_SPLIT_MILLIES) {
all.remove(e2);
}
}
// ignore self, for error logging
all.remove(extent);
if (!all.isEmpty()) {
log.error("Tablet {} overlaps a previously assigned tablet, possibly due to a recent split. " + "Overlapping tablets: Unopened: {}, Opening: {}, Online: {}", extent, unopenedOverlapping, openingOverlapping, onlineOverlapping);
}
return;
}
server.unopenedTablets.add(extent);
}
}
}
TabletLogger.loading(extent, server.getTabletSession());
final AssignmentHandler ah = new AssignmentHandler(server, extent);
if (extent.isRootTablet()) {
Threads.createThread("Root Tablet Assignment", () -> {
ah.run();
if (server.getOnlineTablets().containsKey(extent)) {
log.info("Root tablet loaded: {}", extent);
} else {
log.info("Root tablet failed to load");
}
}).start();
} else {
if (extent.isMeta()) {
server.resourceManager.addMetaDataAssignment(extent, log, ah);
} else {
server.resourceManager.addAssignment(extent, log, ah);
}
}
}
use of org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException in project accumulo by apache.
the class ThriftClientHandler method setUpdateTablet.
private void setUpdateTablet(UpdateSession us, KeyExtent keyExtent) {
long t1 = System.currentTimeMillis();
if (us.currentTablet != null && us.currentTablet.getExtent().equals(keyExtent)) {
return;
}
if (us.currentTablet == null && (us.failures.containsKey(keyExtent) || us.authFailures.containsKey(keyExtent))) {
// if there were previous failures, then do not accept additional writes
return;
}
TableId tableId = null;
try {
// if user has no permission to write to this table, add it to
// the failures list
boolean sameTable = us.currentTablet != null && us.currentTablet.getExtent().tableId().equals(keyExtent.tableId());
tableId = keyExtent.tableId();
if (sameTable || security.canWrite(us.getCredentials(), tableId, server.getContext().getNamespaceId(tableId))) {
long t2 = System.currentTimeMillis();
us.authTimes.addStat(t2 - t1);
us.currentTablet = server.getOnlineTablet(keyExtent);
if (us.currentTablet != null) {
us.queuedMutations.put(us.currentTablet, new ArrayList<>());
} else {
// not serving tablet, so report all mutations as
// failures
us.failures.put(keyExtent, 0L);
server.updateMetrics.addUnknownTabletErrors(0);
}
} else {
log.warn("Denying access to table {} for user {}", keyExtent.tableId(), us.getUser());
long t2 = System.currentTimeMillis();
us.authTimes.addStat(t2 - t1);
us.currentTablet = null;
us.authFailures.put(keyExtent, SecurityErrorCode.PERMISSION_DENIED);
server.updateMetrics.addPermissionErrors(0);
return;
}
} catch (TableNotFoundException tnfe) {
log.error("Table " + tableId + " not found ", tnfe);
long t2 = System.currentTimeMillis();
us.authTimes.addStat(t2 - t1);
us.currentTablet = null;
us.authFailures.put(keyExtent, SecurityErrorCode.TABLE_DOESNT_EXIST);
server.updateMetrics.addUnknownTabletErrors(0);
return;
} catch (ThriftSecurityException e) {
log.error("Denying permission to check user " + us.getUser() + " with user " + e.getUser(), e);
long t2 = System.currentTimeMillis();
us.authTimes.addStat(t2 - t1);
us.currentTablet = null;
us.authFailures.put(keyExtent, e.getCode());
server.updateMetrics.addPermissionErrors(0);
return;
}
}
Aggregations