This is an automated email from the ASF dual-hosted git repository.
cshannon pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push:
new 8fe933a671 Add a constraint check for suspend column (#4546)
8fe933a671 is described below
commit 8fe933a6710066bb88c63401d12e9ff0d88cdf0f
Author: Christopher L. Shannon <[email protected]>
AuthorDate: Fri May 17 16:40:22 2024 -0400
Add a constraint check for suspend column (#4546)
This adds a new metadata constraint check for the suspend metadata
column to ensure that the suspension time is not negative as we should
never have a negative value.
This is a follow on to #4494
---
.../server/constraints/MetadataConstraints.java | 66 +++++++++++++---------
.../constraints/MetadataConstraintsTest.java | 33 +++++++++++
2 files changed, 72 insertions(+), 27 deletions(-)
diff --git
a/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
b/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
index 0f4a361312..1b99a5b307 100644
---
a/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
+++
b/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
@@ -36,6 +36,7 @@ import org.apache.accumulo.core.fate.zookeeper.ZooUtil;
import org.apache.accumulo.core.lock.ServiceLock;
import org.apache.accumulo.core.metadata.AccumuloTable;
import org.apache.accumulo.core.metadata.StoredTabletFile;
+import org.apache.accumulo.core.metadata.SuspendingTServer;
import org.apache.accumulo.core.metadata.schema.DataFileValue;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.BulkFileColumnFamily;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ChoppedColumnFamily;
@@ -306,40 +307,49 @@ public class MetadataConstraints implements Constraint {
} else {
if (!isValidColumn(columnUpdate)) {
violations = addViolation(violations, 2);
- } else if (new
ColumnFQ(columnUpdate).equals(TabletColumnFamily.PREV_ROW_COLUMN)
- && columnUpdate.getValue().length > 0
- && (violations == null || !violations.contains((short) 4))) {
- KeyExtent ke = KeyExtent.fromMetaRow(new Text(mutation.getRow()));
+ } else {
+ final var column = new ColumnFQ(columnUpdate);
+ if (column.equals(TabletColumnFamily.PREV_ROW_COLUMN)
+ && columnUpdate.getValue().length > 0
+ && (violations == null || !violations.contains((short) 4))) {
+ KeyExtent ke = KeyExtent.fromMetaRow(new Text(mutation.getRow()));
- Text per = TabletColumnFamily.decodePrevEndRow(new
Value(columnUpdate.getValue()));
+ Text per = TabletColumnFamily.decodePrevEndRow(new
Value(columnUpdate.getValue()));
- boolean prevEndRowLessThanEndRow =
- per == null || ke.endRow() == null || per.compareTo(ke.endRow())
< 0;
+ boolean prevEndRowLessThanEndRow =
+ per == null || ke.endRow() == null ||
per.compareTo(ke.endRow()) < 0;
- if (!prevEndRowLessThanEndRow) {
- violations = addViolation(violations, 3);
- }
- } else if (new
ColumnFQ(columnUpdate).equals(ServerColumnFamily.LOCK_COLUMN)) {
- if (zooCache == null) {
- zooCache = new ZooCache(context.getZooReader(), null);
- CleanerUtil.zooCacheClearer(this, zooCache);
- }
+ if (!prevEndRowLessThanEndRow) {
+ violations = addViolation(violations, 3);
+ }
+ } else if (column.equals(ServerColumnFamily.LOCK_COLUMN)) {
+ if (zooCache == null) {
+ zooCache = new ZooCache(context.getZooReader(), null);
+ CleanerUtil.zooCacheClearer(this, zooCache);
+ }
- if (zooRoot == null) {
- zooRoot = context.getZooKeeperRoot();
- }
+ if (zooRoot == null) {
+ zooRoot = context.getZooKeeperRoot();
+ }
- boolean lockHeld = false;
- String lockId = new String(columnUpdate.getValue(), UTF_8);
+ boolean lockHeld = false;
+ String lockId = new String(columnUpdate.getValue(), UTF_8);
- try {
- lockHeld = ServiceLock.isLockHeld(zooCache, new
ZooUtil.LockID(zooRoot, lockId));
- } catch (Exception e) {
- log.debug("Failed to verify lock was held {} {}", lockId,
e.getMessage());
- }
+ try {
+ lockHeld = ServiceLock.isLockHeld(zooCache, new
ZooUtil.LockID(zooRoot, lockId));
+ } catch (Exception e) {
+ log.debug("Failed to verify lock was held {} {}", lockId,
e.getMessage());
+ }
- if (!lockHeld) {
- violations = addViolation(violations, 7);
+ if (!lockHeld) {
+ violations = addViolation(violations, 7);
+ }
+ } else if (column.equals(SuspendLocationColumn.SUSPEND_COLUMN)) {
+ try {
+ SuspendingTServer.fromValue(new Value(columnUpdate.getValue()));
+ } catch (IllegalArgumentException e) {
+ violations = addViolation(violations, 10);
+ }
}
}
}
@@ -379,6 +389,8 @@ public class MetadataConstraints implements Constraint {
return "Bulk load mutation contains either inconsistent files or
multiple fateTX ids";
case 9:
return "Invalid data file metadata format";
+ case 10:
+ return "Suspended timestamp is not valid";
}
return null;
}
diff --git
a/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java
b/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java
index b209a01f76..b7e2bd2a11 100644
---
a/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java
+++
b/server/base/src/test/java/org/apache/accumulo/server/constraints/MetadataConstraintsTest.java
@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
@@ -32,19 +33,25 @@ import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.metadata.AccumuloTable;
import org.apache.accumulo.core.metadata.StoredTabletFile;
+import org.apache.accumulo.core.metadata.SuspendingTServer;
+import org.apache.accumulo.core.metadata.TServerInstance;
import org.apache.accumulo.core.metadata.schema.DataFileValue;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.BulkFileColumnFamily;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CurrentLocationColumnFamily;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.DataFileColumnFamily;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ScanFileColumnFamily;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily;
+import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SuspendLocationColumn;
import
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily;
+import org.apache.accumulo.core.util.time.SteadyTime;
import org.apache.accumulo.server.ServerContext;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.easymock.EasyMock;
import org.junit.jupiter.api.Test;
+import com.google.common.net.HostAndPort;
+
public class MetadataConstraintsTest {
private SystemEnvironment createEnv() {
@@ -130,6 +137,32 @@ public class MetadataConstraintsTest {
}
+ @Test
+ public void testSuspensionCheck() {
+ Mutation m = new Mutation(new Text("0;foo"));
+ MetadataConstraints mc = new MetadataConstraints();
+ TServerInstance ser1 = new
TServerInstance(HostAndPort.fromParts("server1", 8555), "s001");
+
+ SuspendLocationColumn.SUSPEND_COLUMN.put(m, SuspendingTServer.toValue(ser1,
+ SteadyTime.from(System.currentTimeMillis(), TimeUnit.MILLISECONDS)));
+ List<Short> violations = mc.check(createEnv(), m);
+ assertNull(violations);
+
+ m = new Mutation(new Text("0;foo"));
+ SuspendLocationColumn.SUSPEND_COLUMN.put(m,
+ SuspendingTServer.toValue(ser1, SteadyTime.from(0,
TimeUnit.MILLISECONDS)));
+ violations = mc.check(createEnv(), m);
+ assertNull(violations);
+
+ m = new Mutation(new Text("0;foo"));
+ // We must encode manually since SteadyTime won't allow a negative
+ SuspendLocationColumn.SUSPEND_COLUMN.put(m, new Value(ser1.getHostPort() +
"|" + -1L));
+ violations = mc.check(createEnv(), m);
+ assertNotNull(violations);
+ assertEquals(1, violations.size());
+ assertEquals(Short.valueOf((short) 10), violations.get(0));
+ }
+
@Test
public void testBulkFileCheck() {
MetadataConstraints mc = new MetadataConstraints();