This is an automated email from the ASF dual-hosted git repository.
krathbun pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/3.1 by this push:
new de2ae7fd3d Reorganizes MetadataConstraints (#4852)
de2ae7fd3d is described below
commit de2ae7fd3dc1b8b39e012c213b9c9e05dd78509e
Author: Kevin Rathbun <[email protected]>
AuthorDate: Mon Sep 16 10:26:00 2024 -0400
Reorganizes MetadataConstraints (#4852)
- new class `BulkFileColData` to store the data needed to validate a
BulkFileColumn update
Changes to check():
- now uses switch instead of if
- validation logic of each column now done in separate methods
- removed unnecessary checks and simplified logic where applicable (e.g.,
if checks that would never be true, same check done more than once)
- violations are no longer added to and returned by `validate` methods,
only added to. Avoids confusion with how the methods should be used.
- initialized violations at start as a list instead of dealing with
null. Null added extra unnecessary complexity.
---
.../server/constraints/BulkFileColData.java | 77 ++++
.../server/constraints/MetadataConstraints.java | 443 +++++++++++----------
.../server/metadata/RootTabletMutatorImpl.java | 2 +-
.../constraints/MetadataConstraintsTest.java | 41 +-
.../apache/accumulo/test/functional/BulkNewIT.java | 3 +-
5 files changed, 342 insertions(+), 224 deletions(-)
diff --git
a/server/base/src/main/java/org/apache/accumulo/server/constraints/BulkFileColData.java
b/server/base/src/main/java/org/apache/accumulo/server/constraints/BulkFileColData.java
new file mode 100644
index 0000000000..6533f8a19a
--- /dev/null
+++
b/server/base/src/main/java/org/apache/accumulo/server/constraints/BulkFileColData.java
@@ -0,0 +1,77 @@
+/*
+ * 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
+ *
+ * https://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.server.constraints;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.core.metadata.StoredTabletFile;
+
+/**
+ * Data needed to validate a BulkFileColumn update
+ */
+class BulkFileColData {
+ private boolean isSplitMutation, isLocationMutation;
+ private final Set<StoredTabletFile> dataFiles, loadedFiles;
+ private final Set<String> tidsSeen;
+
+ BulkFileColData() {
+ isSplitMutation = false;
+ isLocationMutation = false;
+ dataFiles = new HashSet<>();
+ loadedFiles = new HashSet<>();
+ tidsSeen = new HashSet<>();
+ }
+
+ void setIsSplitMutation(boolean b) {
+ isSplitMutation = b;
+ }
+
+ boolean getIsSplitMutation() {
+ return isSplitMutation;
+ }
+
+ void setIsLocationMutation(boolean b) {
+ isLocationMutation = b;
+ }
+
+ boolean getIsLocationMutation() {
+ return isLocationMutation;
+ }
+
+ void addDataFile(StoredTabletFile stf) {
+ dataFiles.add(stf);
+ }
+
+ void addLoadedFile(StoredTabletFile stf) {
+ loadedFiles.add(stf);
+ }
+
+ boolean dataFilesEqualsLoadedFiles() {
+ return dataFiles.equals(loadedFiles);
+ }
+
+ void addTidSeen(String tid) {
+ tidsSeen.add(tid);
+ }
+
+ Set<String> getTidsSeen() {
+ return tidsSeen;
+ }
+}
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 da7acdda64..c3ca7bdd4a 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
@@ -21,10 +21,11 @@ package org.apache.accumulo.server.constraints;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.function.Consumer;
import org.apache.accumulo.core.data.ColumnUpdate;
import org.apache.accumulo.core.data.Mutation;
@@ -62,6 +63,7 @@ import org.slf4j.LoggerFactory;
public class MetadataConstraints implements Constraint {
private static final Logger log =
LoggerFactory.getLogger(MetadataConstraints.class);
+ private static final byte[] BULK_COL_BYTES =
BulkFileColumnFamily.STR_NAME.getBytes(UTF_8);
private ZooCache zooCache = null;
private String zooRoot = null;
@@ -113,246 +115,115 @@ public class MetadataConstraints implements Constraint {
return validColumnQuals.contains(new ColumnFQ(cu));
}
- private static ArrayList<Short> addViolation(ArrayList<Short> lst, int
violation) {
- if (lst == null) {
- lst = new ArrayList<>();
- }
+ private static void addViolation(ArrayList<Short> lst, int violation) {
lst.add((short) violation);
- return lst;
}
- private static ArrayList<Short> addIfNotPresent(ArrayList<Short> lst, int
intViolation) {
- if (lst == null) {
- return addViolation(null, intViolation);
- }
- short violation = (short) intViolation;
- if (!lst.contains(violation)) {
- return addViolation(lst, intViolation);
+ private static void addIfNotPresent(ArrayList<Short> lst, int violation) {
+ if (!lst.contains((short) violation)) {
+ addViolation(lst, violation);
}
- return lst;
}
/*
* Validates the data file metadata is valid for a StoredTabletFile.
*/
- private static ArrayList<Short> validateDataFileMetadata(ArrayList<Short>
violations,
- String metadata) {
+ private static void validateDataFileMetadata(ArrayList<Short> violations,
String metadata,
+ Consumer<StoredTabletFile> stfConsumer) {
try {
- StoredTabletFile.validate(metadata);
+ stfConsumer.accept(StoredTabletFile.of(metadata));
} catch (RuntimeException e) {
- violations = addViolation(violations, 9);
+ addViolation(violations, 9);
}
- return violations;
}
+ /**
+ * Same as defined in {@link Constraint#check(Environment, Mutation)}, but
returns an empty list
+ * instead of null if there are no violations
+ *
+ * @param env constraint environment
+ * @param mutation mutation to check
+ * @return list of violations, or empty list if no violations
+ */
@Override
public List<Short> check(Environment env, Mutation mutation) {
final ServerContext context = ((SystemEnvironment) env).getServerContext();
-
- ArrayList<Short> violations = null;
-
- Collection<ColumnUpdate> colUpdates = mutation.getUpdates();
-
- // check the row, it should contains at least one ; or end with <
- boolean containsSemiC = false;
-
- byte[] row = mutation.getRow();
-
- // always allow rows that fall within reserved areas
- if (row.length > 0 && row[0] == '~') {
- return null;
- }
-
- for (byte b : row) {
- if (b == ';') {
- containsSemiC = true;
- }
-
- if (b == ';' || b == '<') {
- break;
- }
-
- if (!validTableNameChars[0xff & b]) {
- violations = addIfNotPresent(violations, 4);
- }
- }
-
- if (containsSemiC) {
- if (row.length == 0) {
- violations = addIfNotPresent(violations, 4);
- }
+ final ArrayList<Short> violations = new ArrayList<>();
+ final Collection<ColumnUpdate> colUpdates = mutation.getUpdates();
+ final byte[] row = mutation.getRow();
+ final List<ColumnUpdate> bulkFileColUpdates;
+ final BulkFileColData bfcValidationData;
+
+ // avoids creating unnecessary objects
+ if (hasBulkCol(colUpdates)) {
+ bulkFileColUpdates = new ArrayList<>();
+ bfcValidationData = new BulkFileColData();
} else {
- // see if last row char is <
- if (row.length == 0 || row[row.length - 1] != '<') {
- violations = addIfNotPresent(violations, 4);
- }
+ bulkFileColUpdates = null;
+ bfcValidationData = null;
}
- if (row.length > 0 && row[0] == '!') {
- if (row.length < 3 || row[1] != '0' || (row[2] != '<' && row[2] != ';'))
{
- violations = addIfNotPresent(violations, 4);
- }
- }
-
- // ensure row is not less than Constants.METADATA_TABLE_ID
- if (new Text(row).compareTo(new
Text(AccumuloTable.METADATA.tableId().canonical())) < 0) {
- violations = addViolation(violations, 5);
+ // always allow rows that fall within reserved areas
+ if (row.length > 0 && row[0] == '~') {
+ return violations;
}
- boolean checkedBulk = false;
+ validateTabletRow(violations, row);
for (ColumnUpdate columnUpdate : colUpdates) {
- Text columnFamily = new Text(columnUpdate.getColumnFamily());
+ String colFamStr = new String(columnUpdate.getColumnFamily(), UTF_8);
if (columnUpdate.isDeleted()) {
if (!isValidColumn(columnUpdate)) {
- violations = addViolation(violations, 2);
+ addViolation(violations, 2);
}
continue;
}
- if (columnUpdate.getValue().length == 0 &&
!(columnFamily.equals(ScanFileColumnFamily.NAME)
- || columnFamily.equals(LogColumnFamily.NAME))) {
- violations = addViolation(violations, 6);
- }
-
- if (columnFamily.equals(DataFileColumnFamily.NAME)) {
- violations = validateDataFileMetadata(violations,
- new String(columnUpdate.getColumnQualifier(), UTF_8));
-
- try {
- DataFileValue dfv = new DataFileValue(columnUpdate.getValue());
+ validateColValLen(violations, columnUpdate);
- if (dfv.getSize() < 0 || dfv.getNumEntries() < 0) {
- violations = addViolation(violations, 1);
- }
- } catch (NumberFormatException | ArrayIndexOutOfBoundsException nfe) {
- violations = addViolation(violations, 1);
- }
- } else if (columnFamily.equals(ScanFileColumnFamily.NAME)) {
- violations = validateDataFileMetadata(violations,
- new String(columnUpdate.getColumnQualifier(), UTF_8));
- } else if (columnFamily.equals(BulkFileColumnFamily.NAME)) {
- if (!columnUpdate.isDeleted() && !checkedBulk) {
- /*
- * This needs to be re-worked after Issue
https://github.com/apache/accumulo/issues/3505
- * is done.
- *
- * That issue will reorganizes this class and make things more
efficient so we are not
- * looping over the same mutation more than once like in this case.
The below check is
- * commented out for now because the violation check is already done
when creating
- * StoredTabletFiles so it isn't needed here anymore violations =
- * validateDataFileMetadata(violations, new
String(columnUpdate.getColumnQualifier(),
- * UTF_8));
- */
-
- // splits, which also write the time reference, are allowed to write
this reference even
- // when
- // the transaction is not running because the other half of the
tablet is holding a
- // reference
- // to the file.
- boolean isSplitMutation = false;
+ switch (colFamStr) {
+ case TabletColumnFamily.STR_NAME:
+ validateTabletFamily(violations, columnUpdate, mutation);
+ break;
+ case ServerColumnFamily.STR_NAME:
+ validateServerFamily(violations, columnUpdate, context,
bfcValidationData);
+ break;
+ case CurrentLocationColumnFamily.STR_NAME:
// When a tablet is assigned, it re-writes the metadata. It should
probably only update
- // the location information,
- // but it writes everything. We allow it to re-write the bulk
information if it is setting
- // the location.
+ // the location information, but it writes everything. We allow it
to re-write the bulk
+ // information if it is setting the location.
// See ACCUMULO-1230.
- boolean isLocationMutation = false;
-
- HashSet<StoredTabletFile> dataFiles = new HashSet<>();
- HashSet<StoredTabletFile> loadedFiles = new HashSet<>();
-
- String tidString = new String(columnUpdate.getValue(), UTF_8);
- int otherTidCount = 0;
-
- for (ColumnUpdate update : mutation.getUpdates()) {
- if (new
ColumnFQ(update).equals(ServerColumnFamily.DIRECTORY_COLUMN)) {
- isSplitMutation = true;
- } else if (new Text(update.getColumnFamily())
- .equals(CurrentLocationColumnFamily.NAME)) {
- isLocationMutation = true;
- } else if (new
Text(update.getColumnFamily()).equals(DataFileColumnFamily.NAME)) {
- try {
- // This actually validates for a second time as the loop
already validates
- // if a DataFileColumnFamily, this will likely be fixed as
part of
- // https://github.com/apache/accumulo/issues/3505
- dataFiles.add(StoredTabletFile.of(new
Text(update.getColumnQualifier())));
- } catch (RuntimeException e) {
- violations = addViolation(violations, 9);
- }
- } else if (new
Text(update.getColumnFamily()).equals(BulkFileColumnFamily.NAME)) {
- try {
- loadedFiles.add(StoredTabletFile.of(new
Text(update.getColumnQualifier())));
- } catch (RuntimeException e) {
- violations = addViolation(violations, 9);
- }
-
- if (!new String(update.getValue(), UTF_8).equals(tidString)) {
- otherTidCount++;
- }
- }
+ if (bfcValidationData != null) {
+ bfcValidationData.setIsLocationMutation(true);
}
-
- if (!isSplitMutation && !isLocationMutation) {
- if (otherTidCount > 0 || !dataFiles.equals(loadedFiles)) {
- violations = addViolation(violations, 8);
- }
+ break;
+ case SuspendLocationColumn.STR_NAME:
+ validateSuspendLocationFamily(violations, columnUpdate);
+ break;
+ case BulkFileColumnFamily.STR_NAME:
+ // defer validating the bulk file column updates until the end
(relies on checks done
+ // on other column updates)
+ if (bulkFileColUpdates != null) {
+ bulkFileColUpdates.add(columnUpdate);
}
-
- checkedBulk = true;
- }
- } else {
- if (!isValidColumn(columnUpdate)) {
- violations = addViolation(violations, 2);
- } 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()));
-
- boolean prevEndRowLessThanEndRow =
- per == null || ke.endRow() == null ||
per.compareTo(ke.endRow()) < 0;
-
- 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();
- }
-
- 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());
- }
-
- 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);
- }
+ break;
+ case DataFileColumnFamily.STR_NAME:
+ validateDataFileFamily(violations, columnUpdate, bfcValidationData);
+ break;
+ case ScanFileColumnFamily.STR_NAME:
+ validateScanFileFamily(violations, columnUpdate);
+ break;
+ default:
+ if (!isValidColumn(columnUpdate)) {
+ addViolation(violations, 2);
}
- }
}
}
- if (violations != null) {
+ validateBulkFileFamily(violations, bulkFileColUpdates, bfcValidationData);
+
+ if (!violations.isEmpty()) {
log.debug("violating metadata mutation : {}", new
String(mutation.getRow(), UTF_8));
for (ColumnUpdate update : mutation.getUpdates()) {
log.debug(" update: {}:{} value {}", new
String(update.getColumnFamily(), UTF_8),
@@ -392,4 +263,174 @@ public class MetadataConstraints implements Constraint {
return null;
}
+ private void validateColValLen(ArrayList<Short> violations, ColumnUpdate
columnUpdate) {
+ Text columnFamily = new Text(columnUpdate.getColumnFamily());
+ if (columnUpdate.getValue().length == 0 &&
!(columnFamily.equals(ScanFileColumnFamily.NAME)
+ || columnFamily.equals(LogColumnFamily.NAME))) {
+ addViolation(violations, 6);
+ }
+ }
+
+ private void validateTabletRow(ArrayList<Short> violations, byte[] row) {
+ // check the row, it should contain at least one ";" or end with "<". Row
should also
+ // not be less than AccumuloTable.METADATA.tableId().
+ boolean containsSemiC = false;
+
+ for (byte b : row) {
+ if (b == ';') {
+ containsSemiC = true;
+ }
+
+ if (b == ';' || b == '<') {
+ break;
+ }
+
+ if (!validTableNameChars[0xff & b]) {
+ addIfNotPresent(violations, 4);
+ }
+ }
+
+ if (!containsSemiC) {
+ // see if last row char is <
+ if (row.length == 0 || row[row.length - 1] != '<') {
+ addIfNotPresent(violations, 4);
+ }
+ }
+
+ if (row.length > 0 && row[0] == '!') {
+ if (row.length < 3 || row[1] != '0' || (row[2] != '<' && row[2] != ';'))
{
+ addIfNotPresent(violations, 4);
+ }
+ }
+
+ // ensure row is not less than AccumuloTable.METADATA.tableId()
+ if (Arrays.compare(row,
AccumuloTable.METADATA.tableId().canonical().getBytes(UTF_8)) < 0) {
+ addViolation(violations, 5);
+ }
+ }
+
+ private void validateTabletFamily(ArrayList<Short> violations, ColumnUpdate
columnUpdate,
+ Mutation mutation) {
+ String qualStr = new String(columnUpdate.getColumnQualifier(), UTF_8);
+
+ if (qualStr.equals(TabletColumnFamily.PREV_ROW_QUAL)) {
+ if (columnUpdate.getValue().length > 0 && !violations.contains((short)
4)) {
+ KeyExtent ke = KeyExtent.fromMetaRow(new Text(mutation.getRow()));
+ Text per = TabletColumnFamily.decodePrevEndRow(new
Value(columnUpdate.getValue()));
+ boolean prevEndRowLessThanEndRow =
+ per == null || ke.endRow() == null || per.compareTo(ke.endRow()) <
0;
+
+ if (!prevEndRowLessThanEndRow) {
+ addViolation(violations, 3);
+ }
+ }
+ }
+ }
+
+ private void validateServerFamily(ArrayList<Short> violations, ColumnUpdate
columnUpdate,
+ ServerContext context, BulkFileColData bfcValidationData) {
+ String qualStr = new String(columnUpdate.getColumnQualifier(), UTF_8);
+
+ switch (qualStr) {
+ case ServerColumnFamily.LOCK_QUAL:
+ if (zooCache == null) {
+ zooCache = new ZooCache(context.getZooReader(), null);
+ CleanerUtil.zooCacheClearer(this, zooCache);
+ }
+
+ if (zooRoot == null) {
+ zooRoot = context.getZooKeeperRoot();
+ }
+
+ 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());
+ }
+
+ if (!lockHeld) {
+ addViolation(violations, 7);
+ }
+ break;
+ case ServerColumnFamily.DIRECTORY_QUAL:
+ // splits, which also write the time reference, are allowed to write
this reference
+ // even when the transaction is not running because the other half of
the tablet is
+ // holding a reference to the file.
+ if (bfcValidationData != null) {
+ bfcValidationData.setIsSplitMutation(true);
+ }
+ break;
+ }
+ }
+
+ private void validateSuspendLocationFamily(ArrayList<Short> violations,
+ ColumnUpdate columnUpdate) {
+ String qualStr = new String(columnUpdate.getColumnQualifier(), UTF_8);
+ String suspendColQualStr =
+ new
String(SuspendLocationColumn.SUSPEND_COLUMN.getColumnQualifier().getBytes(),
UTF_8);
+
+ if (qualStr.equals(suspendColQualStr)) {
+ try {
+ SuspendingTServer.fromValue(new Value(columnUpdate.getValue()));
+ } catch (IllegalArgumentException e) {
+ addViolation(violations, 10);
+ }
+ }
+ }
+
+ private void validateDataFileFamily(ArrayList<Short> violations,
ColumnUpdate columnUpdate,
+ BulkFileColData bfcValidationData) {
+ Consumer<StoredTabletFile> stfConsumer =
+ bfcValidationData == null ? stf -> {} : bfcValidationData::addDataFile;
+ validateDataFileMetadata(violations, new
String(columnUpdate.getColumnQualifier(), UTF_8),
+ stfConsumer);
+
+ try {
+ DataFileValue dfv = new DataFileValue(columnUpdate.getValue());
+
+ if (dfv.getSize() < 0 || dfv.getNumEntries() < 0) {
+ addViolation(violations, 1);
+ }
+ } catch (NumberFormatException | ArrayIndexOutOfBoundsException nfe) {
+ addViolation(violations, 1);
+ }
+ }
+
+ private void validateScanFileFamily(ArrayList<Short> violations,
ColumnUpdate columnUpdate) {
+ validateDataFileMetadata(violations, new
String(columnUpdate.getColumnQualifier(), UTF_8),
+ stf -> {});
+ }
+
+ private void validateBulkFileFamily(ArrayList<Short> violations,
+ Collection<ColumnUpdate> bulkFileColUpdates, BulkFileColData
bfcValidationData) {
+ if (bulkFileColUpdates != null && !bulkFileColUpdates.isEmpty()) {
+ for (ColumnUpdate bulkFileColUpdate : bulkFileColUpdates) {
+ validateDataFileMetadata(violations,
+ new String(bulkFileColUpdate.getColumnQualifier(), UTF_8),
+ bfcValidationData::addLoadedFile);
+
+ bfcValidationData.addTidSeen(new String(bulkFileColUpdate.getValue(),
UTF_8));
+ }
+
+ if (!bfcValidationData.getIsSplitMutation() &&
!bfcValidationData.getIsLocationMutation()) {
+ if (bfcValidationData.getTidsSeen().size() > 1
+ || !bfcValidationData.dataFilesEqualsLoadedFiles()) {
+ addViolation(violations, 8);
+ }
+ }
+ }
+ }
+
+ private boolean hasBulkCol(Collection<ColumnUpdate> colUpdates) {
+ for (ColumnUpdate colUpdate : colUpdates) {
+ if (Arrays.equals(colUpdate.getColumnFamily(), BULK_COL_BYTES)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
diff --git
a/server/base/src/main/java/org/apache/accumulo/server/metadata/RootTabletMutatorImpl.java
b/server/base/src/main/java/org/apache/accumulo/server/metadata/RootTabletMutatorImpl.java
index 7ebdd7db92..85c5992b4f 100644
---
a/server/base/src/main/java/org/apache/accumulo/server/metadata/RootTabletMutatorImpl.java
+++
b/server/base/src/main/java/org/apache/accumulo/server/metadata/RootTabletMutatorImpl.java
@@ -83,7 +83,7 @@ public class RootTabletMutatorImpl extends TabletMutatorBase
implements Ample.Ta
MetadataConstraints metaConstraint = new MetadataConstraints();
List<Short> violations = metaConstraint.check(new RootEnv(context),
mutation);
- if (violations != null && !violations.isEmpty()) {
+ if (!violations.isEmpty()) {
throw new IllegalStateException(
"Mutation for root tablet metadata violated constraints : " +
violations);
}
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 b8e7cf38a1..4d69ebd8a6 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
@@ -19,8 +19,9 @@
package org.apache.accumulo.server.constraints;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.Method;
import java.util.Base64;
@@ -71,7 +72,7 @@ public class MetadataConstraintsTest {
List<Short> violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(Short.valueOf((short) 3), violations.get(0));
@@ -80,7 +81,7 @@ public class MetadataConstraintsTest {
violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(Short.valueOf((short) 4), violations.get(0));
@@ -89,7 +90,7 @@ public class MetadataConstraintsTest {
violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(Short.valueOf((short) 2), violations.get(0));
@@ -98,7 +99,7 @@ public class MetadataConstraintsTest {
violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(2, violations.size());
assertEquals(Short.valueOf((short) 4), violations.get(0));
assertEquals(Short.valueOf((short) 5), violations.get(1));
@@ -108,7 +109,7 @@ public class MetadataConstraintsTest {
violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(Short.valueOf((short) 6), violations.get(0));
@@ -117,21 +118,21 @@ public class MetadataConstraintsTest {
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
m = new Mutation(new Text(AccumuloTable.METADATA.tableId().canonical() +
"<"));
TabletColumnFamily.PREV_ROW_COLUMN.put(m, new Value("bar"));
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
m = new Mutation(new Text("!1<"));
TabletColumnFamily.PREV_ROW_COLUMN.put(m, new Value("bar"));
violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(Short.valueOf((short) 4), violations.get(0));
@@ -146,19 +147,19 @@ public class MetadataConstraintsTest {
SuspendLocationColumn.SUSPEND_COLUMN.put(m, SuspendingTServer.toValue(ser1,
SteadyTime.from(System.currentTimeMillis(), TimeUnit.MILLISECONDS)));
List<Short> violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
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);
+ assertTrue(violations.isEmpty());
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);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(Short.valueOf((short) 10), violations.get(0));
}
@@ -180,7 +181,7 @@ public class MetadataConstraintsTest {
.of(new
Path("hdfs://1.2.3.4/accumulo/tables/2a/t-0003/someFile")).getMetadataText(),
new DataFileValue(1, 1).encodeAsValue());
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
// loaded marker w/o file
m = new Mutation(new Text("0;foo"));
@@ -209,7 +210,7 @@ public class MetadataConstraintsTest {
.of(new
Path("hdfs://1.2.3.4/accumulo/tables/2a/t-0003/someFile2")).getMetadataText(),
new DataFileValue(1, 1).encodeAsValue());
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
// two files w/ different txid
m = new Mutation(new Text("0;foo"));
@@ -255,7 +256,7 @@ public class MetadataConstraintsTest {
new Value("5"));
ServerColumnFamily.DIRECTORY_COLUMN.put(m, new Value("/t1"));
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
// mutation that looks like a load
m = new Mutation(new Text("0;foo"));
@@ -265,14 +266,14 @@ public class MetadataConstraintsTest {
new Value("5"));
m.put(CurrentLocationColumnFamily.NAME, new Text("789"), new
Value("127.0.0.1:9997"));
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
// deleting a load flag
m = new Mutation(new Text("0;foo"));
m.putDelete(BulkFileColumnFamily.NAME, StoredTabletFile
.of(new
Path("hdfs://1.2.3.4/accumulo/tables/2a/t-0003/someFile")).getMetadataText());
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
// Missing beginning of path
m = new Mutation(new Text("0;foo"));
@@ -460,7 +461,7 @@ public class MetadataConstraintsTest {
.of(new
Path("hdfs://1.2.3.4/accumulo/tables/2a/t-0003/someFile")).getMetadataText(),
new DataFileValue(1, 1).encodeAsValue());
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
// Should pass validation with range set
m = new Mutation(new Text("0;foo"));
@@ -469,7 +470,7 @@ public class MetadataConstraintsTest {
new Range("a", false, "b", true)).getMetadataText(),
new DataFileValue(1, 1).encodeAsValue());
violations = mc.check(createEnv(), m);
- assertNull(violations);
+ assertTrue(violations.isEmpty());
assertNotNull(mc.getViolationDescription((short) 9));
}
@@ -488,7 +489,7 @@ public class MetadataConstraintsTest {
private void assertViolation(MetadataConstraints mc, Mutation m, Short
violation) {
List<Short> violations = mc.check(createEnv(), m);
- assertNotNull(violations);
+ assertFalse(violations.isEmpty());
assertEquals(1, violations.size());
assertEquals(violation, violations.get(0));
assertNotNull(mc.getViolationDescription(violations.get(0)));
diff --git
a/test/src/main/java/org/apache/accumulo/test/functional/BulkNewIT.java
b/test/src/main/java/org/apache/accumulo/test/functional/BulkNewIT.java
index 06fdb6945f..ee9d418b68 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/BulkNewIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/BulkNewIT.java
@@ -24,7 +24,6 @@ import static
org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType
import static
org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -723,7 +722,7 @@ public class BulkNewIT extends SharedMiniClusterBase {
m.put("", "", NoBulkConstratint.CANARY_VALUE);
// This test assume the metadata constraint check will not flag this
mutation, the following
// validates this assumption.
- assertNull(metaConstraints.check(env, m));
+ assertTrue(metaConstraints.check(env, m).isEmpty());
bw.addMutation(m);
return false;
} catch (MutationsRejectedException e) {