This is an automated email from the ASF dual-hosted git repository. ctubbsii 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 e9a531e840 Fix some code quality issues (#4934) e9a531e840 is described below commit e9a531e84046ae698768d29bb2c4331d80df047f Author: Christopher Tubbs <ctubb...@apache.org> AuthorDate: Wed Oct 2 14:30:48 2024 -0400 Fix some code quality issues (#4934) * Fix incorrect generics on AbstractFateTxStoreImpl (an unused generic type parameter was hiding the generic parameter from the FateTxStore interface); AbstractFateTxStoreImpl does not need, and should not have, a generic parameter of its own * Remove several unused variables and imports * Remove unrecognized nonstandard warning suppression UnstableApiUsage * Remove unused assignment in FateCleanerTest, keeping the side-effect * Suppress unused warnings about private no-arg constructors that exist only for GSon (I wonder if there's a better way to do this... perhaps with explicit type adaptors that use the regular constructors?) * Remove unused "parent" argument and field for ConditionalTabletMutatorImpl * Cast `tabletMutator` to concrete TabletMutatorImpl type, rather than the abstract generic `TabletMutatorBase` without a generic type parameter * Avoid compiler warning for unclosed AutoCloseable ServerContext in a lambda inside FindSplits by assigning to a final variable outside the lambda, and reusing it, rather than calling `manager.getContext()` twice * Substantial alterations to AmpleConditionalWriterIT in order to close all the unclosed AutoCloseable ConditionalTabletsMutatorImpl instances throughout the class; the actual implementation of this class' close method is empty currently, but it may not always be, and this resolves a bunch of unnecessary warnings about leaving them unclosed * Add missing default case to switch statement in MetricsIT * Remove a few unnecessary casts to `SortedMap<Key,Value>` * Fix BulkNewIT warning about unclosed ClientContext that was merely cast from the AccumuloClient; instead, cast it in the try-with-resources block instead --- .../accumulo/core/fate/AbstractFateStore.java | 2 +- .../apache/accumulo/core/fate/MetaFateStore.java | 2 +- .../accumulo/core/fate/WrappedFateTxStore.java | 2 - .../accumulo/core/fate/user/UserFateStore.java | 2 +- .../core/metadata/schema/UnSplittableMetadata.java | 1 - .../apache/accumulo/core/fate/FateCleanerTest.java | 3 +- .../manager/state/TabletManagementParameters.java | 1 + .../metadata/ConditionalTabletMutatorImpl.java | 6 +- .../metadata/ConditionalTabletsMutatorImpl.java | 3 +- .../accumulo/server/metadata/ServerAmpleImpl.java | 3 +- .../gc/GarbageCollectWriteAheadLogsTest.java | 2 - .../manager/metrics/fate/FateMetricValues.java | 4 - .../manager/tableOps/availability/LockTable.java | 3 - .../manager/tableOps/compact/CompactRange.java | 3 - .../accumulo/manager/tableOps/delete/CleanUp.java | 2 - .../manager/tableOps/split/FindSplits.java | 5 +- .../accumulo/manager/upgrade/Upgrader12to13.java | 1 - .../org/apache/accumulo/tserver/TabletServer.java | 3 - .../test/functional/AmpleConditionalWriterIT.java | 1182 ++++++++++---------- .../accumulo/test/functional/BinaryStressIT.java | 5 - .../apache/accumulo/test/functional/BulkNewIT.java | 19 +- .../accumulo/test/functional/LargeRowIT.java | 1 - .../test/functional/ManyWriteAheadLogsIT.java | 4 - .../apache/accumulo/test/functional/SplitIT.java | 9 +- .../apache/accumulo/test/metrics/MetricsIT.java | 2 + .../accumulo/test/performance/NullTserver.java | 7 - 26 files changed, 599 insertions(+), 678 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/fate/AbstractFateStore.java b/core/src/main/java/org/apache/accumulo/core/fate/AbstractFateStore.java index a499e07950..97b391e218 100644 --- a/core/src/main/java/org/apache/accumulo/core/fate/AbstractFateStore.java +++ b/core/src/main/java/org/apache/accumulo/core/fate/AbstractFateStore.java @@ -283,7 +283,7 @@ public abstract class AbstractFateStore<T> implements FateStore<T> { protected abstract FateTxStore<T> newUnreservedFateTxStore(FateId fateId); - protected abstract class AbstractFateTxStoreImpl<T> implements FateTxStore<T> { + protected abstract class AbstractFateTxStoreImpl implements FateTxStore<T> { protected final FateId fateId; protected boolean deleted; protected FateReservation reservation; diff --git a/core/src/main/java/org/apache/accumulo/core/fate/MetaFateStore.java b/core/src/main/java/org/apache/accumulo/core/fate/MetaFateStore.java index 555498d90d..08247e7441 100644 --- a/core/src/main/java/org/apache/accumulo/core/fate/MetaFateStore.java +++ b/core/src/main/java/org/apache/accumulo/core/fate/MetaFateStore.java @@ -225,7 +225,7 @@ public class MetaFateStore<T> extends AbstractFateStore<T> { return fateInstanceType; } - private class FateTxStoreImpl extends AbstractFateTxStoreImpl<T> { + private class FateTxStoreImpl extends AbstractFateTxStoreImpl { private FateTxStoreImpl(FateId fateId) { super(fateId); diff --git a/core/src/main/java/org/apache/accumulo/core/fate/WrappedFateTxStore.java b/core/src/main/java/org/apache/accumulo/core/fate/WrappedFateTxStore.java index bf0a35721c..f121a902e0 100644 --- a/core/src/main/java/org/apache/accumulo/core/fate/WrappedFateTxStore.java +++ b/core/src/main/java/org/apache/accumulo/core/fate/WrappedFateTxStore.java @@ -24,8 +24,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Optional; -import org.apache.accumulo.core.fate.ReadOnlyFateStore.TStatus; - public class WrappedFateTxStore<T> implements FateStore.FateTxStore<T> { protected final FateStore.FateTxStore<T> wrapped; diff --git a/core/src/main/java/org/apache/accumulo/core/fate/user/UserFateStore.java b/core/src/main/java/org/apache/accumulo/core/fate/user/UserFateStore.java index a008e67473..f1f82758ff 100644 --- a/core/src/main/java/org/apache/accumulo/core/fate/user/UserFateStore.java +++ b/core/src/main/java/org/apache/accumulo/core/fate/user/UserFateStore.java @@ -408,7 +408,7 @@ public class UserFateStore<T> extends AbstractFateStore<T> { return fateInstanceType; } - private class FateTxStoreImpl extends AbstractFateTxStoreImpl<T> { + private class FateTxStoreImpl extends AbstractFateTxStoreImpl { private FateTxStoreImpl(FateId fateId) { super(fateId); diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/UnSplittableMetadata.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/UnSplittableMetadata.java index 5c53c82952..a63b09b29a 100644 --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/UnSplittableMetadata.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/UnSplittableMetadata.java @@ -74,7 +74,6 @@ public class UnSplittableMetadata { return Base64.getEncoder().encodeToString(hashOfSplitParameters.asBytes()); } - @SuppressWarnings("UnstableApiUsage") private static HashCode calculateSplitParamsHash(KeyExtent keyExtent, long splitThreshold, long maxEndRowSize, int maxFilesToOpen, Set<StoredTabletFile> files) { Preconditions.checkArgument(splitThreshold > 0, "splitThreshold must be greater than 0"); diff --git a/core/src/test/java/org/apache/accumulo/core/fate/FateCleanerTest.java b/core/src/test/java/org/apache/accumulo/core/fate/FateCleanerTest.java index 8a6a69c70d..969a80deb6 100644 --- a/core/src/test/java/org/apache/accumulo/core/fate/FateCleanerTest.java +++ b/core/src/test/java/org/apache/accumulo/core/fate/FateCleanerTest.java @@ -20,6 +20,7 @@ package org.apache.accumulo.core.fate; import static java.util.stream.Collectors.toSet; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import java.time.Duration; @@ -288,7 +289,7 @@ public class FateCleanerTest { tts.time += Duration.ofHours(6).toNanos(); FateCleaner<String> cleaner1 = new FateCleaner<>(testStore, Duration.ofHours(10), tts); - FateId fateId1 = testStore.create(); + assertNotNull(testStore.create()); cleaner1.ageOff(); tts.time -= Duration.ofHours(3).toNanos(); // steady time going backwards should cause an error diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementParameters.java b/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementParameters.java index 6ccbe99f59..41a59986db 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementParameters.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementParameters.java @@ -251,6 +251,7 @@ public class TabletManagementParameters { } // Gson requires private constructor + @SuppressWarnings("unused") private JsonData() {} JsonData(TabletManagementParameters params) { diff --git a/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletMutatorImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletMutatorImpl.java index 18739f33e1..9978dbbe7c 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletMutatorImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletMutatorImpl.java @@ -75,7 +75,6 @@ public class ConditionalTabletMutatorImpl extends TabletMutatorBase<Ample.Condit private final ConditionalMutation mutation; private final Consumer<ConditionalMutation> mutationConsumer; - private final Ample.ConditionalTabletsMutator parent; private final BiConsumer<KeyExtent,Ample.RejectionHandler> rejectionHandlerConsumer; @@ -86,13 +85,12 @@ public class ConditionalTabletMutatorImpl extends TabletMutatorBase<Ample.Condit private boolean sawOperationRequirement = false; private boolean checkPrevEndRow = true; - protected ConditionalTabletMutatorImpl(Ample.ConditionalTabletsMutator parent, - ServerContext context, KeyExtent extent, Consumer<ConditionalMutation> mutationConsumer, + protected ConditionalTabletMutatorImpl(ServerContext context, KeyExtent extent, + Consumer<ConditionalMutation> mutationConsumer, BiConsumer<KeyExtent,Ample.RejectionHandler> rejectionHandlerConsumer) { super(new ConditionalMutation(extent.toMetaRow())); this.mutation = (ConditionalMutation) super.mutation; this.mutationConsumer = mutationConsumer; - this.parent = parent; this.rejectionHandlerConsumer = rejectionHandlerConsumer; this.extent = extent; this.context = context; diff --git a/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletsMutatorImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletsMutatorImpl.java index ffb47918bd..660453f299 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletsMutatorImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletsMutatorImpl.java @@ -93,8 +93,7 @@ public class ConditionalTabletsMutatorImpl implements Ample.ConditionalTabletsMu Preconditions.checkState(extents.putIfAbsent(extent.toMetaRow(), extent) == null, "Duplicate extents not handled %s", extent); - return new ConditionalTabletMutatorImpl(this, context, extent, mutations::add, - rejectedHandlers::put); + return new ConditionalTabletMutatorImpl(context, extent, mutations::add, rejectedHandlers::put); } protected ConditionalWriter createConditionalWriter(Ample.DataLevel dataLevel) diff --git a/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java index 2b39641b5e..dcea93dea9 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java @@ -50,7 +50,6 @@ import org.apache.accumulo.core.metadata.schema.AmpleImpl; import org.apache.accumulo.core.metadata.schema.MetadataSchema.BlipSection; import org.apache.accumulo.core.metadata.schema.MetadataSchema.DeletesSection; import org.apache.accumulo.core.metadata.schema.MetadataSchema.DeletesSection.SkewedKeyValue; -import org.apache.accumulo.core.metadata.schema.TabletMutatorBase; import org.apache.accumulo.core.security.Authorizations; import org.apache.accumulo.server.ServerContext; import org.apache.hadoop.io.Text; @@ -82,7 +81,7 @@ public class ServerAmpleImpl extends AmpleImpl implements Ample { public Ample.TabletMutator mutateTablet(KeyExtent extent) { TabletsMutator tmi = mutateTablets(); Ample.TabletMutator tabletMutator = tmi.mutateTablet(extent); - ((TabletMutatorBase) tabletMutator).setCloseAfterMutate(tmi); + ((TabletMutatorImpl) tabletMutator).setCloseAfterMutate(tmi); return tabletMutator; } diff --git a/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java b/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java index f868fd26d1..75707bb58c 100644 --- a/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java +++ b/server/gc/src/test/java/org/apache/accumulo/gc/GarbageCollectWriteAheadLogsTest.java @@ -37,7 +37,6 @@ import org.apache.accumulo.core.gc.thrift.GcCycleStats; import org.apache.accumulo.core.metadata.TServerInstance; import org.apache.accumulo.core.metadata.schema.TabletMetadata; import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; -import org.apache.accumulo.core.tabletserver.log.LogEntry; import org.apache.accumulo.core.util.Pair; import org.apache.accumulo.server.ServerContext; import org.apache.accumulo.server.fs.VolumeManager; @@ -60,7 +59,6 @@ public class GarbageCollectWriteAheadLogsTest { Collections.singletonMap(server2, Collections.singletonList(id)); private final Path path = new Path("hdfs://localhost:9000/accumulo/wal/localhost+1234/" + id); private final KeyExtent extent = KeyExtent.fromMetaRow(new Text("1<")); - private final List<LogEntry> walogs = Collections.emptyList(); private final TabletMetadata tabletAssignedToServer1; private final TabletMetadata tabletAssignedToServer2; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/metrics/fate/FateMetricValues.java b/server/manager/src/main/java/org/apache/accumulo/manager/metrics/fate/FateMetricValues.java index ea494bd44d..19ba624306 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/metrics/fate/FateMetricValues.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/metrics/fate/FateMetricValues.java @@ -27,8 +27,6 @@ import java.util.TreeMap; import org.apache.accumulo.core.fate.AdminUtil; import org.apache.accumulo.core.fate.ReadOnlyFateStore; import org.apache.accumulo.core.fate.ReadOnlyFateStore.TStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Immutable class that holds a snapshot of fate metric values - use builder to instantiate an @@ -36,8 +34,6 @@ import org.slf4j.LoggerFactory; */ public abstract class FateMetricValues { - private static final Logger log = LoggerFactory.getLogger(FateMetricValues.class); - protected final long updateTime; protected final long currentFateOps; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java index e6d099de1b..921a5502e0 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java @@ -29,12 +29,9 @@ import org.apache.accumulo.core.fate.zookeeper.DistributedReadWriteLock; import org.apache.accumulo.manager.Manager; import org.apache.accumulo.manager.tableOps.ManagerRepo; import org.apache.accumulo.manager.tableOps.Utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class LockTable extends ManagerRepo { private static final long serialVersionUID = 1L; - private static final Logger LOG = LoggerFactory.getLogger(LockTable.class); private final TableId tableId; private final NamespaceId namespaceId; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/compact/CompactRange.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/compact/CompactRange.java index bba52a18a1..ac0438f228 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/compact/CompactRange.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/compact/CompactRange.java @@ -43,13 +43,10 @@ import org.apache.accumulo.manager.tableOps.ManagerRepo; import org.apache.accumulo.manager.tableOps.Utils; import org.apache.accumulo.server.compaction.CompactionConfigStorage; import org.apache.hadoop.io.Text; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.collect.MoreCollectors; public class CompactRange extends ManagerRepo { - private static final Logger log = LoggerFactory.getLogger(CompactRange.class); private static final long serialVersionUID = 1L; private final TableId tableId; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/delete/CleanUp.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/delete/CleanUp.java index 9944c14265..142fe479d5 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/delete/CleanUp.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/delete/CleanUp.java @@ -59,8 +59,6 @@ class CleanUp extends ManagerRepo { private final TableId tableId; private final NamespaceId namespaceId; - private long creationTime; - public CleanUp(TableId tableId, NamespaceId namespaceId) { this.tableId = tableId; this.namespaceId = namespaceId; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/FindSplits.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/FindSplits.java index 1b790cc815..60073e987a 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/FindSplits.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/split/FindSplits.java @@ -117,11 +117,12 @@ public class FindSplits extends ManagerRepo { // Case 1: If a split is needed then set the unsplittable marker as no split // points could be found so that we don't keep trying again until the // split metadata is changed - if (SplitUtils.needsSplit(manager.getContext(), tabletMetadata)) { + final var context = manager.getContext(); + if (SplitUtils.needsSplit(context, tabletMetadata)) { log.info("Tablet {} needs to split, but no split points could be found.", tabletMetadata.getExtent()); var unSplittableMeta = computedUnsplittable - .orElseGet(() -> SplitUtils.toUnSplittable(manager.getContext(), tabletMetadata)); + .orElseGet(() -> SplitUtils.toUnSplittable(context, tabletMetadata)); // With the current design we don't need to require the files to be the same // for correctness as the TabletManagementIterator will detect the difference diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/upgrade/Upgrader12to13.java b/server/manager/src/main/java/org/apache/accumulo/manager/upgrade/Upgrader12to13.java index e2dce0ef8c..91dea17cd2 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/upgrade/Upgrader12to13.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/upgrade/Upgrader12to13.java @@ -257,7 +257,6 @@ public class Upgrader12to13 implements Upgrader { final String ZTABLE_COMPACT_CANCEL_ID = "/compact-cancel-id"; for (Entry<String,String> e : context.tableOperations().tableIdMap().entrySet()) { - final String tName = e.getKey(); final String tId = e.getValue(); final String zTablePath = zkRoot + Constants.ZTABLES + "/" + tId; zrw.delete(zTablePath + ZTABLE_COMPACT_ID); diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java index 1f600c5801..cb12d06359 100644 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java @@ -124,7 +124,6 @@ import org.apache.accumulo.server.log.WalStateManager.WalMarkerException; import org.apache.accumulo.server.rpc.ServerAddress; import org.apache.accumulo.server.rpc.TServerUtils; import org.apache.accumulo.server.rpc.ThriftProcessorTypes; -import org.apache.accumulo.server.security.SecurityOperation; import org.apache.accumulo.server.security.SecurityUtil; import org.apache.accumulo.server.security.delegation.ZooAuthenticationKeyWatcher; import org.apache.accumulo.server.util.time.RelativeTime; @@ -198,7 +197,6 @@ public class TabletServer extends AbstractServer implements TabletHostingServer final Map<KeyExtent,Long> recentlyUnloadedCache = Collections.synchronizedMap(new LRUMap<>(1000)); final TabletServerResourceManager resourceManager; - private final SecurityOperation security; private final BlockingDeque<ManagerMessage> managerMessages = new LinkedBlockingDeque<>(); @@ -326,7 +324,6 @@ public class TabletServer extends AbstractServer implements TabletHostingServer logger = new TabletServerLogger(this, walMaxSize, syncCounter, flushCounter, walCreationRetryFactory, walWritingRetryFactory, walMaxAge); this.resourceManager = new TabletServerResourceManager(context, this); - this.security = context.getSecurityOperation(); watchCriticalScheduledTask(context.getScheduledExecutor().scheduleWithFixedDelay( ClientTabletCache::clearInstances, jitter(), jitter(), TimeUnit.MILLISECONDS)); diff --git a/test/src/main/java/org/apache/accumulo/test/functional/AmpleConditionalWriterIT.java b/test/src/main/java/org/apache/accumulo/test/functional/AmpleConditionalWriterIT.java index ac3ce6da71..a343b94854 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/AmpleConditionalWriterIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/AmpleConditionalWriterIT.java @@ -163,23 +163,20 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertNull(context.getAmple().readTablet(e1).getLocation()); - var ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts1)).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts1)).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Location.future(ts1), context.getAmple().readTablet(e1).getLocation()); // test require absent with a future location set - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts2)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts2)).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Location.future(ts1), context.getAmple().readTablet(e1).getLocation()); - try (TabletsMetadata tablets = context.getAmple().readTablets().forTable(tid).filter(new HasCurrentFilter()).build()) { List<KeyExtent> actual = @@ -187,22 +184,20 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertEquals(List.of(), actual); } - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.future(ts1)) - .putLocation(Location.current(ts1)).deleteLocation(Location.future(ts1)) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.future(ts1)) + .putLocation(Location.current(ts1)).deleteLocation(Location.future(ts1)) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Location.current(ts1), context.getAmple().readTablet(e1).getLocation()); // test require absent with a current location set - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts2)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts2)).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Location.current(ts1), context.getAmple().readTablet(e1).getLocation()); try (TabletsMetadata tablets = @@ -212,79 +207,70 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertEquals(List.of(e1), actual); } - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.future(ts1)) - .putLocation(Location.current(ts1)).deleteLocation(Location.future(ts1)) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.future(ts1)) + .putLocation(Location.current(ts1)).deleteLocation(Location.future(ts1)) + .submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Location.current(ts1), context.getAmple().readTablet(e1).getLocation()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.future(ts2)) - .putLocation(Location.current(ts2)).deleteLocation(Location.future(ts2)) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.future(ts2)) + .putLocation(Location.current(ts2)).deleteLocation(Location.future(ts2)) + .submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Location.current(ts1), context.getAmple().readTablet(e1).getLocation()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.current(ts1)) - .deleteLocation(Location.current(ts1)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.current(ts1)) + .deleteLocation(Location.current(ts1)).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertNull(context.getAmple().readTablet(e1).getLocation()); // Set two current locations, this puts the tablet in a bad state as its only expected that // single location should be set - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().putLocation(Location.current(ts1)) - .putLocation(Location.current(ts2)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().putLocation(Location.current(ts1)) + .putLocation(Location.current(ts2)).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } // When a tablet has two locations reading it should throw an exception assertThrows(IllegalStateException.class, () -> context.getAmple().readTablet(e1)); // Try to update the tablet requiring one of the locations that is set on the tablet. Even // though the required location exists, the presence of the other location in the tablet // metadata should cause the update to fail. - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.current(ts1)) - .deleteLocation(Location.current(ts1)).deleteLocation(Location.current(ts2)) - .submit(tm -> false); - results = ctmi.process(); - var finalResult1 = results.get(e1); - // The update should be rejected because of the two locations. When a conditional mutation is - // rejected an attempt is made to read the tablet metadata and examine. This read of the - // tablet metadata will fail because the tablet has two locations. - assertThrows(IllegalStateException.class, finalResult1::getStatus); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(Location.current(ts1)) + .deleteLocation(Location.current(ts1)).deleteLocation(Location.current(ts2)) + .submit(tm -> false); + // The update should be rejected because of the two locations. When a conditional mutation + // is rejected an attempt is made to read the tablet metadata and examine. This read of the + // tablet metadata will fail because the tablet has two locations. + assertThrows(IllegalStateException.class, ctmi.process().get(e1)::getStatus); + } // tablet should still have two location set, so reading it should fail assertThrows(IllegalStateException.class, () -> context.getAmple().readTablet(e1)); // Requiring an absent location should fail when two locations are set - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .deleteLocation(Location.current(ts1)).deleteLocation(Location.current(ts2)) - .submit(tm -> false); - results = ctmi.process(); - var finalResult2 = results.get(e1); - assertThrows(IllegalStateException.class, finalResult2::getStatus); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .deleteLocation(Location.current(ts1)).deleteLocation(Location.current(ts2)) + .submit(tm -> false); + assertThrows(IllegalStateException.class, ctmi.process().get(e1)::getStatus); + } // tablet should still have two location set, so reading it should fail assertThrows(IllegalStateException.class, () -> context.getAmple().readTablet(e1)); - // Change the tablet to have a futre and current location set. - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().deleteLocation(Location.current(ts1)) - .putLocation(Location.future(ts1)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + // Change the tablet to have a future and current location set. + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().deleteLocation(Location.current(ts1)) + .putLocation(Location.future(ts1)).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } // tablet should still have two location set, so reading it should fail assertThrows(IllegalStateException.class, () -> context.getAmple().readTablet(e1)); @@ -293,35 +279,31 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { // required location does not exist. for (var loc : List.of(Location.current(ts1), Location.current(ts2), Location.future(ts1), Location.future(ts2))) { - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(loc) - .deleteLocation(Location.future(ts1)).deleteLocation(Location.current(ts2)) - .submit(tm -> false); - results = ctmi.process(); - var finalResult3 = results.get(e1); - // tablet should still have two location set, so reading it should fail - assertThrows(IllegalStateException.class, finalResult3::getStatus); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireLocation(loc) + .deleteLocation(Location.future(ts1)).deleteLocation(Location.current(ts2)) + .submit(tm -> false); + // tablet should still have two location set, so reading it should fail + assertThrows(IllegalStateException.class, ctmi.process().get(e1)::getStatus); + } } // Requiring an absent location should fail when a future and current location are set - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .deleteLocation(Location.current(ts1)).deleteLocation(Location.current(ts2)) - .submit(tm -> false); - results = ctmi.process(); - var finalResult4 = results.get(e1); - assertThrows(IllegalStateException.class, finalResult4::getStatus); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .deleteLocation(Location.current(ts1)).deleteLocation(Location.current(ts2)) + .submit(tm -> false); + assertThrows(IllegalStateException.class, ctmi.process().get(e1)::getStatus); + } // tablet should still have two location set, so reading it should fail assertThrows(IllegalStateException.class, () -> context.getAmple().readTablet(e1)); // Delete one of the locations w/o any location requirements, this should succeed. - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().deleteLocation(Location.future(ts1)) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().deleteLocation(Location.future(ts1)) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } // This check validates the expected state of the tablet as some of the previous test were // catching an exception and making assumption about the state of the tablet metadata based on // the fact that an exception was thrown. @@ -351,56 +333,54 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { System.out.println(context.getAmple().readTablet(e1).getLocation()); // simulate a compaction where the tablet location is not set - var ctmi = new ConditionalTabletsMutatorImpl(context); - - var tm1 = TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).putFile(stf3, dfv) - .build(); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, FILES) - .putFile(stf4, new DataFileValue(0, 0)).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + var tm1 = TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv) + .putFile(stf3, dfv).build(); + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, FILES) + .putFile(stf4, new DataFileValue(0, 0)).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(), context.getAmple().readTablet(e1).getFiles()); var tm2 = TabletMetadata.builder(e1).putLocation(Location.current(ts1)).build(); // simulate minor compacts where the tablet location is not set for (StoredTabletFile file : List.of(stf1, stf2, stf3)) { - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, LOCATION) - .putFile(file, new DataFileValue(0, 0)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, LOCATION) + .putFile(file, new DataFileValue(0, 0)).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } } assertEquals(Set.of(), context.getAmple().readTablet(e1).getFiles()); // set the location var tm3 = TabletMetadata.builder(e1).build(LOCATION); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm3, LOCATION) - .putLocation(Location.current(ts1)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm3, LOCATION) + .putLocation(Location.current(ts1)).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } var tm4 = TabletMetadata.builder(e1).putLocation(Location.current(ts2)).build(); // simulate minor compacts where the tablet location is wrong for (StoredTabletFile file : List.of(stf1, stf2, stf3)) { - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm4, LOCATION) - .putFile(file, new DataFileValue(0, 0)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm4, LOCATION) + .putFile(file, new DataFileValue(0, 0)).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } } assertEquals(Set.of(), context.getAmple().readTablet(e1).getFiles()); // simulate minor compacts where the tablet location is set for (StoredTabletFile file : List.of(stf1, stf2, stf3)) { - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, LOCATION) - .putFile(file, new DataFileValue(0, 0)).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, LOCATION) + .putFile(file, new DataFileValue(0, 0)).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); @@ -410,77 +390,73 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).build(), TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).putFile(stf3, dfv) .putFile(stf4, dfv).build())) { - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta, FILES) - .putFile(stf4, new DataFileValue(0, 0)).deleteFile(stf1).deleteFile(stf2) - .deleteFile(stf3).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta, FILES) + .putFile(stf4, new DataFileValue(0, 0)).deleteFile(stf1).deleteFile(stf2) + .deleteFile(stf3).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); } // simulate a compaction - ctmi = new ConditionalTabletsMutatorImpl(context); var tm5 = TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).putFile(stf3, dfv) .build(); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm5, FILES) - .putFile(stf4, new DataFileValue(0, 0)).deleteFile(stf1).deleteFile(stf2).deleteFile(stf3) - .submit(tm -> false); - results = ctmi.process(); - // First attempt should fail because the dfvs were replaced in the test - // so the values of the files will not match - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm5, FILES) + .putFile(stf4, new DataFileValue(0, 0)).deleteFile(stf1).deleteFile(stf2) + .deleteFile(stf3).submit(tm -> false); + // First attempt should fail because the dfvs were replaced in the test + // so the values of the files will not match + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } // Try again with the correct comapcted datafiles var compactedDv = new DataFileValue(0, 0); - ctmi = new ConditionalTabletsMutatorImpl(context); tm5 = TabletMetadata.builder(e1).putFile(stf1, compactedDv).putFile(stf2, compactedDv) .putFile(stf3, compactedDv).build(); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm5, FILES) - .putFile(stf4, new DataFileValue(0, 0)).deleteFile(stf1).deleteFile(stf2).deleteFile(stf3) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm5, FILES) + .putFile(stf4, new DataFileValue(0, 0)).deleteFile(stf1).deleteFile(stf2) + .deleteFile(stf3).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf4), context.getAmple().readTablet(e1).getFiles()); // simulate a bulk import var stf5 = StoredTabletFile .of(new Path("hdfs://localhost:8020/accumulo/tables/2a/b-0000009/I0000074.rf")); - ctmi = new ConditionalTabletsMutatorImpl(context); var tm6 = TabletMetadata.builder(e1).build(LOADED); FateInstanceType type = FateInstanceType.fromTableId(tid); FateId fateId = FateId.from(type, UUID.randomUUID()); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm6, LOADED) - .putFile(stf5, new DataFileValue(0, 0)).putBulkFile(stf5.getTabletFile(), fateId) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm6, LOADED) + .putFile(stf5, new DataFileValue(0, 0)).putBulkFile(stf5.getTabletFile(), fateId) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf4, stf5), context.getAmple().readTablet(e1).getFiles()); // simulate a compaction var stf6 = StoredTabletFile .of(new Path("hdfs://localhost:8020/accumulo/tables/2a/default_tablet/A0000075.rf")); - ctmi = new ConditionalTabletsMutatorImpl(context); var tm7 = TabletMetadata.builder(e1).putFile(stf4, compactedDv).putFile(stf5, compactedDv).build(); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm7, FILES) - .putFile(stf6, new DataFileValue(0, 0)).deleteFile(stf4).deleteFile(stf5) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm7, FILES) + .putFile(stf6, new DataFileValue(0, 0)).deleteFile(stf4).deleteFile(stf5) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf6), context.getAmple().readTablet(e1).getFiles()); // simulate trying to re bulk import file after a compaction - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm6, LOADED) - .putFile(stf5, new DataFileValue(0, 0)).putBulkFile(stf5.getTabletFile(), fateId) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm6, LOADED) + .putFile(stf5, new DataFileValue(0, 0)).putBulkFile(stf5.getTabletFile(), fateId) + .submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf6), context.getAmple().readTablet(e1).getFiles()); } } @@ -493,17 +469,16 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { String walFilePath = java.nio.file.Path.of("tserver+8080", UUID.randomUUID().toString()).toString(); final LogEntry originalLogEntry = LogEntry.fromPath(walFilePath); - ConditionalTabletsMutatorImpl ctmi = new ConditionalTabletsMutatorImpl(context); // create a tablet metadata with no write ahead logs var tmEmptySet = TabletMetadata.builder(e1).build(LOGS); // tablet should not have any logs to start with so requireSame with the empty logs should pass assertTrue(context.getAmple().readTablet(e1).getLogs().isEmpty()); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tmEmptySet, LOGS) - .putWal(originalLogEntry).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - Set<LogEntry> expectedLogs = new HashSet<>(); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tmEmptySet, LOGS) + .putWal(originalLogEntry).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } expectedLogs.add(originalLogEntry); assertEquals(expectedLogs, new HashSet<>(context.getAmple().readTablet(e1).getLogs()), "The original LogEntry should be present."); @@ -512,10 +487,10 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { String walFilePath2 = java.nio.file.Path.of("tserver+8080", UUID.randomUUID().toString()).toString(); LogEntry newLogEntry = LogEntry.fromPath(walFilePath2); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().putWal(newLogEntry).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().putWal(newLogEntry).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } // Verify that both the original and new WALs are present expectedLogs.add(newLogEntry); @@ -541,12 +516,11 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { subset.forEach(builder::putWal); TabletMetadata tmSubset = builder.build(LOGS); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tmSubset, LOGS) - .deleteWal(originalLogEntry).submit(t -> false); - results = ctmi.process(); - - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tmSubset, LOGS) + .deleteWal(originalLogEntry).submit(t -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } // ensure the operation did not go through actualLogs = new HashSet<>(context.getAmple().readTablet(e1).getLogs()); @@ -557,32 +531,31 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { // this example) TabletMetadata tm2 = TabletMetadata.builder(e1).putWal(originalLogEntry).putWal(newLogEntry).build(LOGS); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, LOGS) - .deleteWal(originalLogEntry).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus(), - "Requiring the current WALs should result in acceptance when making an update."); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, LOGS) + .deleteWal(originalLogEntry).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus(), + "Requiring the current WALs should result in acceptance when making an update."); + } // Verify that the update went through as expected assertEquals(List.of(newLogEntry), context.getAmple().readTablet(e1).getLogs(), "Only the new LogEntry should remain after deleting the original."); // test the requireAbsentLogs() function when logs are not present in the tablet metadata assertTrue(context.getAmple().readTablet(e2).getLogs().isEmpty()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLogs().putWal(originalLogEntry) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLogs().putWal(originalLogEntry) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e2).getStatus()); + } // test the requireAbsentLogs() function when logs are present in the tablet metadata assertFalse(context.getAmple().readTablet(e2).getLogs().isEmpty()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLogs().deleteWal(originalLogEntry) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLogs().deleteWal(originalLogEntry) + .submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e2).getStatus()); + } assertFalse(context.getAmple().readTablet(e2).getLogs().isEmpty()); } @@ -603,38 +576,35 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { System.out.println(context.getAmple().readTablet(e1).getLocation()); // simulate a compaction where the tablet location is not set - var ctmi = new ConditionalTabletsMutatorImpl(context); var tm1 = TabletMetadata.builder(e1).build(FILES, SELECTED); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, FILES).putFile(stf1, dfv) - .putFile(stf2, dfv).putFile(stf3, dfv).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, FILES).putFile(stf1, dfv) + .putFile(stf2, dfv).putFile(stf3, dfv).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); - ctmi = new ConditionalTabletsMutatorImpl(context); FateInstanceType type = FateInstanceType.fromTableId(tid); FateId fateId1 = FateId.from(type, UUID.randomUUID()); FateId fateId2 = FateId.from(type, UUID.randomUUID()); var time = SteadyTime.from(100_100, TimeUnit.NANOSECONDS); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, FILES, SELECTED) - .putSelectedFiles(new SelectedFiles(Set.of(stf1, stf2, stf3), true, fateId1, time)) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, FILES, SELECTED) + .putSelectedFiles(new SelectedFiles(Set.of(stf1, stf2, stf3), true, fateId1, time)) + .submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); assertNull(context.getAmple().readTablet(e1).getSelectedFiles()); var tm2 = TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).putFile(stf3, dfv) .build(SELECTED); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, FILES, SELECTED) - .putSelectedFiles(new SelectedFiles(Set.of(stf1, stf2, stf3), true, fateId1, time)) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm2, FILES, SELECTED) + .putSelectedFiles(new SelectedFiles(Set.of(stf1, stf2, stf3), true, fateId1, time)) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getSelectedFiles().getFiles()); @@ -651,12 +621,11 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { for (var selectedFiles : expectedToFail) { var tm3 = TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).putFile(stf3, dfv) .putSelectedFiles(selectedFiles).build(); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm3, FILES, SELECTED) - .deleteSelectedFiles().submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm3, FILES, SELECTED) + .deleteSelectedFiles().submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getSelectedFiles().getFiles()); @@ -664,12 +633,11 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { var tm5 = TabletMetadata.builder(e1).putFile(stf1, dfv).putFile(stf2, dfv).putFile(stf3, dfv) .putSelectedFiles(new SelectedFiles(Set.of(stf1, stf2, stf3), true, fateId1, time)).build(); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm5, FILES, SELECTED) - .deleteSelectedFiles().submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm5, FILES, SELECTED) + .deleteSelectedFiles().submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf1, stf2, stf3), context.getAmple().readTablet(e1).getFiles()); assertNull(context.getAmple().readTablet(e1).getSelectedFiles()); } @@ -696,15 +664,13 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { final SelectedFiles selectedFiles = new SelectedFiles(storedTabletFiles, initiallySelectedAll, fateId, time); - ConditionalTabletsMutatorImpl ctmi = new ConditionalTabletsMutatorImpl(context); - - // write the SelectedFiles to the keyextent - ctmi.mutateTablet(e1).requireAbsentOperation().putSelectedFiles(selectedFiles) - .submit(tm -> false); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + // write the SelectedFiles to the keyextent + ctmi.mutateTablet(e1).requireAbsentOperation().putSelectedFiles(selectedFiles) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } // verify we can read the selected files - Status mutationStatus = ctmi.process().get(e1).getStatus(); - assertEquals(Status.ACCEPTED, mutationStatus, "Failed to put selected files to tablet"); assertEquals(selectedFiles, context.getAmple().readTablet(e1).getSelectedFiles(), "Selected files should match those that were written"); @@ -759,22 +725,19 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertEquals(newJson, actualMetadataValue, "Value should be equal to the new json we manually wrote above"); - TabletMetadata tm1 = - TabletMetadata.builder(e1).putSelectedFiles(selectedFiles).build(SELECTED); - ctmi = new ConditionalTabletsMutatorImpl(context); + var tm1 = TabletMetadata.builder(e1).putSelectedFiles(selectedFiles).build(SELECTED); StoredTabletFile stf4 = StoredTabletFile.of(new Path(pathPrefix + "F0000073.rf")); // submit a mutation with the condition that the selected files match what was originally // written DataFileValue dfv = new DataFileValue(100, 100); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, SELECTED).putFile(stf4, dfv) - .submit(tm -> false); - - mutationStatus = ctmi.process().get(e1).getStatus(); - - // with a SortedFilesIterator attached to the Condition for SELECTED, the metadata should be - // re-ordered and once again match what was originally written meaning the conditional - // mutation should have been accepted and the file added should be present - assertEquals(Status.ACCEPTED, mutationStatus); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tm1, SELECTED).putFile(stf4, dfv) + .submit(tm -> false); + // with a SortedFilesIterator attached to the Condition for SELECTED, the metadata should be + // re-ordered and once again match what was originally written meaning the conditional + // mutation should have been accepted and the file added should be present + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(stf4), context.getAmple().readTablet(e1).getFiles(), "Expected to see the file that was added by the mutation"); } @@ -807,55 +770,51 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { var context = cluster.getServerContext(); - var ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts1)).submit(tm -> false); - ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts2)).submit(tm -> false); - var results = ctmi.process(); - - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts1)).submit(tm -> false); + ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts2)).submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + assertEquals(Set.of(e1, e2), results.keySet()); + } assertEquals(Location.future(ts1), context.getAmple().readTablet(e1).getLocation()); assertEquals(Location.future(ts2), context.getAmple().readTablet(e2).getLocation()); assertNull(context.getAmple().readTablet(e3).getLocation()); assertNull(context.getAmple().readTablet(e4).getLocation()); - assertEquals(Set.of(e1, e2), results.keySet()); - var e5 = new KeyExtent(tid, new Text("yz"), new Text("ya")); assertNull(context.getAmple().readTablet(e5)); // in addition to testing multiple tablets also testing requireAbsentTablet() which is // currently not called elsewhere in this IT - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts2)).submit(tm -> false); - ctmi.mutateTablet(e2).requireAbsentTablet().putLocation(Location.future(ts1)) - .submit(tm -> false); - ctmi.mutateTablet(e3).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts1)).submit(tm -> false); - ctmi.mutateTablet(e4).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts2)).submit(tm -> false); - ctmi.mutateTablet(e5).requireAbsentTablet().putDirName("t-54321") - .putPrevEndRow(e5.prevEndRow()).putTabletAvailability(TabletAvailability.ONDEMAND) - .submit(tm -> false); - results = ctmi.process(); - - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - assertEquals(Status.REJECTED, results.get(e2).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e4).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e5).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts2)).submit(tm -> false); + ctmi.mutateTablet(e2).requireAbsentTablet().putLocation(Location.future(ts1)) + .submit(tm -> false); + ctmi.mutateTablet(e3).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts1)).submit(tm -> false); + ctmi.mutateTablet(e4).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts2)).submit(tm -> false); + ctmi.mutateTablet(e5).requireAbsentTablet().putDirName("t-54321") + .putPrevEndRow(e5.prevEndRow()).putTabletAvailability(TabletAvailability.ONDEMAND) + .submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.REJECTED, results.get(e1).getStatus()); + assertEquals(Status.REJECTED, results.get(e2).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e4).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e5).getStatus()); + assertEquals(Set.of(e1, e2, e3, e4, e5), results.keySet()); + } assertEquals(Location.future(ts1), context.getAmple().readTablet(e1).getLocation()); assertEquals(Location.future(ts2), context.getAmple().readTablet(e2).getLocation()); assertEquals(Location.future(ts1), context.getAmple().readTablet(e3).getLocation()); assertEquals(Location.future(ts2), context.getAmple().readTablet(e4).getLocation()); assertEquals("t-54321", context.getAmple().readTablet(e5).getDirName()); - - assertEquals(Set.of(e1, e2, e3, e4, e5), results.keySet()); } } @@ -870,15 +829,15 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { var opid1 = TabletOperationId.from(TabletOperationType.SPLITTING, fateId1); var opid2 = TabletOperationId.from(TabletOperationType.MERGING, fateId2); - var ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().putOperation(opid1).submit(tm -> false); - ctmi.mutateTablet(e2).requireAbsentOperation().putOperation(opid2).submit(tm -> false); - ctmi.mutateTablet(e3).requireOperation(opid1).deleteOperation().submit(tm -> false); - var results = ctmi.process(); - - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); - assertEquals(Status.REJECTED, results.get(e3).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().putOperation(opid1).submit(tm -> false); + ctmi.mutateTablet(e2).requireAbsentOperation().putOperation(opid2).submit(tm -> false); + ctmi.mutateTablet(e3).requireOperation(opid1).deleteOperation().submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + assertEquals(Status.REJECTED, results.get(e3).getStatus()); + } assertEquals(TabletOperationType.SPLITTING, context.getAmple().readTablet(e1).getOperationId().getType()); assertEquals(opid1, context.getAmple().readTablet(e1).getOperationId()); @@ -887,25 +846,25 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertEquals(opid2, context.getAmple().readTablet(e2).getOperationId()); assertNull(context.getAmple().readTablet(e3).getOperationId()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireOperation(opid2).deleteOperation().submit(tm -> false); - ctmi.mutateTablet(e2).requireOperation(opid1).deleteOperation().submit(tm -> false); - results = ctmi.process(); - - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - assertEquals(Status.REJECTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireOperation(opid2).deleteOperation().submit(tm -> false); + ctmi.mutateTablet(e2).requireOperation(opid1).deleteOperation().submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.REJECTED, results.get(e1).getStatus()); + assertEquals(Status.REJECTED, results.get(e2).getStatus()); + } assertEquals(TabletOperationType.SPLITTING, context.getAmple().readTablet(e1).getOperationId().getType()); assertEquals(TabletOperationType.MERGING, context.getAmple().readTablet(e2).getOperationId().getType()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireOperation(opid1).deleteOperation().submit(tm -> false); - ctmi.mutateTablet(e2).requireOperation(opid2).deleteOperation().submit(tm -> false); - results = ctmi.process(); - - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireOperation(opid1).deleteOperation().submit(tm -> false); + ctmi.mutateTablet(e2).requireOperation(opid2).deleteOperation().submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + } assertNull(context.getAmple().readTablet(e1).getOperationId()); assertNull(context.getAmple().readTablet(e2).getOperationId()); } @@ -937,21 +896,22 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { // Test different compaction requirement scenarios for tablets w/o any compactions in the // metadata table - var ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMetaNoCompactions, ECOMP) - .putExternalCompaction(ecid1, ecMeta).submit(tm -> false); - ctmi.mutateTablet(e2).requireAbsentOperation().requireCompaction(ecid2) - .putExternalCompaction(ecid1, ecMeta).submit(tm -> false); - ctmi.mutateTablet(e3).requireAbsentOperation().requireSame(tabletMetaNoCompactions, ECOMP) - .putExternalCompaction(ecid1, ecMeta).putExternalCompaction(ecid2, ecMeta) - .submit(tm -> false); - ctmi.mutateTablet(e4).requireAbsentOperation().requireSame(tabletMetaCompactions, ECOMP) - .putExternalCompaction(ecid1, ecMeta).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.REJECTED, results.get(e2).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); - assertEquals(Status.REJECTED, results.get(e4).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMetaNoCompactions, ECOMP) + .putExternalCompaction(ecid1, ecMeta).submit(tm -> false); + ctmi.mutateTablet(e2).requireAbsentOperation().requireCompaction(ecid2) + .putExternalCompaction(ecid1, ecMeta).submit(tm -> false); + ctmi.mutateTablet(e3).requireAbsentOperation().requireSame(tabletMetaNoCompactions, ECOMP) + .putExternalCompaction(ecid1, ecMeta).putExternalCompaction(ecid2, ecMeta) + .submit(tm -> false); + ctmi.mutateTablet(e4).requireAbsentOperation().requireSame(tabletMetaCompactions, ECOMP) + .putExternalCompaction(ecid1, ecMeta).submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.REJECTED, results.get(e2).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); + assertEquals(Status.REJECTED, results.get(e4).getStatus()); + } assertEquals(Set.of(ecid1), context.getAmple().readTablet(e1).getExternalCompactions().keySet()); assertEquals(Set.of(), context.getAmple().readTablet(e2).getExternalCompactions().keySet()); @@ -961,14 +921,15 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { // Test compaction requirements that do not match the compaction ids that exists in the // metadata table. - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireCompaction(ecid2) - .deleteExternalCompaction(ecid1).submit(tm -> false); - ctmi.mutateTablet(e3).requireAbsentOperation().requireSame(tabletMetaCompactions, ECOMP) - .deleteExternalCompaction(ecid1).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - assertEquals(Status.REJECTED, results.get(e3).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireCompaction(ecid2) + .deleteExternalCompaction(ecid1).submit(tm -> false); + ctmi.mutateTablet(e3).requireAbsentOperation().requireSame(tabletMetaCompactions, ECOMP) + .deleteExternalCompaction(ecid1).submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.REJECTED, results.get(e1).getStatus()); + assertEquals(Status.REJECTED, results.get(e3).getStatus()); + } assertEquals(Set.of(ecid1), context.getAmple().readTablet(e1).getExternalCompactions().keySet()); assertEquals(Set.of(ecid1, ecid2), @@ -976,18 +937,18 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { // Test compaction requirements that match the compaction ids that exists in the metadata // table. - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMetaCompactions, ECOMP) - .deleteExternalCompaction(ecid1).submit(tm -> false); - ctmi.mutateTablet(e3).requireAbsentOperation().requireCompaction(ecid2) - .deleteExternalCompaction(ecid1).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMetaCompactions, ECOMP) + .deleteExternalCompaction(ecid1).submit(tm -> false); + ctmi.mutateTablet(e3).requireAbsentOperation().requireCompaction(ecid2) + .deleteExternalCompaction(ecid1).submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); + } assertEquals(Set.of(), context.getAmple().readTablet(e1).getExternalCompactions().keySet()); assertEquals(Set.of(ecid2), context.getAmple().readTablet(e3).getExternalCompactions().keySet()); - } } @@ -996,8 +957,6 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) { var context = cluster.getServerContext(); - var ctmi = new ConditionalTabletsMutatorImpl(context); - FateInstanceType type = FateInstanceType.fromTableId(tid); FateId fateId1 = FateId.from(type, UUID.randomUUID()); FateId fateId2 = FateId.from(type, UUID.randomUUID()); @@ -1006,65 +965,64 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { FateId fateId5 = FateId.from(type, UUID.randomUUID()); var tabletMeta1 = TabletMetadata.builder(e1).build(COMPACTED); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) - .putCompacted(fateId2) - .submit(tabletMetadata -> tabletMetadata.getCompacted().contains(fateId2)); - var tabletMeta2 = TabletMetadata.builder(e2).putCompacted(fateId1).build(COMPACTED); - ctmi.mutateTablet(e2).requireAbsentOperation().requireSame(tabletMeta2, COMPACTED) - .putCompacted(fateId3) - .submit(tabletMetadata -> tabletMetadata.getCompacted().contains(fateId3)); - - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.REJECTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) + .putCompacted(fateId2) + .submit(tabletMetadata -> tabletMetadata.getCompacted().contains(fateId2)); + var tabletMeta2 = TabletMetadata.builder(e2).putCompacted(fateId1).build(COMPACTED); + ctmi.mutateTablet(e2).requireAbsentOperation().requireSame(tabletMeta2, COMPACTED) + .putCompacted(fateId3) + .submit(tabletMetadata -> tabletMetadata.getCompacted().contains(fateId3)); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.REJECTED, results.get(e2).getStatus()); + } tabletMeta1 = context.getAmple().readTablet(e1); assertEquals(Set.of(fateId2), tabletMeta1.getCompacted()); assertEquals(Set.of(), context.getAmple().readTablet(e2).getCompacted()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) - .putCompacted(fateId4).putCompacted(fateId5).submit(tabletMetadata -> false); - - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) + .putCompacted(fateId4).putCompacted(fateId5).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } tabletMeta1 = context.getAmple().readTablet(e1); assertEquals(Set.of(fateId2, fateId4, fateId5), tabletMeta1.getCompacted()); // test require same with a superset - ctmi = new ConditionalTabletsMutatorImpl(context); tabletMeta1 = TabletMetadata.builder(e2).putCompacted(fateId2).putCompacted(fateId4) .putCompacted(fateId5).putCompacted(fateId1).build(COMPACTED); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) - .deleteCompacted(fateId2).deleteCompacted(fateId4).deleteCompacted(fateId5) - .submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) + .deleteCompacted(fateId2).deleteCompacted(fateId4).deleteCompacted(fateId5) + .submit(tabletMetadata -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(fateId2, fateId4, fateId5), context.getAmple().readTablet(e1).getCompacted()); // test require same with a subset - ctmi = new ConditionalTabletsMutatorImpl(context); tabletMeta1 = TabletMetadata.builder(e2).putCompacted(fateId2).putCompacted(fateId4).build(COMPACTED); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) - .deleteCompacted(fateId2).deleteCompacted(fateId4).deleteCompacted(fateId5) - .submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) + .deleteCompacted(fateId2).deleteCompacted(fateId4).deleteCompacted(fateId5) + .submit(tabletMetadata -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(fateId2, fateId4, fateId5), context.getAmple().readTablet(e1).getCompacted()); // now use the exact set the tablet has - ctmi = new ConditionalTabletsMutatorImpl(context); tabletMeta1 = TabletMetadata.builder(e2).putCompacted(fateId2).putCompacted(fateId4) .putCompacted(fateId5).build(COMPACTED); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) - .deleteCompacted(fateId2).deleteCompacted(fateId4).deleteCompacted(fateId5) - .submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, COMPACTED) + .deleteCompacted(fateId2).deleteCompacted(fateId4).deleteCompacted(fateId5) + .submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(), context.getAmple().readTablet(e1).getCompacted()); } } @@ -1083,27 +1041,27 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { TabletOperationId opid = TabletOperationId.from(TabletOperationType.MERGING, FateId.from(type, UUID.randomUUID())); - var ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(RootTable.EXTENT).requireAbsentOperation().requireAbsentLocation() - .putOperation(opid).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(RootTable.EXTENT).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(RootTable.EXTENT).requireAbsentOperation().requireAbsentLocation() + .putOperation(opid).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(RootTable.EXTENT).getStatus()); + } assertNull(context.getAmple().readTablet(RootTable.EXTENT).getOperationId()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(RootTable.EXTENT).requireAbsentOperation() - .requireLocation(Location.future(loc.getServerInstance())).putOperation(opid) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(RootTable.EXTENT).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(RootTable.EXTENT).requireAbsentOperation() + .requireLocation(Location.future(loc.getServerInstance())).putOperation(opid) + .submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(RootTable.EXTENT).getStatus()); + } assertNull(context.getAmple().readTablet(RootTable.EXTENT).getOperationId()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(RootTable.EXTENT).requireAbsentOperation() - .requireLocation(Location.current(loc.getServerInstance())).putOperation(opid) - .submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(RootTable.EXTENT).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(RootTable.EXTENT).requireAbsentOperation() + .requireLocation(Location.current(loc.getServerInstance())).putOperation(opid) + .submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(RootTable.EXTENT).getStatus()); + } assertEquals(opid.canonical(), context.getAmple().readTablet(RootTable.EXTENT).getOperationId().canonical()); } @@ -1115,24 +1073,24 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { for (var time : List.of(new MetadataTime(100, TimeType.LOGICAL), new MetadataTime(100, TimeType.MILLIS), new MetadataTime(0, TimeType.LOGICAL))) { - var ctmi = new ConditionalTabletsMutatorImpl(context); var tabletMeta1 = TabletMetadata.builder(e1).putTime(time).build(); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, TIME) - .putTime(new MetadataTime(101, TimeType.LOGICAL)).submit(tabletMetadata -> false); - var results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, TIME) + .putTime(new MetadataTime(101, TimeType.LOGICAL)).submit(tabletMetadata -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(new MetadataTime(0, TimeType.MILLIS), context.getAmple().readTablet(e1).getTime()); } for (int i = 0; i < 10; i++) { - var ctmi = new ConditionalTabletsMutatorImpl(context); var tabletMeta1 = TabletMetadata.builder(e1).putTime(new MetadataTime(i, TimeType.MILLIS)).build(); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, TIME) - .putTime(new MetadataTime(i + 1, TimeType.MILLIS)).submit(tabletMetadata -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, TIME) + .putTime(new MetadataTime(i + 1, TimeType.MILLIS)).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(new MetadataTime(i + 1, TimeType.MILLIS), context.getAmple().readTablet(e1).getTime()); } @@ -1144,82 +1102,80 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) { var context = cluster.getServerContext(); - var ctmi = new ConditionalTabletsMutatorImpl(context); - FateInstanceType type = FateInstanceType.fromTableId(tid); FateId fateId1 = FateId.from(type, UUID.randomUUID()); FateId fateId2 = FateId.from(type, UUID.randomUUID()); FateId fateId3 = FateId.from(type, UUID.randomUUID()); FateId fateId4 = FateId.from(type, UUID.randomUUID()); FateId fateId5 = FateId.from(type, UUID.randomUUID()); - var tabletMeta1 = TabletMetadata.builder(e1).build(USER_COMPACTION_REQUESTED); - ctmi.mutateTablet(e1).requireAbsentOperation() - .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED).putUserCompactionRequested(fateId2) - .submit(tabletMetadata -> tabletMetadata.getUserCompactionsRequested().contains(fateId2)); - var tabletMeta2 = TabletMetadata.builder(e2).putUserCompactionRequested(fateId1) - .build(USER_COMPACTION_REQUESTED); - ctmi.mutateTablet(e2).requireAbsentOperation() - .requireSame(tabletMeta2, USER_COMPACTION_REQUESTED).putUserCompactionRequested(fateId3) - .submit(tabletMetadata -> tabletMetadata.getUserCompactionsRequested().contains(fateId3)); - - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.REJECTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation() + .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED).putUserCompactionRequested(fateId2) + .submit( + tabletMetadata -> tabletMetadata.getUserCompactionsRequested().contains(fateId2)); + var tabletMeta2 = TabletMetadata.builder(e2).putUserCompactionRequested(fateId1) + .build(USER_COMPACTION_REQUESTED); + ctmi.mutateTablet(e2).requireAbsentOperation() + .requireSame(tabletMeta2, USER_COMPACTION_REQUESTED).putUserCompactionRequested(fateId3) + .submit( + tabletMetadata -> tabletMetadata.getUserCompactionsRequested().contains(fateId3)); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.REJECTED, results.get(e2).getStatus()); + } tabletMeta1 = context.getAmple().readTablet(e1); assertEquals(Set.of(fateId2), tabletMeta1.getUserCompactionsRequested()); assertEquals(Set.of(), context.getAmple().readTablet(e2).getUserCompactionsRequested()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation() - .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED).putUserCompactionRequested(fateId4) - .putUserCompactionRequested(fateId5).submit(tabletMetadata -> false); - - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation() + .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED).putUserCompactionRequested(fateId4) + .putUserCompactionRequested(fateId5).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } tabletMeta1 = context.getAmple().readTablet(e1); assertEquals(Set.of(fateId2, fateId4, fateId5), tabletMeta1.getUserCompactionsRequested()); // test require same with a superset - ctmi = new ConditionalTabletsMutatorImpl(context); tabletMeta1 = TabletMetadata.builder(e2).putUserCompactionRequested(fateId2) .putUserCompactionRequested(fateId4).putUserCompactionRequested(fateId5) .putUserCompactionRequested(fateId1).build(USER_COMPACTION_REQUESTED); - ctmi.mutateTablet(e1).requireAbsentOperation() - .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED) - .deleteUserCompactionRequested(fateId2).deleteUserCompactionRequested(fateId4) - .deleteUserCompactionRequested(fateId5).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation() + .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED) + .deleteUserCompactionRequested(fateId2).deleteUserCompactionRequested(fateId4) + .deleteUserCompactionRequested(fateId5).submit(tabletMetadata -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(fateId2, fateId4, fateId5), context.getAmple().readTablet(e1).getUserCompactionsRequested()); // test require same with a subset - ctmi = new ConditionalTabletsMutatorImpl(context); tabletMeta1 = TabletMetadata.builder(e2).putUserCompactionRequested(fateId2) .putUserCompactionRequested(fateId4).build(USER_COMPACTION_REQUESTED); - ctmi.mutateTablet(e1).requireAbsentOperation() - .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED) - .deleteUserCompactionRequested(fateId2).deleteUserCompactionRequested(fateId4) - .deleteUserCompactionRequested(fateId5).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation() + .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED) + .deleteUserCompactionRequested(fateId2).deleteUserCompactionRequested(fateId4) + .deleteUserCompactionRequested(fateId5).submit(tabletMetadata -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(fateId2, fateId4, fateId5), context.getAmple().readTablet(e1).getUserCompactionsRequested()); // now use the exact set the tablet has - ctmi = new ConditionalTabletsMutatorImpl(context); tabletMeta1 = TabletMetadata.builder(e2).putUserCompactionRequested(fateId2) .putUserCompactionRequested(fateId4).putUserCompactionRequested(fateId5) .build(USER_COMPACTION_REQUESTED); - ctmi.mutateTablet(e1).requireAbsentOperation() - .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED) - .deleteUserCompactionRequested(fateId2).deleteUserCompactionRequested(fateId4) - .deleteUserCompactionRequested(fateId5).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation() + .requireSame(tabletMeta1, USER_COMPACTION_REQUESTED) + .deleteUserCompactionRequested(fateId2).deleteUserCompactionRequested(fateId4) + .deleteUserCompactionRequested(fateId5).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(Set.of(), context.getAmple().readTablet(e1).getUserCompactionsRequested()); } } @@ -1269,7 +1225,6 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { @Test public void multipleFilters() { ServerContext context = cluster.getServerContext(); - ConditionalTabletsMutatorImpl ctmi; // make sure we read all tablets on table initially with no filters testFilterApplied(context, Set.of(), Set.of(e1, e2, e3, e4), @@ -1285,12 +1240,12 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { for (KeyExtent ke : tabletsWithWalCompactFlush) { FateInstanceType type = FateInstanceType.fromTableId(ke.tableId()); FateId fateId = FateId.from(type, UUID.randomUUID()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(ke).requireAbsentOperation().putCompacted(fateId) - .putFlushId(TestTabletMetadataFilter.VALID_FLUSH_ID).putWal(wal) - .submit(tabletMetadata -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(ke).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(ke).requireAbsentOperation().putCompacted(fateId) + .putFlushId(TestTabletMetadataFilter.VALID_FLUSH_ID).putWal(wal) + .submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(ke).getStatus()); + } } // check that applying a combination of filters returns only tablets that meet the criteria testFilterApplied(context, Set.of(new TestTabletMetadataFilter(), new GcWalsFilter(Set.of())), @@ -1301,11 +1256,11 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { // on a subset of the tablets, put a location final Set<KeyExtent> tabletsWithLocation = Set.of(e2, e3, e4); for (KeyExtent ke : tabletsWithLocation) { - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(ke).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.current(serverInstance)).submit(tabletMetadata -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(ke).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(ke).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.current(serverInstance)).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(ke).getStatus()); + } assertEquals(Location.current(serverInstance), context.getAmple().readTablet(ke).getLocation(), "Did not see expected location after adding it"); @@ -1323,48 +1278,50 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { @Test public void testCompactedAndFlushIdFilter() { ServerContext context = cluster.getServerContext(); - ConditionalTabletsMutatorImpl ctmi = new ConditionalTabletsMutatorImpl(context); Set<TabletMetadataFilter> filter = Set.of(new TestTabletMetadataFilter()); FateInstanceType type = FateInstanceType.fromTableId(tid); FateId fateId1 = FateId.from(type, UUID.randomUUID()); FateId fateId2 = FateId.from(type, UUID.randomUUID()); - // make sure we read all tablets on table initially with no filters - testFilterApplied(context, Set.of(), Set.of(e1, e2, e3, e4), - "Initially, all tablets should be present"); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + // make sure we read all tablets on table initially with no filters + testFilterApplied(context, Set.of(), Set.of(e1, e2, e3, e4), + "Initially, all tablets should be present"); + } - // Set compacted on e2 but with no flush ID - ctmi.mutateTablet(e2).requireAbsentOperation().putCompacted(fateId1) - .submit(tabletMetadata -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + // Set compacted on e2 but with no flush ID + ctmi.mutateTablet(e2).requireAbsentOperation().putCompacted(fateId1) + .submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e2).getStatus()); + } testFilterApplied(context, filter, Set.of(), "Compacted but no flush ID should return no tablets"); // Set incorrect flush ID on e2 - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e2).requireAbsentOperation().putFlushId(45L) - .submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e2).requireAbsentOperation().putFlushId(45L) + .submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e2).getStatus()); + } testFilterApplied(context, filter, Set.of(), "Compacted with incorrect flush ID should return no tablets"); // Set correct flush ID on e2 - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e2).requireAbsentOperation() - .putFlushId(TestTabletMetadataFilter.VALID_FLUSH_ID).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e2).requireAbsentOperation() + .putFlushId(TestTabletMetadataFilter.VALID_FLUSH_ID).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e2).getStatus()); + } testFilterApplied(context, filter, Set.of(e2), "Compacted with correct flush ID should return e2"); // Set compacted and correct flush ID on e3 - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e3).requireAbsentOperation().putCompacted(fateId2) - .putFlushId(TestTabletMetadataFilter.VALID_FLUSH_ID).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e3).requireAbsentOperation().putCompacted(fateId2) + .putFlushId(TestTabletMetadataFilter.VALID_FLUSH_ID).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e3).getStatus()); + } testFilterApplied(context, filter, Set.of(e2, e3), "Compacted with correct flush ID should return e2 and e3"); } @@ -1372,7 +1329,7 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { @Test public void walFilter() { ServerContext context = cluster.getServerContext(); - ConditionalTabletsMutatorImpl ctmi = new ConditionalTabletsMutatorImpl(context); + Set<TabletMetadataFilter> filter = Set.of(new GcWalsFilter(Set.of())); // make sure we read all tablets on table initially with no filters @@ -1380,33 +1337,35 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { "Initially, all tablets should be present"); // add a wal to e2 - String walFilePath = + var walFilePath = java.nio.file.Path.of("tserver+8080", UUID.randomUUID().toString()).toString(); - LogEntry wal = LogEntry.fromPath(walFilePath); - ctmi.mutateTablet(e2).requireAbsentOperation().putWal(wal).submit(tabletMetadata -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + var wal = LogEntry.fromPath(walFilePath); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e2).requireAbsentOperation().putWal(wal).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e2).getStatus()); + } // test that the filter works testFilterApplied(context, filter, Set.of(e2), "Only tablets with wals should be returned"); // add wal to tablet e4 - ctmi = new ConditionalTabletsMutatorImpl(context); walFilePath = java.nio.file.Path.of("tserver+8080", UUID.randomUUID().toString()).toString(); wal = LogEntry.fromPath(walFilePath); - ctmi.mutateTablet(e4).requireAbsentOperation().putWal(wal).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e4).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e4).requireAbsentOperation().putWal(wal).submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e4).getStatus()); + } // now, when using the wal filter, should see both e2 and e4 testFilterApplied(context, filter, Set.of(e2, e4), "Only tablets with wals should be returned"); // remove the wal from e4 - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e4).requireAbsentOperation().deleteWal(wal).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e4).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e4).requireAbsentOperation().deleteWal(wal) + .submit(tabletMetadata -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e4).getStatus()); + } // test that now only the tablet with a wal is returned when using filter() testFilterApplied(context, filter, Set.of(e2), "Only tablets with wals should be returned"); @@ -1414,20 +1373,21 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { var ts1 = new TServerInstance("localhost:9997", 5000L); var ts2 = new TServerInstance("localhost:9997", 6000L); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts1)).submit(tabletMetadata -> false); - ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.current(ts1)).submit(tabletMetadata -> false); - ctmi.mutateTablet(e3).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.future(ts2)).submit(tabletMetadata -> false); - ctmi.mutateTablet(e4).requireAbsentOperation().requireAbsentLocation() - .putLocation(Location.current(ts2)).submit(tabletMetadata -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e4).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts1)).submit(tabletMetadata -> false); + ctmi.mutateTablet(e2).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.current(ts1)).submit(tabletMetadata -> false); + ctmi.mutateTablet(e3).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.future(ts2)).submit(tabletMetadata -> false); + ctmi.mutateTablet(e4).requireAbsentOperation().requireAbsentLocation() + .putLocation(Location.current(ts2)).submit(tabletMetadata -> false); + var results = ctmi.process(); + assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e3).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e4).getStatus()); + } testFilterApplied(context, filter, Set.of(e1, e2, e3, e4), "All tablets should appear to be assigned to dead tservers and be returned"); @@ -1469,39 +1429,42 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertTrue(context.getAmple().readTablet(e1).getFlushId().isEmpty()); - var ctmi = new ConditionalTabletsMutatorImpl(context); - var tabletMeta1 = TabletMetadata.builder(e1).putFlushId(42L).build(); assertTrue(tabletMeta1.getFlushId().isPresent()); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, FLUSH_ID) - .putFlushId(43L).submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 43L); - var results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, FLUSH_ID) + .putFlushId(43L) + .submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 43L); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertTrue(context.getAmple().readTablet(e1).getFlushId().isEmpty()); - ctmi = new ConditionalTabletsMutatorImpl(context); var tabletMeta2 = TabletMetadata.builder(e1).build(FLUSH_ID); assertFalse(tabletMeta2.getFlushId().isPresent()); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta2, FLUSH_ID) - .putFlushId(43L).submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 43L); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta2, FLUSH_ID) + .putFlushId(43L) + .submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 43L); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(43L, context.getAmple().readTablet(e1).getFlushId().getAsLong()); - ctmi = new ConditionalTabletsMutatorImpl(context); var tabletMeta3 = TabletMetadata.builder(e1).putFlushId(43L).build(); - assertTrue(tabletMeta1.getFlushId().isPresent()); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta3, FLUSH_ID) - .putFlushId(44L).submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 44L); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + assertTrue(tabletMeta3.getFlushId().isPresent()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta3, FLUSH_ID) + .putFlushId(44L) + .submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 44L); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertEquals(44L, context.getAmple().readTablet(e1).getFlushId().getAsLong()); - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta3, FLUSH_ID) - .putFlushId(45L).submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 45L); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta3, FLUSH_ID) + .putFlushId(45L) + .submit(tabletMetadata -> tabletMetadata.getFlushId().orElse(-1) == 45L); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(44L, context.getAmple().readTablet(e1).getFlushId().getAsLong()); } } @@ -1675,17 +1638,17 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { assertEquals(TabletAvailability.ONDEMAND, context.getAmple().readTablet(e2).getTabletAvailability()); - var ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation() - .requireTabletAvailability(TabletAvailability.HOSTED) - .putTabletAvailability(TabletAvailability.UNHOSTED).submit(tm -> false); - ctmi.mutateTablet(e2).requireAbsentOperation() - .requireTabletAvailability(TabletAvailability.ONDEMAND) - .putTabletAvailability(TabletAvailability.UNHOSTED).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); - assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); - + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation() + .requireTabletAvailability(TabletAvailability.HOSTED) + .putTabletAvailability(TabletAvailability.UNHOSTED).submit(tm -> false); + ctmi.mutateTablet(e2).requireAbsentOperation() + .requireTabletAvailability(TabletAvailability.ONDEMAND) + .putTabletAvailability(TabletAvailability.UNHOSTED).submit(tm -> false); + var results = ctmi.process(); + assertEquals(Status.REJECTED, results.get(e1).getStatus()); + assertEquals(Status.ACCEPTED, results.get(e2).getStatus()); + } assertEquals(TabletAvailability.ONDEMAND, context.getAmple().readTablet(e1).getTabletAvailability()); assertEquals(TabletAvailability.UNHOSTED, @@ -1698,53 +1661,50 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) { var context = cluster.getServerContext(); - var ctmi = new ConditionalTabletsMutatorImpl(context); - var tabletMeta1 = TabletMetadata.builder(e1).build(UNSPLITTABLE); - // require the UNSPLITTABLE column to be absent when it is absent - UnSplittableMetadata usm1 = - UnSplittableMetadata.toUnSplittable(e1, 1000, 100000, 32, Set.of()); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, UNSPLITTABLE) - .setUnSplittable(usm1).submit(tm -> false); - var results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + var usm1 = UnSplittableMetadata.toUnSplittable(e1, 1000, 100000, 32, Set.of()); + + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, UNSPLITTABLE) + .setUnSplittable(usm1).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } var tabletMeta2 = context.getAmple().readTablet(e1); assertEquals(usm1.toBase64(), tabletMeta2.getUnSplittable().toBase64()); // require the UNSPLITTABLE column to be absent when it is not absent - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, UNSPLITTABLE) - .deleteUnSplittable().submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta1, UNSPLITTABLE) + .deleteUnSplittable().submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(usm1.toBase64(), context.getAmple().readTablet(e1).getUnSplittable().toBase64()); - UnSplittableMetadata usm2 = - UnSplittableMetadata.toUnSplittable(e1, 1001, 100001, 33, Set.of()); + var usm2 = UnSplittableMetadata.toUnSplittable(e1, 1001, 100001, 33, Set.of()); var tabletMeta3 = TabletMetadata.builder(e1).setUnSplittable(usm2).build(UNSPLITTABLE); // require the UNSPLITTABLE column to be usm2 when it is actually usm1 - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta3, UNSPLITTABLE) - .deleteUnSplittable().submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta3, UNSPLITTABLE) + .deleteUnSplittable().submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertEquals(usm1.toBase64(), context.getAmple().readTablet(e1).getUnSplittable().toBase64()); // require the UNSPLITTABLE column to be usm1 when it is actually usm1 - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta2, UNSPLITTABLE) - .deleteUnSplittable().submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.ACCEPTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta2, UNSPLITTABLE) + .deleteUnSplittable().submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + } assertNull(context.getAmple().readTablet(e1).getUnSplittable()); // require the UNSPLITTABLE column to be usm1 when it is actually absent - ctmi = new ConditionalTabletsMutatorImpl(context); - ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta2, UNSPLITTABLE) - .setUnSplittable(usm2).submit(tm -> false); - results = ctmi.process(); - assertEquals(Status.REJECTED, results.get(e1).getStatus()); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().requireSame(tabletMeta2, UNSPLITTABLE) + .setUnSplittable(usm2).submit(tm -> false); + assertEquals(Status.REJECTED, ctmi.process().get(e1).getStatus()); + } assertNull(context.getAmple().readTablet(e1).getUnSplittable()); } } @@ -1754,34 +1714,36 @@ public class AmpleConditionalWriterIT extends AccumuloClusterHarness { try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) { var context = cluster.getServerContext(); - var ctmi1 = new ConditionalTabletsMutatorImpl(context); - ctmi1.mutateTablet(e1).requireAbsentTablet().putDirName("d1").submit(tm -> false); - // making multiple updates for the same tablet is not supported - assertThrows(IllegalStateException.class, - () -> ctmi1.mutateTablet(e1).requireAbsentTablet().putDirName("d2").submit(tm -> false)); - // attempt to use a column that requireSame does not support - TabletMetadata tabletMetadata = TabletMetadata.builder(e2).build(); - assertThrows(UnsupportedOperationException.class, - () -> ctmi1.mutateTablet(e2).requireAbsentOperation() - .requireSame(tabletMetadata, HOSTING_REQUESTED).putDirName("d2").submit(tm -> false)); - - var ctmi2 = new ConditionalTabletsMutatorImpl(context); - // the following end prev end row update should cause a constraint violation because a tablets - // prev end row must be less than its end row - ctmi2.mutateTablet(e1).requireAbsentOperation().putPrevEndRow(e1.endRow()) - .submit(tm -> false); - var results = ctmi2.process(); - // getting status when a constraint violation happened should throw an exception - assertThrows(IllegalStateException.class, () -> results.get(e1).getStatus()); - - var ctmi3 = new ConditionalTabletsMutatorImpl(context); - ctmi3.mutateTablet(e1).requireAbsentOperation().putFlushNonce(1234).submit(tm -> false); - var results2 = ctmi3.process(); - assertEquals(Status.ACCEPTED, results2.get(e1).getStatus()); - - // attempting to use after calling proccess() should throw an exception - assertThrows(IllegalStateException.class, () -> ctmi3.mutateTablet(e1) - .requireAbsentOperation().putFlushNonce(1234).submit(tm -> false)); + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentTablet().putDirName("d1").submit(tm -> false); + // making multiple updates for the same tablet is not supported + assertThrows(IllegalStateException.class, + () -> ctmi.mutateTablet(e1).requireAbsentTablet().putDirName("d2").submit(tm -> false)); + // attempt to use a column that requireSame does not support + TabletMetadata tabletMetadata = TabletMetadata.builder(e2).build(); + assertThrows(UnsupportedOperationException.class, + () -> ctmi.mutateTablet(e2).requireAbsentOperation() + .requireSame(tabletMetadata, HOSTING_REQUESTED).putDirName("d2") + .submit(tm -> false)); + } + + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + // the following end prev end row update should cause a constraint violation because a + // tablet's prev end row must be less than its end row + ctmi.mutateTablet(e1).requireAbsentOperation().putPrevEndRow(e1.endRow()) + .submit(tm -> false); + // getting status when a constraint violation happened should throw an exception + assertThrows(IllegalStateException.class, () -> ctmi.process().get(e1).getStatus()); + } + + try (var ctmi = new ConditionalTabletsMutatorImpl(context)) { + ctmi.mutateTablet(e1).requireAbsentOperation().putFlushNonce(1234).submit(tm -> false); + assertEquals(Status.ACCEPTED, ctmi.process().get(e1).getStatus()); + + // attempting to use after calling proccess() should throw an exception + assertThrows(IllegalStateException.class, () -> ctmi.mutateTablet(e1) + .requireAbsentOperation().putFlushNonce(1234).submit(tm -> false)); + } } } } diff --git a/test/src/main/java/org/apache/accumulo/test/functional/BinaryStressIT.java b/test/src/main/java/org/apache/accumulo/test/functional/BinaryStressIT.java index 670547379b..1d9b7ea8eb 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/BinaryStressIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/BinaryStressIT.java @@ -20,7 +20,6 @@ package org.apache.accumulo.test.functional; import java.time.Duration; import java.util.HashSet; -import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -57,8 +56,6 @@ public class BinaryStressIT extends AccumuloClusterHarness { cfg.setProperty(Property.TSERV_MAXMEM, "50K"); } - private String majcDelay, maxMem; - @BeforeEach public void alterConfig() throws Exception { if (getClusterType() == ClusterType.MINI) { @@ -66,8 +63,6 @@ public class BinaryStressIT extends AccumuloClusterHarness { } try (AccumuloClient client = Accumulo.newClient().from(getClientProps()).build()) { InstanceOperations iops = client.instanceOperations(); - Map<String,String> conf = iops.getSystemConfiguration(); - maxMem = conf.get(Property.TSERV_MAXMEM.getKey()); iops.setProperty(Property.TSERV_MAXMEM.getKey(), "50K"); 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 27b5f80879..df256d2499 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 @@ -222,29 +222,28 @@ public class BulkNewIT extends SharedMiniClusterBase { @Test public void testSetTime() throws Exception { - try (AccumuloClient client = Accumulo.newClient().from(getClientProps()).build()) { + try (var client = (ClientContext) Accumulo.newClient().from(getClientProps()).build()) { tableName = "testSetTime_table1"; NewTableConfiguration newTableConf = new NewTableConfiguration(); // set logical time type so we can set time on bulk import newTableConf.setTimeType(TimeType.LOGICAL); client.tableOperations().create(tableName, newTableConf); - var ctx = (ClientContext) client; - - var tablet = ctx.getAmple().readTablet(new KeyExtent(ctx.getTableId(tableName), null, null)); + var tablet = + client.getAmple().readTablet(new KeyExtent(client.getTableId(tableName), null, null)); assertEquals(new MetadataTime(0, TimeType.LOGICAL), tablet.getTime()); - var extent = new KeyExtent(ctx.getTableId(tableName), new Text("0333"), null); + var extent = new KeyExtent(client.getTableId(tableName), new Text("0333"), null); testSingleTabletSingleFile(client, false, true, () -> { // Want to test with and without a location, assuming the tablet does not have a location // now. Need to validate that assumption. - assertNull(ctx.getAmple().readTablet(extent).getLocation()); + assertNull(client.getAmple().readTablet(extent).getLocation()); return null; }); assertEquals(new MetadataTime(1, TimeType.LOGICAL), - ctx.getAmple().readTablet(extent).getTime()); + client.getAmple().readTablet(extent).getTime()); int added = 0; try (var writer = client.createBatchWriter(tableName); @@ -263,7 +262,7 @@ public class BulkNewIT extends SharedMiniClusterBase { // Writes to a tablet should not change time unless it flushes, so time in metadata table // should be the same assertEquals(new MetadataTime(1, TimeType.LOGICAL), - ctx.getAmple().readTablet(extent).getTime()); + client.getAmple().readTablet(extent).getTime()); // verify data written by batch writer overwrote bulk imported data try (var scanner = client.createScanner(tableName)) { @@ -298,13 +297,13 @@ public class BulkNewIT extends SharedMiniClusterBase { // the bulk import should update the time in the metadata table assertEquals(new MetadataTime(2 + added, TimeType.LOGICAL), - ctx.getAmple().readTablet(extent).getTime()); + client.getAmple().readTablet(extent).getTime()); client.tableOperations().flush(tableName, null, null, true); // the flush should not change the time in the metadata table assertEquals(new MetadataTime(2 + added, TimeType.LOGICAL), - ctx.getAmple().readTablet(extent).getTime()); + client.getAmple().readTablet(extent).getTime()); try (var scanner = client.createScanner("accumulo.metadata")) { scanner.forEach((k, v) -> System.out.println(k + " " + v)); diff --git a/test/src/main/java/org/apache/accumulo/test/functional/LargeRowIT.java b/test/src/main/java/org/apache/accumulo/test/functional/LargeRowIT.java index 8aa3360be3..715f47f470 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/LargeRowIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/LargeRowIT.java @@ -78,7 +78,6 @@ public class LargeRowIT extends AccumuloClusterHarness { private String REG_TABLE_NAME; private String PRE_SPLIT_TABLE_NAME; private int timeoutFactor = 1; - private String tservMajcDelay; @BeforeEach public void getTimeoutFactor() throws Exception { diff --git a/test/src/main/java/org/apache/accumulo/test/functional/ManyWriteAheadLogsIT.java b/test/src/main/java/org/apache/accumulo/test/functional/ManyWriteAheadLogsIT.java index aa2d54d298..1beb80c7af 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/ManyWriteAheadLogsIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/ManyWriteAheadLogsIT.java @@ -53,8 +53,6 @@ public class ManyWriteAheadLogsIT extends AccumuloClusterHarness { private static final Logger log = LoggerFactory.getLogger(ManyWriteAheadLogsIT.class); - private String walSize; - @Override public void configureMiniCluster(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) { // configure a smaller wal size so the wals will roll frequently in the test @@ -78,8 +76,6 @@ public class ManyWriteAheadLogsIT extends AccumuloClusterHarness { } try (AccumuloClient client = Accumulo.newClient().from(getClientProps()).build()) { InstanceOperations iops = client.instanceOperations(); - Map<String,String> conf = iops.getSystemConfiguration(); - walSize = conf.get(Property.TSERV_WAL_MAX_SIZE.getKey()); iops.setProperty(Property.TSERV_WAL_MAX_SIZE.getKey(), "1M"); getClusterControl().stopAllServers(ServerType.TABLET_SERVER); diff --git a/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java b/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java index f444eababe..cee49c3756 100644 --- a/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java +++ b/test/src/main/java/org/apache/accumulo/test/functional/SplitIT.java @@ -39,7 +39,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.SortedMap; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.Callable; @@ -104,7 +103,7 @@ public class SplitIT extends AccumuloClusterHarness { cfg.setMemory(ServerType.TABLET_SERVER, 384, MemoryUnit.MEGABYTE); } - private String tservMaxMem, tservMajcDelay; + private String tservMaxMem; @BeforeEach public void alterConfig() throws Exception { @@ -115,12 +114,10 @@ public class SplitIT extends AccumuloClusterHarness { tservMaxMem = config.get(Property.TSERV_MAXMEM.getKey()); // Property.TSERV_MAXMEM can't be altered on a running server - boolean restarted = false; if (!tservMaxMem.equals("5K")) { iops.setProperty(Property.TSERV_MAXMEM.getKey(), "5K"); getCluster().getClusterControl().stopAllServers(ServerType.TABLET_SERVER); getCluster().getClusterControl().startAllServers(ServerType.TABLET_SERVER); - restarted = true; } } } @@ -555,7 +552,7 @@ public class SplitIT extends AccumuloClusterHarness { // remove the srv:lock column for tests as this will change // because we are changing the metadata from the IT. - var original = (SortedMap<Key,Value>) tabletMetadata.getKeyValues().stream() + var original = tabletMetadata.getKeyValues().stream() .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a1, b1) -> b1, TreeMap::new)); assertTrue(original.keySet().removeIf(LOCK_COLUMN::hasColumns)); @@ -570,7 +567,7 @@ public class SplitIT extends AccumuloClusterHarness { assertEquals(extent, tabletMetadata.getExtent()); // tablet should have an operation id set, but nothing else changed - var kvCopy = (SortedMap<Key,Value>) tabletMetadata2.getKeyValues().stream() + var kvCopy = tabletMetadata2.getKeyValues().stream() .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> b, TreeMap::new)); assertTrue(kvCopy.keySet().removeIf(LOCK_COLUMN::hasColumns)); assertTrue(kvCopy.keySet().removeIf(OPID_COLUMN::hasColumns)); diff --git a/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java b/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java index 42706273f6..7880f4f8b2 100644 --- a/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java +++ b/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java @@ -202,6 +202,8 @@ public class MetricsIT extends ConfigurableMacBase implements MetricsProducer { case COMPACTOR_JOB_PRIORITY_QUEUE_JOBS_PRIORITY: queueMetricsSeen.set(compactionPriorityQueuePriorityBit, true); break; + default: + break; } } else { // completely unexpected metric diff --git a/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java b/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java index f428aaf4de..f15968e09f 100644 --- a/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java +++ b/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java @@ -35,9 +35,6 @@ import org.apache.accumulo.core.clientImpl.thrift.TInfo; import org.apache.accumulo.core.conf.DefaultConfiguration; import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.conf.SiteConfiguration; -import org.apache.accumulo.core.data.Range; -import org.apache.accumulo.core.data.TableId; -import org.apache.accumulo.core.dataImpl.KeyExtent; import org.apache.accumulo.core.dataImpl.thrift.InitialMultiScan; import org.apache.accumulo.core.dataImpl.thrift.InitialScan; import org.apache.accumulo.core.dataImpl.thrift.IterInfo; @@ -361,10 +358,7 @@ public class NullTserver { context.setServiceLock(miniLock); HostAndPort addr = HostAndPort.fromParts(InetAddress.getLocalHost().getHostName(), opts.port); - TableId tableId = context.getTableId(opts.tableName); - // read the locations for the table - Range tableRange = new KeyExtent(tableId, null, null).toMetaRange(); List<Assignment> assignments = new ArrayList<>(); try (var tablets = context.getAmple().readTablets().forLevel(DataLevel.USER).build()) { long randomSessionID = opts.port; @@ -377,7 +371,6 @@ public class NullTserver { } } // point them to this server - final ServiceLock lock = miniLock; TabletStateStore store = TabletStateStore.getStoreForLevel(DataLevel.USER, context); store.setLocations(assignments);