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 56e0253a86 Improve deprecated property resolution (#2730) 56e0253a86 is described below commit 56e0253a86534b662a47913785925baf489cb4ac Author: Christopher Tubbs <ctubb...@apache.org> AuthorDate: Wed Jun 1 14:04:48 2022 -0400 Improve deprecated property resolution (#2730) * Improve deprecated property resolution Resolve a sequence of deprecation changes, instead of just a single deprecation with a replacement (for example, if property A is deprecated and replaced with property B, then B is deprecated and replaced with C, we'd resolve like: ```java resolve(C, B, A); ``` rather than: ```java resolve(C, resolve(B, A)); ``` Also: * To avoid errors, ensure that the current property isn't deprecated * Check that the deprecated properties are actually deprecated * Add a unit test case * Update the javadoc * Don't make method final (messes with EasyMock) --- .../accumulo/core/conf/AccumuloConfiguration.java | 27 ++++++++++---- .../core/conf/AccumuloConfigurationTest.java | 41 ++++++++++++++++++++++ .../org/apache/accumulo/tserver/log/DfsLogger.java | 13 ++++--- .../org/apache/accumulo/tserver/tablet/Tablet.java | 6 ++-- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java b/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java index 17b48ab7b4..7652db531f 100644 --- a/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java +++ b/core/src/main/java/org/apache/accumulo/core/conf/AccumuloConfiguration.java @@ -35,6 +35,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -94,14 +95,28 @@ public abstract class AccumuloConfiguration implements Iterable<Entry<String,Str public abstract String get(Property property); /** - * Given a property and a deprecated property determine which one to use base on which one is set. + * Given a property that is not deprecated and an ordered list of deprecated properties, determine + * which one to use based on which is set by the user in the configuration. If the non-deprecated + * property is set, use that. Otherwise, use the first deprecated property that is set. If no + * deprecated properties are set, use the non-deprecated property by default, even though it is + * not set (since it is not set, it will resolve to its default value). Since the deprecated + * properties are checked in order, newer properties should be on the left, replacing older + * properties on the right, so if a newer property is set, it will be selected over any older + * property that may also be set. */ - public Property resolve(Property property, Property deprecatedProperty) { - if (isPropertySet(property) || !isPropertySet(deprecatedProperty)) { - return property; - } else { - return deprecatedProperty; + public Property resolve(Property property, Property... deprecated) { + if (property.isDeprecated()) { + throw new IllegalArgumentException("Unexpected deprecated " + property.name()); + } + for (Property p : deprecated) { + if (!p.isDeprecated()) { + var notDeprecated = Stream.of(deprecated).filter(Predicate.not(Property::isDeprecated)) + .map(Property::name).collect(Collectors.toList()); + throw new IllegalArgumentException("Unexpected non-deprecated " + notDeprecated); + } } + return isPropertySet(property) ? property + : Stream.of(deprecated).filter(this::isPropertySet).findFirst().orElse(property); } /** diff --git a/core/src/test/java/org/apache/accumulo/core/conf/AccumuloConfigurationTest.java b/core/src/test/java/org/apache/accumulo/core/conf/AccumuloConfigurationTest.java index 5fb3cfa375..d0ba95db31 100644 --- a/core/src/test/java/org/apache/accumulo/core/conf/AccumuloConfigurationTest.java +++ b/core/src/test/java/org/apache/accumulo/core/conf/AccumuloConfigurationTest.java @@ -375,4 +375,45 @@ public class AccumuloConfigurationTest { tc.getScanExecutors().stream().filter(c -> c.name.equals("hulksmash")).findFirst().get(); assertEquals(44, sec8.maxThreads); } + + // note: this is hard to test if there aren't any deprecated properties + // if that's the case, just comment this test out or create a dummy deprecated property + @SuppressWarnings("deprecation") + @Test + public void testResolveDeprecated() { + var conf = new ConfigurationCopy(); + + // deprecated first argument + var e1 = assertThrows(IllegalArgumentException.class, () -> conf + .resolve(Property.INSTANCE_DFS_DIR, Property.INSTANCE_DFS_URI, Property.INSTANCE_DFS_URI)); + assertEquals("Unexpected deprecated INSTANCE_DFS_DIR", e1.getMessage()); + + // non-deprecated second argument + var e2 = assertThrows(IllegalArgumentException.class, + () -> conf.resolve(Property.INSTANCE_VOLUMES, Property.INSTANCE_DFS_DIR, + Property.INSTANCE_SECRET, Property.INSTANCE_DFS_DIR, Property.INSTANCE_VOLUMES)); + assertEquals("Unexpected non-deprecated [INSTANCE_SECRET, INSTANCE_VOLUMES]", e2.getMessage()); + + // empty second argument always resolves to non-deprecated first argument + assertSame(Property.INSTANCE_VOLUMES, conf.resolve(Property.INSTANCE_VOLUMES)); + + // none are set, resolve to non-deprecated + assertSame(Property.INSTANCE_VOLUMES, conf.resolve(Property.INSTANCE_VOLUMES, + Property.INSTANCE_DFS_DIR, Property.INSTANCE_DFS_URI)); + + // resolve to first deprecated argument that's set; here, it's the final one + conf.set(Property.INSTANCE_DFS_URI, ""); + assertSame(Property.INSTANCE_DFS_URI, conf.resolve(Property.INSTANCE_VOLUMES, + Property.INSTANCE_DFS_DIR, Property.INSTANCE_DFS_URI)); + + // resolve to first deprecated argument that's set; now, it's the first one because both are set + conf.set(Property.INSTANCE_DFS_DIR, ""); + assertSame(Property.INSTANCE_DFS_DIR, conf.resolve(Property.INSTANCE_VOLUMES, + Property.INSTANCE_DFS_DIR, Property.INSTANCE_DFS_URI)); + + // every property is set, so resolve to the non-deprecated one + conf.set(Property.INSTANCE_VOLUMES, ""); + assertSame(Property.INSTANCE_VOLUMES, conf.resolve(Property.INSTANCE_VOLUMES, + Property.INSTANCE_DFS_DIR, Property.INSTANCE_DFS_URI)); + } } diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java index ac9ee8b878..e6c07cf0ee 100644 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java @@ -273,9 +273,7 @@ public class DfsLogger implements Comparable<DfsLogger> { } @Override - public void await() { - return; - } + public void await() {} } static final LoggerOperation NO_WAIT_LOGGER_OP = new NoWaitLoggerOperation(); @@ -469,12 +467,13 @@ public class DfsLogger implements Comparable<DfsLogger> { log.debug("Got new write-ahead log: {}", this); } - @SuppressWarnings("deprecation") static long getWalBlockSize(AccumuloConfiguration conf) { long blockSize = conf.getAsBytes(Property.TSERV_WAL_BLOCKSIZE); - if (blockSize == 0) - blockSize = (long) (conf.getAsBytes( - conf.resolve(Property.TSERV_WAL_MAX_SIZE, Property.TSERV_WALOG_MAX_SIZE)) * 1.1); + if (blockSize == 0) { + @SuppressWarnings("deprecation") + Property prop = conf.resolve(Property.TSERV_WAL_MAX_SIZE, Property.TSERV_WALOG_MAX_SIZE); + blockSize = (long) (conf.getAsBytes(prop) * 1.1); + } return blockSize; } diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java index 027af6a408..6c6c82dd4d 100644 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java @@ -1705,9 +1705,9 @@ public class Tablet extends TabletBase { // grab this outside of tablet lock. @SuppressWarnings("deprecation") - int maxLogs = tableConfiguration - .getCount(tableConfiguration.resolve(Property.TSERV_WAL_MAX_REFERENCED, tableConfiguration - .resolve(Property.TSERV_WALOG_MAX_REFERENCED, Property.TABLE_MINC_LOGS_MAX))); + Property prop = tableConfiguration.resolve(Property.TSERV_WAL_MAX_REFERENCED, + Property.TSERV_WALOG_MAX_REFERENCED, Property.TABLE_MINC_LOGS_MAX); + int maxLogs = tableConfiguration.getCount(prop); String reason = null; synchronized (this) {