Skip to content

Make several TableOpsImpl methods atomic #5540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,26 @@ public Map<String,String> modifyProperties(String tableName,
}
}

/**
* Like modifyProperties(...), but if an AccumuloException is caused by a TableNotFoundException,
* unwrap and rethrow the TNFE directly. This is a hacky, temporary workaround that we can use
* until we are able to change the public API and throw TNFE directly from all applicable methods.
*/
private Map<String,String> modifyPropertiesUnwrapped(String tableName,
Consumer<Map<String,String>> mapMutator)
throws TableNotFoundException, AccumuloException, AccumuloSecurityException {

try {
return modifyProperties(tableName, mapMutator);
} catch (AccumuloException ae) {
Throwable cause = ae.getCause();
if (cause instanceof TableNotFoundException) {
throw new TableNotFoundException(null, tableName, null, ae);
}
throw ae;
}
}

private void setPropertyNoChecks(final String tableName, final String property,
final String value)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
Expand Down Expand Up @@ -1206,42 +1226,32 @@ public Map<String,String> getTableProperties(final String tableName)
}

@Override
public void setLocalityGroups(String tableName, Map<String,Set<Text>> groups)
public void setLocalityGroups(String tableName, Map<String,Set<Text>> groupsToSet)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
// ensure locality groups do not overlap
LocalityGroupUtil.ensureNonOverlappingGroups(groups);
LocalityGroupUtil.ensureNonOverlappingGroups(groupsToSet);

for (Entry<String,Set<Text>> entry : groups.entrySet()) {
Set<Text> colFams = entry.getValue();
String value = LocalityGroupUtil.encodeColumnFamilies(colFams);
setPropertyNoChecks(tableName, Property.TABLE_LOCALITY_GROUP_PREFIX + entry.getKey(), value);
}
final String localityGroupPrefix = Property.TABLE_LOCALITY_GROUP_PREFIX.getKey();

try {
setPropertyNoChecks(tableName, Property.TABLE_LOCALITY_GROUPS.getKey(),
Joiner.on(",").join(groups.keySet()));
} catch (AccumuloException e) {
if (e.getCause() instanceof TableNotFoundException) {
throw (TableNotFoundException) e.getCause();
}
throw e;
}
modifyPropertiesUnwrapped(tableName, properties -> {

// remove anything extraneous
String prefix = Property.TABLE_LOCALITY_GROUP_PREFIX.getKey();
for (Entry<String,String> entry : getProperties(tableName)) {
String property = entry.getKey();
if (property.startsWith(prefix)) {
// this property configures a locality group, find out which
// one:
String[] parts = property.split("\\.");
String group = parts[parts.length - 1];
// add/update each locality group
groupsToSet.forEach((groupName, colFams) -> properties.put(localityGroupPrefix + groupName,
LocalityGroupUtil.encodeColumnFamilies(colFams)));

if (!groups.containsKey(group)) {
removePropertyNoChecks(tableName, property);
// update the list of all locality groups
final String allGroups = Joiner.on(",").join(groupsToSet.keySet());
properties.put(Property.TABLE_LOCALITY_GROUPS.getKey(), allGroups);

// remove any stale locality groups that were previously set
properties.keySet().removeIf(property -> {
if (property.startsWith(localityGroupPrefix)) {
String group = property.substring(localityGroupPrefix.length());
return !groupsToSet.containsKey(group);
}
}
}
return false;
});
});
}

@Override
Expand Down Expand Up @@ -1846,37 +1856,31 @@ private void doTableFateOperation(String tableOrNamespaceName,
}
}

private void clearSamplerOptions(String tableName)
throws AccumuloException, TableNotFoundException, AccumuloSecurityException {
EXISTING_TABLE_NAME.validate(tableName);

String prefix = Property.TABLE_SAMPLER_OPTS.getKey();
for (Entry<String,String> entry : getProperties(tableName)) {
String property = entry.getKey();
if (property.startsWith(prefix)) {
removeProperty(tableName, property);
}
}
}

@Override
public void setSamplerConfiguration(String tableName, SamplerConfiguration samplerConfiguration)
throws AccumuloException, TableNotFoundException, AccumuloSecurityException {
EXISTING_TABLE_NAME.validate(tableName);

clearSamplerOptions(tableName);
Map<String,String> props =
new SamplerConfigurationImpl(samplerConfiguration).toTablePropertiesMap();
modifyProperties(tableName, properties -> properties.putAll(props));

modifyPropertiesUnwrapped(tableName, properties -> {
properties.keySet()
.removeIf(property -> property.startsWith(Property.TABLE_SAMPLER_OPTS.getKey()));
properties.putAll(props);
});
}

@Override
public void clearSamplerConfiguration(String tableName)
throws AccumuloException, TableNotFoundException, AccumuloSecurityException {
EXISTING_TABLE_NAME.validate(tableName);

removeProperty(tableName, Property.TABLE_SAMPLER.getKey());
clearSamplerOptions(tableName);
modifyPropertiesUnwrapped(tableName, properties -> {
properties.remove(Property.TABLE_SAMPLER.getKey());
properties.keySet()
.removeIf(property -> property.startsWith(Property.TABLE_SAMPLER_OPTS.getKey()));
});
}

@Override
Expand Down