From dcd2b091543560ed31c0d389bf5d413797f1f0f3 Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Fri, 28 Dec 2018 21:33:36 -0800 Subject: [PATCH 1/6] Update ServerConfiguration to use ConfigKey and ConfigKeyGroup *Motivation* This PR is part of BP-37 - using the new configuration framework to re-organize server configuration *Changes* Update server configuration to use ConfigKey and ConfigKeyGroup Master Issue: #1867 --- .../bookkeeper/common/conf/ConfigKey.java | 106 +- .../apache/bookkeeper/common/conf/Type.java | 4 +- .../bookkeeper/common/conf/Validator.java | 15 + .../bookkeeper/common/conf/ConfigKeyTest.java | 59 + .../conf/AbstractConfiguration.java | 657 ++++- .../bookkeeper/conf/ClientConfiguration.java | 25 +- .../bookkeeper/conf/ServerConfiguration.java | 2275 +++++++++++++---- .../apache/bookkeeper/proto/BookieServer.java | 2 +- .../replication/TestReplicationWorker.java | 2 +- .../codahale-metrics-provider/pom.xml | 7 +- .../codahale/CodahaleMetricsProvider.java | 62 +- .../prometheus-metrics-provider/pom.xml | 8 +- .../prometheus/PrometheusMetricsProvider.java | 27 +- .../twitter-ostrich-provider/pom.xml | 7 +- .../twitter/ostrich/OstrichProvider.java | 32 +- .../twitter-science-provider/pom.xml | 7 +- .../twitter/science/TwitterStatsProvider.java | 21 +- 17 files changed, 2673 insertions(+), 643 deletions(-) diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java index b2bb47a92b9..15df0529a04 100644 --- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java +++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java @@ -25,6 +25,7 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.function.Function; import lombok.Builder; import lombok.Builder.Default; import lombok.Data; @@ -100,7 +101,23 @@ public static ConfigKeyBuilder builder(String name) { @Default private Object defaultValue = null; - private String defaultValueAsString() { + /** + * Default value supplier. + */ + @Default + private Function defaultValueSupplier = (conf) -> null; + + private Object defaultValue(Configuration conf) { + Object value = defaultValue(); + if (null == value) { + return defaultValueSupplier.apply(conf); + } else { + return value; + } + } + + private String defaultValueAsString(Configuration conf) { + Object defaultValue = defaultValue(conf); if (null == defaultValue) { return null; } else if (defaultValue instanceof String) { @@ -221,10 +238,12 @@ public void set(Configuration conf, Object value) { "Invalid value '" + value + "' to set on setting '" + name() + "': required '" + validator() + "'"); } - if (value instanceof Class) { - conf.setProperty(name(), ((Class) value).getName()); - } else { - conf.setProperty(name(), value); + if (null != value) { + if (value instanceof Class) { + conf.setProperty(name(), ((Class) value).getName()); + } else { + conf.setProperty(name(), value); + } } } @@ -236,7 +255,7 @@ public void set(Configuration conf, Object value) { */ public long getLong(Configuration conf) { checkArgument(type() == Type.LONG, "'" + name() + "' is NOT a LONG numeric setting"); - return conf.getLong(name(), (Long) defaultValue()); + return conf.getLong(name(), (Long) defaultValue(conf)); } /** @@ -247,7 +266,7 @@ public long getLong(Configuration conf) { */ public int getInt(Configuration conf) { checkArgument(type() == Type.INT, "'" + name() + "' is NOT a INT numeric setting"); - return conf.getInt(name(), (Integer) defaultValue()); + return conf.getInt(name(), (Integer) defaultValue(conf)); } /** @@ -258,7 +277,7 @@ public int getInt(Configuration conf) { */ public short getShort(Configuration conf) { checkArgument(type() == Type.SHORT, "'" + name() + "' is NOT a SHORT numeric setting"); - return conf.getShort(name(), (Short) defaultValue()); + return conf.getShort(name(), (Short) defaultValue(conf)); } /** @@ -269,7 +288,7 @@ public short getShort(Configuration conf) { */ public boolean getBoolean(Configuration conf) { checkArgument(type() == Type.BOOLEAN, "'" + name() + "' is NOT a BOOL numeric setting"); - return conf.getBoolean(name(), (Boolean) defaultValue()); + return conf.getBoolean(name(), (Boolean) defaultValue(conf)); } /** @@ -280,7 +299,18 @@ public boolean getBoolean(Configuration conf) { */ public double getDouble(Configuration conf) { checkArgument(type() == Type.DOUBLE, "'" + name() + "' is NOT a DOUBLE numeric setting"); - return conf.getDouble(name(), (Double) defaultValue()); + return conf.getDouble(name(), (Double) defaultValue(conf)); + } + + /** + * Retrieve the setting from the configuration conf as a {@link Float} value. + * + * @param conf configuration to retrieve the setting + * @return the value as a float number + */ + public float getFloat(Configuration conf) { + checkArgument(type() == Type.FLOAT, "'" + name() + "' is NOT a FLOAT numeric setting"); + return conf.getFloat(name(), (Float) defaultValue(conf)); } /** @@ -290,7 +320,18 @@ public double getDouble(Configuration conf) { * @return the value as a string. */ public String getString(Configuration conf) { - return conf.getString(name(), defaultValueAsString()); + return conf.getString(name(), defaultValueAsString(conf)); + } + + /** + * Retrieve the setting from the configuration conf as a {@link String} value, + * if the setting isn't set, return null. + * + * @param conf configuration to retrieve the setting + * @return the value as a string + */ + public String getStringWithoutDefault(Configuration conf) { + return conf.getString(name()); } /** @@ -303,7 +344,7 @@ public String getString(Configuration conf) { public Class getClass(Configuration conf, Class interfaceCls) { checkArgument(type() == Type.CLASS, "'" + name() + "' is NOT a CLASS setting"); try { - Class defaultClass = (Class) defaultValue(); + Class defaultClass = (Class) defaultValue(conf); return ReflectionUtils.getClass(conf, name(), defaultClass, interfaceCls, getClass().getClassLoader()); } catch (ConfigurationException e) { throw new IllegalArgumentException("Invalid class is set to setting '" + name() + "': ", e); @@ -320,7 +361,7 @@ public Class getClass(Configuration conf, Class interfaceCls public Class getClass(Configuration conf) { checkArgument(type() == Type.CLASS, "'" + name() + "' is NOT a CLASS setting"); try { - Class defaultClass = (Class) defaultValue(); + Class defaultClass = (Class) defaultValue(conf); return ReflectionUtils.getClass(conf, name(), defaultClass, getClass().getClassLoader()); } catch (ConfigurationException e) { throw new IllegalArgumentException("Invalid class is set to setting '" + name() + "': ", e); @@ -336,13 +377,46 @@ public Class getClass(Configuration conf) { @SuppressWarnings("unchecked") public List getList(Configuration conf) { checkArgument(type() == Type.LIST, "'" + name() + "' is NOT a LIST setting"); - List list = (List) defaultValue(); + List list = (List) defaultValue(conf); if (null == list) { list = Collections.emptyList(); } return conf.getList(name(), list); } + /** + * Retrieve the setting from the configuration conf as a string array. + * + * @param conf configuration to retrieve the setting + * @return the value as a string array + * @see #getArrayWithoutDefault(Configuration) + */ + public String[] getArray(Configuration conf) { + String[] retArray = getArrayWithoutDefault(conf); + if (null == retArray || retArray.length == 0) { + return (String[]) defaultValue(conf); + } else { + return retArray; + } + } + + /** + * Retrieve the setting from the configuration conf as a string array. + * If the key doesn't exist, it doesn't return the default value. + * + * @param conf configuration to retrieve the setting + * @return the value as a string array + * @see #getArray(Configuration) + */ + public String[] getArrayWithoutDefault(Configuration conf) { + checkArgument(type() == Type.ARRAY, "'" + name() + "' is NOT an ARRAY setting"); + if (conf.containsKey(name())) { + return conf.getStringArray(name()); + } else { + return null; + } + } + /** * Retrieve the setting value from the provided conf. * @@ -358,10 +432,14 @@ public Object get(Configuration conf) { return getShort(conf); case DOUBLE: return getDouble(conf); + case FLOAT: + return getFloat(conf); case BOOLEAN: return getBoolean(conf); case LIST: return getList(conf); + case ARRAY: + return getArray(conf); case CLASS: return getClass(conf); default: diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Type.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Type.java index c48e94c8b97..f361c1d7a36 100644 --- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Type.java +++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Type.java @@ -33,8 +33,10 @@ public enum Type { INT((name, value) -> value instanceof Integer), SHORT((name, value) -> value instanceof Short), LONG((name, value) -> value instanceof Long), + FLOAT((name, value) -> value instanceof Float), DOUBLE((name, value) -> value instanceof Double), - LIST((name, value) -> value instanceof List), + LIST((name, value) -> value instanceof List || value instanceof String), + ARRAY((name, value) -> value instanceof String[] || value instanceof String), CLASS((name, value) -> value instanceof Class || value instanceof String); private Validator validator; diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Validator.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Validator.java index 249ad310416..9f543baa4ac 100644 --- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Validator.java +++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/Validator.java @@ -45,4 +45,19 @@ default String documentation() { return ""; } + default Validator and(Validator validator) { + return (name, value) -> + validate(name, value) && validator.validate(name, value); + } + + default Validator or(Validator validator) { + return (name, value) -> + validate(name, value) || validator.validate(name, value); + } + + default Validator negate() { + return (name, value) -> + !validate(name, value); + } + } diff --git a/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/conf/ConfigKeyTest.java b/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/conf/ConfigKeyTest.java index 858a615db54..b7b289ec754 100644 --- a/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/conf/ConfigKeyTest.java +++ b/bookkeeper-common/src/test/java/org/apache/bookkeeper/common/conf/ConfigKeyTest.java @@ -19,6 +19,7 @@ package org.apache.bookkeeper.common.conf; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -223,6 +224,29 @@ public void testGetDouble() { assertEquals(newValue, key.get(conf)); } + @Test + public void testGetFloat() { + String keyName = runtime.getMethodName(); + float defaultValue = ThreadLocalRandom.current().nextFloat(); + ConfigKey key = ConfigKey.builder(keyName) + .required(true) + .type(Type.FLOAT) + .defaultValue(defaultValue) + .build(); + + Configuration conf = new ConcurrentConfiguration(); + + // get default value + assertEquals(defaultValue, key.getFloat(conf), 0.0001); + assertEquals(defaultValue, key.get(conf)); + + // set value + float newValue = (defaultValue * 2); + key.set(conf, newValue); + assertEquals(newValue, key.getFloat(conf), 0.0001); + assertEquals(newValue, key.get(conf)); + } + @Test public void testGetBoolean() { String keyName = runtime.getMethodName(); @@ -281,6 +305,41 @@ public void testGetList() { assertEquals(newList, key.get(conf)); } + @Test + public void testGetArray() { + String keyName = runtime.getMethodName(); + String[] defaultArray = new String[] { + "item1", "item2", "item3" + }; + ConfigKey key = ConfigKey.builder(keyName) + .required(true) + .type(Type.ARRAY) + .defaultValue(defaultArray) + .build(); + + Configuration conf = new CompositeConfiguration(); + + // get default value + assertArrayEquals(defaultArray, key.getArray(conf)); + assertArrayEquals(defaultArray, (String[]) key.get(conf)); + + // set value + String[] newArray = new String[] { + "item4", "item5", "item6" + }; + key.set(conf, newArray); + assertArrayEquals(newArray, key.getArray(conf)); + assertArrayEquals(newArray, (String[]) key.get(conf)); + + // set string value + newArray = new String[] { + "item7", "item8", "item9" + }; + conf.setProperty(key.name(), "item7,item8,item9"); + assertArrayEquals(newArray, key.getArray(conf)); + assertArrayEquals(newArray, (String[]) key.get(conf)); + } + @Test public void testGetClass() { String keyName = runtime.getMethodName(); diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java index f12200fcaff..9d75cb4ebf4 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java @@ -17,8 +17,7 @@ */ package org.apache.bookkeeper.conf; -import static org.apache.bookkeeper.conf.ClientConfiguration.CLIENT_AUTH_PROVIDER_FACTORY_CLASS; - +import com.google.common.collect.Lists; import java.net.URL; import java.util.HashMap; import java.util.Iterator; @@ -28,9 +27,11 @@ import javax.net.ssl.SSLEngine; import lombok.extern.slf4j.Slf4j; +import org.apache.bookkeeper.common.conf.ConfigKey; +import org.apache.bookkeeper.common.conf.ConfigKeyGroup; +import org.apache.bookkeeper.common.conf.Type; import org.apache.bookkeeper.common.util.JsonUtil; import org.apache.bookkeeper.common.util.JsonUtil.ParseJsonException; -import org.apache.bookkeeper.common.util.ReflectionUtils; import org.apache.bookkeeper.feature.Feature; import org.apache.bookkeeper.meta.AbstractZkLedgerManagerFactory; import org.apache.bookkeeper.meta.HierarchicalLedgerManagerFactory; @@ -68,93 +69,498 @@ public abstract class AbstractConfiguration DEFAULT_LOADER = loader; } - // Zookeeper Parameters - protected static final String ZK_TIMEOUT = "zkTimeout"; - protected static final String ZK_SERVERS = "zkServers"; + // + // Metadata Service Settings + // + + protected static final ConfigKeyGroup GROUP_METADATA_SERVICE = ConfigKeyGroup.builder("metadataservice") + .description("Metadata Service related settings") + .order(0) + .build(); + + protected static final String METADATA_SERVICE_URI = "metadataServiceUri"; + protected static final ConfigKey METADATA_SERVICE_URI_KEY = ConfigKey.builder(METADATA_SERVICE_URI) + .type(Type.STRING) + .description("metadata service uri that bookkeeper is used for loading corresponding metadata driver" + + " and resolving its metadata service location") + .required(true) + .group(GROUP_METADATA_SERVICE) + .orderInGroup(0) + .build(); - // Ledger Manager protected static final String LEDGER_MANAGER_TYPE = "ledgerManagerType"; protected static final String LEDGER_MANAGER_FACTORY_CLASS = "ledgerManagerFactoryClass"; + protected static final ConfigKey LEDGER_MANAGER_TYPE_KEY = ConfigKey.builder(LEDGER_MANAGER_TYPE) + .type(Type.STRING) + .description("Ledger Manager Type") + .defaultValue("hierarchical") + .group(GROUP_METADATA_SERVICE) + .orderInGroup(1) + .deprecated(true) + .deprecatedByConfigKey(LEDGER_MANAGER_FACTORY_CLASS) + .build(); + + protected static final ConfigKey LEDGER_MANAGER_FACTORY_CLASS_KEY = ConfigKey.builder(LEDGER_MANAGER_FACTORY_CLASS) + .type(Type.CLASS) + .description("Ledger Manager Class") + .documentation("What kind of ledger manager is used to manage how ledgers are stored, managed and" + + " garbage collected. Try to read 'BookKeeper Internals' for detail info.") + .defaultValue(HierarchicalLedgerManagerFactory.class) + .group(GROUP_METADATA_SERVICE) + .orderInGroup(2) + .deprecated(true) + .deprecatedByConfigKey(METADATA_SERVICE_URI) + .deprecatedSince("4.7") + .build(); + protected static final String ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS = "allowShadedLedgerManagerFactoryClass"; + protected static final ConfigKey ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS_KEY = + ConfigKey.builder(ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS) + .type(Type.BOOLEAN) + .description("Flag to allow using shaded ledger manager class to connect to a bookkeeper cluster") + .documentation("sometimes the bookkeeper server classes are shaded. the ledger manager factory" + + " classes might be relocated to be under other packages. this would fail the clients using" + + " shaded factory classes since the factory classes are not matched. Users can enable this flag" + + " to allow using shaded ledger manager class to connect to a bookkeeper cluster.") + .defaultValue(false) + .group(GROUP_METADATA_SERVICE) + .orderInGroup(3) + .build(); + + protected static final String SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX = "shadedLedgerManagerFactoryClassPrefix"; - protected static final String METADATA_SERVICE_URI = "metadataServiceUri"; - protected static final String ZK_LEDGERS_ROOT_PATH = "zkLedgersRootPath"; - protected static final String ZK_REQUEST_RATE_LIMIT = "zkRequestRateLimit"; - protected static final String AVAILABLE_NODE = "available"; - protected static final String REREPLICATION_ENTRY_BATCH_SIZE = "rereplicationEntryBatchSize"; - protected static final String STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME = - "storeSystemTimeAsLedgerUnderreplicatedMarkTime"; - protected static final String STORE_SYSTEMTIME_AS_LEDGER_CREATION_TIME = "storeSystemTimeAsLedgerCreationTime"; + protected static final ConfigKey SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX_KEY = + ConfigKey.builder(SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX) + .type(Type.STRING) + .description("the shaded ledger manager factory prefix") + .documentation("this is used when `" + ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS + "` is set to true.") + .defaultValue("dlshade.") + .group(GROUP_METADATA_SERVICE) + .orderInGroup(4) + .build(); + + // Kluge for compatibility testing. Never set this outside tests. + public static final String LEDGER_MANAGER_FACTORY_DISABLE_CLASS_CHECK = "ledgerManagerFactoryDisableClassCheck"; // Metastore settings, only being used when LEDGER_MANAGER_FACTORY_CLASS is MSLedgerManagerFactory protected static final String METASTORE_IMPL_CLASS = "metastoreImplClass"; + protected static final ConfigKey METASTORE_IMPL_CLASS_KEY = ConfigKey.builder(METASTORE_IMPL_CLASS) + .type(Type.STRING) + .description("metastore implementation class, only being used when `" + LEDGER_MANAGER_FACTORY_CLASS + + "` is `MSLedgerManagerFactory`") + .group(GROUP_METADATA_SERVICE) + .orderInGroup(5) + .build(); + protected static final String METASTORE_MAX_ENTRIES_PER_SCAN = "metastoreMaxEntriesPerScan"; + protected static final ConfigKey METASTORE_MAX_ENTRIES_PER_SCAN_KEY = + ConfigKey.builder(METASTORE_MAX_ENTRIES_PER_SCAN) + .type(Type.INT) + .description("Max entries per scan in metastore, only being used when `" + LEDGER_MANAGER_FACTORY_CLASS + + "` is `MSLedgerManagerFactory`") + .defaultValue(50) + .group(GROUP_METADATA_SERVICE) + .orderInGroup(6) + .build(); + + // + // ZooKeeper Metadata Service Settings + // + + protected static final ConfigKeyGroup GROUP_ZK = ConfigKeyGroup.builder("zk") + .description("ZooKeeper Metadata Service related settings") + .order(1) + .build(); + + protected static final String AVAILABLE_NODE = "available"; + protected static final String ZK_LEDGERS_ROOT_PATH = "zkLedgersRootPath"; + protected static final ConfigKey ZK_LEDGERS_ROOT_PATH_KEY = ConfigKey.builder(ZK_LEDGERS_ROOT_PATH) + .type(Type.STRING) + .description("Root Zookeeper path to store ledger metadata") + .documentation("This parameter is used by zookeeper-based ledger manager as a root znode" + + " to store all ledgers.") + .defaultValue("/ledgers") + .group(GROUP_ZK) + .orderInGroup(0) + .deprecated(true) + .deprecatedByConfigKey(METADATA_SERVICE_URI) + .deprecatedSince("4.7") + .build(); + protected static final String ZK_SERVERS = "zkServers"; + protected static final ConfigKey ZK_SERVERS_KEY = ConfigKey.builder(ZK_SERVERS) + .type(Type.LIST) + .description("A list of one of more servers on which Zookeeper is running") + .documentation("The server list can be comma separated values, for example:" + + " zkServers=zk1:2181,zk2:2181,zk3:2181") + .required(true) + .group(GROUP_ZK) + .orderInGroup(1) + .deprecated(true) + .deprecatedByConfigKey(METADATA_SERVICE_URI) + .deprecatedSince("4.7") + .build(); + + protected static final String ZK_TIMEOUT = "zkTimeout"; + protected static final ConfigKey ZK_TIMEOUT_KEY = ConfigKey.builder(ZK_TIMEOUT) + .type(Type.INT) + .description("ZooKeeper client session timeout in milliseconds") + .documentation("Bookie server will exit if it received SESSION_EXPIRED because it" + + " was partitioned off from ZooKeeper for more than the session timeout" + + " JVM garbage collection, disk I/O will cause SESSION_EXPIRED." + + " Increment this value could help avoiding this issue") + .defaultValue(10000) + .group(GROUP_ZK) + .orderInGroup(2) + .build(); + + protected static final String ZK_REQUEST_RATE_LIMIT = "zkRequestRateLimit"; + protected static final ConfigKey ZK_REQUEST_RATE_LIMIT_KEY = ConfigKey.builder(ZK_REQUEST_RATE_LIMIT) + .type(Type.DOUBLE) + .description("The Zookeeper request limit") + .documentation("It is only enabled when setting a positive value. Default value is 0.") + .defaultValue(0) + .group(GROUP_ZK) + .orderInGroup(3) + .build(); + + protected static final String ZK_ENABLE_SECURITY = "zkEnableSecurity"; + protected static final ConfigKey ZK_ENABLE_SECURITY_KEY = ConfigKey.builder(ZK_ENABLE_SECURITY) + .type(Type.BOOLEAN) + .description("Set ACLs on every node written on ZooKeeper") + .documentation("this way only allowed users will be able to read and write BookKeeper" + + " metadata stored on ZooKeeper. In order to make ACLs work you need to setup" + + " ZooKeeper JAAS authentication all the bookies and Client need to share the" + + " same user, and this is usually done using Kerberos authentication. See" + + " ZooKeeper documentation") + .defaultValue(false) + .group(GROUP_ZK) + .orderInGroup(4) + .build(); + + // + // Security Settings + // + + protected static final ConfigKeyGroup GROUP_SECURITY = ConfigKeyGroup.builder("security") + .description("Security related settings") + .order(2) + .build(); + + // Client auth provider factory class name. It must be configured on Bookies to for the Auditor + protected static final String CLIENT_AUTH_PROVIDER_FACTORY_CLASS = "clientAuthProviderFactoryClass"; + protected static final ConfigKey CLIENT_AUTH_PROVIDER_FACTORY_CLASS_KEY = + ConfigKey.builder(CLIENT_AUTH_PROVIDER_FACTORY_CLASS) + .type(Type.CLASS) + .description("Set the client authentication provider factory class name") + .documentation("If Authentication is enabled on bookies and Auditor is running along" + + " with bookies, this must be configured. Otherwise if this is not set, no authentication" + + " will be used") + .group(GROUP_SECURITY) + .orderInGroup(1) + .build(); + + // + // TLS Settings + // + + protected static final ConfigKeyGroup GROUP_TLS = ConfigKeyGroup.builder("tls") + .description("TLS Settings") + .order(3) + .build(); // Common TLS configuration // TLS Provider (JDK or OpenSSL) protected static final String TLS_PROVIDER = "tlsProvider"; + protected static final ConfigKey TLS_PROVIDER_KEY = ConfigKey.builder(TLS_PROVIDER) + .type(Type.STRING) + .description("TLS Provider") + .defaultValue("OpenSSL") + .optionValues(Lists.newArrayList( + "OpenSSL", + "JDK" + )) + .group(GROUP_TLS) + .orderInGroup(0) + .build(); // TLS provider factory class name protected static final String TLS_PROVIDER_FACTORY_CLASS = "tlsProviderFactoryClass"; - - protected static final String LEDGERID_FORMATTER_CLASS = "ledgerIdFormatterClass"; - protected static final String ENTRY_FORMATTER_CLASS = "entryFormatterClass"; + protected static final ConfigKey TLS_PROVIDER_FACTORY_CLASS_KEY = ConfigKey.builder(TLS_PROVIDER_FACTORY_CLASS) + .type(Type.CLASS) + .description("TLS Provider factory class name") + .group(GROUP_TLS) + .orderInGroup(1) + .build(); // Enable authentication of the other connection end point (mutual authentication) protected static final String TLS_CLIENT_AUTHENTICATION = "tlsClientAuthentication"; + protected static final ConfigKey TLS_CLIENT_AUTHENTICATION_KEY = ConfigKey.builder(TLS_CLIENT_AUTHENTICATION) + .type(Type.BOOLEAN) + .description("Enable authentication of the other connection endpoint (mutual authentication)") + .defaultValue(false) + .group(GROUP_TLS) + .orderInGroup(2) + .build(); - // Preserve MDC or not for tasks in executor - protected static final String PRESERVE_MDC_FOR_TASK_EXECUTION = "preserveMdcForTaskExecution"; + /** + * TLS KeyStore, TrustStore, Password files and Certificate Paths. + */ + protected static final String TLS_KEYSTORE_TYPE = "tlsKeyStoreType"; + protected static final ConfigKey TLS_KEYSTORE_TYPE_KEY = ConfigKey.builder(TLS_KEYSTORE_TYPE) + .type(Type.STRING) + .description("TLS Keystore type") + .defaultValue("JKS") + .optionValues(Lists.newArrayList( + "PKCS12", + "JKS", + "PEM" + )) + .group(GROUP_TLS) + .orderInGroup(3) + .build(); - // Default formatter classes - protected static final Class DEFAULT_ENTRY_FORMATTER = StringEntryFormatter.class; - protected static final Class DEFAULT_LEDGERID_FORMATTER = - LedgerIdFormatter.LongLedgerIdFormatter.class; + protected static final String TLS_KEYSTORE = "tlsKeyStore"; + protected static final ConfigKey TLS_KEYSTORE_KEY = ConfigKey.builder(TLS_KEYSTORE) + .type(Type.STRING) + .description("Path to TLS Keystore location") + .group(GROUP_TLS) + .orderInGroup(4) + .build(); + + protected static final String TLS_KEYSTORE_PASSWORD_PATH = "tlsKeyStorePasswordPath"; + protected static final ConfigKey TLS_KEYSTORE_PASSWORD_PATH_KEY = ConfigKey.builder(TLS_KEYSTORE_PASSWORD_PATH) + .type(Type.STRING) + .description("Path to TLS Keystore password location, if the key store is protected by a password") + .group(GROUP_TLS) + .orderInGroup(5) + .build(); + + protected static final String TLS_TRUSTSTORE_TYPE = "tlsTrustStoreType"; + protected static final ConfigKey TLS_TRUSTSTORE_TYPE_KEY = ConfigKey.builder(TLS_TRUSTSTORE_TYPE) + .type(Type.STRING) + .description("TLS Truststore type") + .defaultValue("JKS") + .optionValues(Lists.newArrayList( + "PKCS12", + "JKS", + "PEM" + )) + .group(GROUP_TLS) + .orderInGroup(6) + .build(); + + protected static final String TLS_TRUSTSTORE = "tlsTrustStore"; + protected static final ConfigKey TLS_TRUSTSTORE_KEY = ConfigKey.builder(TLS_TRUSTSTORE) + .type(Type.STRING) + .description("Path to TLS Truststore location") + .group(GROUP_TLS) + .orderInGroup(7) + .build(); + + protected static final String TLS_TRUSTSTORE_PASSWORD_PATH = "tlsTrustStorePasswordPath"; + protected static final ConfigKey TLS_TRUSTSTORE_PASSWORD_PATH_KEY = ConfigKey.builder(TLS_TRUSTSTORE_PASSWORD_PATH) + .type(Type.STRING) + .description("Path to TLS Truststore password location, if the trust store is protected by a password") + .group(GROUP_TLS) + .orderInGroup(8) + .build(); + + protected static final String TLS_CERTIFICATE_PATH = "tlsCertificatePath"; + protected static final ConfigKey TLS_CERTIFICATE_PATH_KEY = ConfigKey.builder(TLS_CERTIFICATE_PATH) + .type(Type.STRING) + .description("Path to TLS certificate location") + .group(GROUP_TLS) + .orderInGroup(9) + .build(); /** * This list will be passed to {@link SSLEngine#setEnabledCipherSuites(java.lang.String[]) }. * Please refer to official JDK JavaDocs */ protected static final String TLS_ENABLED_CIPHER_SUITES = "tlsEnabledCipherSuites"; + protected static final ConfigKey TLS_ENABLED_CIPHER_SUITES_KEY = ConfigKey.builder(TLS_ENABLED_CIPHER_SUITES) + .type(Type.STRING) + .description("Set the list of enabled TLS cipher suites.") + .documentation("Leave null not to override default JDK list. This list will be passed to" + + " {@link SSLEngine#setEnabledCipherSuites(java.lang.String[]) }. Please refer to official JDK JavaDocs") + .group(GROUP_TLS) + .orderInGroup(10) + .build(); /** * This list will be passed to {@link SSLEngine#setEnabledProtocols(java.lang.String[]) }. * Please refer to official JDK JavaDocs */ protected static final String TLS_ENABLED_PROTOCOLS = "tlsEnabledProtocols"; + protected static final ConfigKey TLS_ENABLED_PROTOCOLS_KEY = ConfigKey.builder(TLS_ENABLED_PROTOCOLS) + .type(Type.STRING) + .description("Set the list of enabled TLS protocols.") + .documentation("Leave null not to override default JDK list. This list will be passed to" + + " {@link SSLEngine#setEnabledProtocols(java.lang.String[]) }. Please refer to official JDK JavaDocs") + .group(GROUP_TLS) + .orderInGroup(11) + .build(); + + // + // AutoRecovery + // + + protected static final ConfigKeyGroup GROUP_AUTORECOVERY = ConfigKeyGroup.builder("autorecovery") + .description("AutoRecovery related settings") + .order(900) + .build(); + + protected static final ConfigKeyGroup GROUP_AUDITOR = ConfigKeyGroup.builder("auditor") + .description("AutoRecovery Auditor related settings") + .order(901) + .build(); - /** - * TLS KeyStore, TrustStore, Password files and Certificate Paths. - */ - protected static final String TLS_KEYSTORE_TYPE = "tlsKeyStoreType"; - protected static final String TLS_KEYSTORE = "tlsKeyStore"; - protected static final String TLS_KEYSTORE_PASSWORD_PATH = "tlsKeyStorePasswordPath"; - protected static final String TLS_TRUSTSTORE_TYPE = "tlsTrustStoreType"; - protected static final String TLS_TRUSTSTORE = "tlsTrustStore"; - protected static final String TLS_TRUSTSTORE_PASSWORD_PATH = "tlsTrustStorePasswordPath"; - protected static final String TLS_CERTIFICATE_PATH = "tlsCertificatePath"; - - //Netty configuration - protected static final String NETTY_MAX_FRAME_SIZE = "nettyMaxFrameSizeBytes"; - protected static final int DEFAULT_NETTY_MAX_FRAME_SIZE = 5 * 1024 * 1024; // 5MB - - // Zookeeper ACL settings - protected static final String ZK_ENABLE_SECURITY = "zkEnableSecurity"; - - // Kluge for compatibility testing. Never set this outside tests. - public static final String LEDGER_MANAGER_FACTORY_DISABLE_CLASS_CHECK = "ledgerManagerFactoryDisableClassCheck"; + protected static final String STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME = + "storeSystemTimeAsLedgerUnderreplicatedMarkTime"; + protected static final ConfigKey STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME_KEY = + ConfigKey.builder(STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME) + .type(Type.BOOLEAN) + .description("Enable the Auditor to use system time as underreplicated ledger mark time") + .documentation("If this is enabled, Auditor will write a ctime field into the underreplicated" + + " ledger znode") + .defaultValue(true) + .group(GROUP_AUDITOR) + .orderInGroup(0) + .build(); + + protected static final ConfigKeyGroup GROUP_REPLICATION_WORKER = ConfigKeyGroup.builder("replicationworker") + .description("AutoRecovery Replication Worker related settings") + .order(902) + .build(); - // Validate bookie process user - public static final String PERMITTED_STARTUP_USERS = "permittedStartupUsers"; + protected static final String REREPLICATION_ENTRY_BATCH_SIZE = "rereplicationEntryBatchSize"; + protected static final ConfigKey REREPLICATION_ENTRY_BATCH_SIZE_KEY = + ConfigKey.builder(REREPLICATION_ENTRY_BATCH_SIZE) + .type(Type.LONG) + .description("The number of entries that a replication will rereplicate in parallel") + .defaultValue(10) + .group(GROUP_REPLICATION_WORKER) + .orderInGroup(0) + .build(); + + // + // Placement Policy + // + protected static final ConfigKeyGroup GROUP_PLACEMENT_POLICY = ConfigKeyGroup.builder("placementpolicy") + .description("Placement policy related settings") + .order(1000) + .build(); // minimum number of racks per write quorum public static final String MIN_NUM_RACKS_PER_WRITE_QUORUM = "minNumRacksPerWriteQuorum"; + protected static final ConfigKey MIN_NUM_RACKS_PER_WRITE_QUORUM_KEY = + ConfigKey.builder(MIN_NUM_RACKS_PER_WRITE_QUORUM) + .type(Type.INT) + .description("minimum number of racks per write quorum") + .documentation("RackawareEnsemblePlacementPolicy will try to get bookies from atleast '" + + MIN_NUM_RACKS_PER_WRITE_QUORUM + "' racks for a writeQuorum") + .defaultValue(2) + .group(GROUP_PLACEMENT_POLICY) + .orderInGroup(0) + .build(); // enforce minimum number of racks per write quorum public static final String ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM = "enforceMinNumRacksPerWriteQuorum"; + protected static final ConfigKey ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM_KEY = + ConfigKey.builder(ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM) + .type(Type.BOOLEAN) + .description("Flag to enforce RackawareEnsemblePlacementPolicy to pick bookies from '" + + MIN_NUM_RACKS_PER_WRITE_QUORUM + "' racks for a writeQuorum.") + .documentation("If this feature is enabled, when a bookkeeper client cann't find an available bookie" + + " then it would throw BKNotEnoughBookiesException instead of picking random one.") + .defaultValue(false) + .group(GROUP_PLACEMENT_POLICY) + .orderInGroup(1) + .build(); + + // + // Netty Settings + // + + protected static final ConfigKeyGroup GROUP_NETTY = ConfigKeyGroup.builder("netty") + .description("Netty related settings") + .order(1001) + .build(); + + protected static final String NETTY_MAX_FRAME_SIZE = "nettyMaxFrameSizeBytes"; + protected static final int DEFAULT_NETTY_MAX_FRAME_SIZE = 5 * 1024 * 1024; // 5MB + protected static final ConfigKey NETTY_MAX_FRAME_SIZE_KEY = ConfigKey.builder(NETTY_MAX_FRAME_SIZE) + .type(Type.INT) + .description("The maximum netty frame size in bytes") + .documentation("Any message received larger than this will be rejected") + .defaultValue(DEFAULT_NETTY_MAX_FRAME_SIZE) + .group(GROUP_NETTY) + .orderInGroup(0) + .build(); + + // + // Tools related settings + // + + protected static final ConfigKeyGroup GROUP_TOOLS = ConfigKeyGroup.builder("tools") + .description("Tools Settings") + .order(1002) + .build(); + + // Default formatter classes + protected static final Class DEFAULT_ENTRY_FORMATTER = StringEntryFormatter.class; + protected static final Class DEFAULT_LEDGERID_FORMATTER = + LedgerIdFormatter.LongLedgerIdFormatter.class; + protected static final String LEDGERID_FORMATTER_CLASS = "ledgerIdFormatterClass"; + protected static final ConfigKey LEDGERID_FORMATTER_CLASS_KEY = ConfigKey.builder(LEDGERID_FORMATTER_CLASS) + .type(Type.CLASS) + .description("The formatter class that bookkeeper tools use to format ledger id") + .defaultValue(DEFAULT_LEDGERID_FORMATTER) + .group(GROUP_TOOLS) + .orderInGroup(0) + .build(); + + protected static final String ENTRY_FORMATTER_CLASS = "entryFormatterClass"; + protected static final ConfigKey ENTRY_FORMATTER_CLASS_KEY = ConfigKey.builder(ENTRY_FORMATTER_CLASS) + .type(Type.CLASS) + .description("The formatter class that bookkeeper tools use to format entries") + .defaultValue(DEFAULT_ENTRY_FORMATTER) + .group(GROUP_TOOLS) + .orderInGroup(1) + .build(); + + // + // Monitoring related settings + // + + protected static final ConfigKeyGroup GROUP_MONITORING = ConfigKeyGroup.builder("monitoring") + .description("Monitoring related settings") + .order(1003) + .build(); + + // Preserve MDC or not for tasks in executor + protected static final String PRESERVE_MDC_FOR_TASK_EXECUTION = "preserveMdcForTaskExecution"; + protected static final ConfigKey PRESERVE_MDC_FOR_TASK_EXECUTION_KEY = + ConfigKey.builder(PRESERVE_MDC_FOR_TASK_EXECUTION) + .type(Type.BOOLEAN) + .description("Flag to preserve MDC for tasks in Executor.") + .defaultValue(false) + .group(GROUP_MONITORING) + .orderInGroup(0) + .since("4.9") + .build(); // option to limit stats logging public static final String LIMIT_STATS_LOGGING = "limitStatsLogging"; + protected static final ConfigKey LIMIT_STATS_LOGGING_KEY = + ConfigKey.builder(LIMIT_STATS_LOGGING) + .type(Type.BOOLEAN) + .description("Flag to limit exposing stats (e.g. exposing pcbc stats)") + .defaultValue(false) + .group(GROUP_MONITORING) + .orderInGroup(1) + .since("4.9") + .build(); protected AbstractConfiguration() { super(); @@ -164,20 +570,6 @@ protected AbstractConfiguration() { } } - /** - * Limit who can start the application to prevent future permission errors. - */ - public void setPermittedStartupUsers(String s) { - setProperty(PERMITTED_STARTUP_USERS, s); - } - - /** - * Get array of users specified in this property. - */ - public String[] getPermittedStartupUsers() { - return getStringArray(PERMITTED_STARTUP_USERS); - } - /** * You can load configurations in precedence order. The first one takes * precedence over any loaded later. @@ -233,7 +625,7 @@ public String getMetadataServiceUriUnchecked() throws UncheckedConfigurationExce * @throws ConfigurationException if the metadata service uri is invalid. */ public String getMetadataServiceUri() throws ConfigurationException { - String serviceUri = getString(METADATA_SERVICE_URI); + String serviceUri = METADATA_SERVICE_URI_KEY.getString(this); if (null == serviceUri) { // no service uri is defined, fallback to old settings String ledgerManagerType; @@ -258,7 +650,7 @@ public String getMetadataServiceUri() throws ConfigurationException { * @return the configuration object. */ public T setMetadataServiceUri(String serviceUri) { - setProperty(METADATA_SERVICE_URI, serviceUri); + METADATA_SERVICE_URI_KEY.set(this, serviceUri); return getThis(); } @@ -272,7 +664,7 @@ public T setMetadataServiceUri(String serviceUri) { */ @Deprecated public String getZkServers() { - List servers = getList(ZK_SERVERS, null); + List servers = ZK_SERVERS_KEY.getList(this); if (null == servers || 0 == servers.size()) { return null; } @@ -289,7 +681,7 @@ public String getZkServers() { */ @Deprecated public T setZkServers(String zkServers) { - setProperty(ZK_SERVERS, zkServers); + ZK_SERVERS_KEY.set(this, Lists.newArrayList(StringUtils.split(zkServers, ","))); return getThis(); } @@ -299,7 +691,7 @@ public T setZkServers(String zkServers) { * @return zookeeper server timeout */ public int getZkTimeout() { - return getInt(ZK_TIMEOUT, 10000); + return ZK_TIMEOUT_KEY.getInt(this); } /** @@ -310,7 +702,7 @@ public int getZkTimeout() { * @return server configuration */ public T setZkTimeout(int zkTimeout) { - setProperty(ZK_TIMEOUT, Integer.toString(zkTimeout)); + ZK_TIMEOUT_KEY.set(this, zkTimeout); return getThis(); } @@ -323,7 +715,7 @@ public T setZkTimeout(int zkTimeout) { */ @Deprecated public void setLedgerManagerType(String lmType) { - setProperty(LEDGER_MANAGER_TYPE, lmType); + LEDGER_MANAGER_TYPE_KEY.set(this, lmType); } /** @@ -335,7 +727,7 @@ public void setLedgerManagerType(String lmType) { */ @Deprecated public String getLedgerManagerType() { - return getString(LEDGER_MANAGER_TYPE); + return LEDGER_MANAGER_TYPE_KEY.getString(this); } /** @@ -347,7 +739,7 @@ public String getLedgerManagerType() { * @return configuration instance. */ public T setAllowShadedLedgerManagerFactoryClass(boolean allowed) { - setProperty(ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS, allowed); + ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS_KEY.set(this, allowed); return getThis(); } @@ -358,7 +750,7 @@ public T setAllowShadedLedgerManagerFactoryClass(boolean allowed) { * @return ledger manager factory class name. */ public boolean isShadedLedgerManagerFactoryClassAllowed() { - return getBoolean(ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS, false); + return ALLOW_SHADED_LEDGER_MANAGER_FACTORY_CLASS_KEY.getBoolean(this); } /** @@ -373,7 +765,7 @@ public boolean isShadedLedgerManagerFactoryClassAllowed() { * @return configuration instance. */ public T setShadedLedgerManagerFactoryClassPrefix(String classPrefix) { - setProperty(SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX, classPrefix); + SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX_KEY.set(this, classPrefix); return getThis(); } @@ -388,7 +780,7 @@ public T setShadedLedgerManagerFactoryClassPrefix(String classPrefix) { * @see #isShadedLedgerManagerFactoryClassAllowed() */ public String getShadedLedgerManagerFactoryClassPrefix() { - return getString(SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX, "dlshade."); + return SHADED_LEDGER_MANAGER_FACTORY_CLASS_PREFIX_KEY.getString(this); } /** @@ -398,7 +790,7 @@ public String getShadedLedgerManagerFactoryClassPrefix() { * Ledger Manager Factory Class Name */ public void setLedgerManagerFactoryClassName(String factoryClassName) { - setProperty(LEDGER_MANAGER_FACTORY_CLASS, factoryClassName); + LEDGER_MANAGER_FACTORY_CLASS_KEY.set(this, factoryClassName); } /** @@ -407,7 +799,7 @@ public void setLedgerManagerFactoryClassName(String factoryClassName) { * @return ledger manager factory class name. */ public String getLedgerManagerFactoryClassName() { - return getString(LEDGER_MANAGER_FACTORY_CLASS); + return LEDGER_MANAGER_FACTORY_CLASS_KEY.getString(this); } /** @@ -450,7 +842,7 @@ public String getLedgerManagerLayoutStringFromFactoryClass() throws Configuratio * Ledger Manager Factory Class */ public void setLedgerManagerFactoryClass(Class factoryClass) { - setProperty(LEDGER_MANAGER_FACTORY_CLASS, factoryClass.getName()); + LEDGER_MANAGER_FACTORY_CLASS_KEY.set(this, factoryClass); } /** @@ -460,9 +852,11 @@ public void setLedgerManagerFactoryClass(Class f */ public Class getLedgerManagerFactoryClass() throws ConfigurationException { - return ReflectionUtils.getClass(this, LEDGER_MANAGER_FACTORY_CLASS, - null, LedgerManagerFactory.class, - DEFAULT_LOADER); + try { + return LEDGER_MANAGER_FACTORY_CLASS_KEY.getClass(this, LedgerManagerFactory.class); + } catch (IllegalArgumentException iae) { + throw new ConfigurationException(iae.getMessage(), iae.getCause()); + } } /** @@ -472,7 +866,7 @@ public Class getLedgerManagerFactoryClass() */ @Deprecated public void setZkLedgersRootPath(String zkLedgersPath) { - setProperty(ZK_LEDGERS_ROOT_PATH, zkLedgersPath); + ZK_LEDGERS_ROOT_PATH_KEY.set(this, zkLedgersPath); } /** @@ -482,7 +876,7 @@ public void setZkLedgersRootPath(String zkLedgersPath) { */ @Deprecated public String getZkLedgersRootPath() { - return getString(ZK_LEDGERS_ROOT_PATH, "/ledgers"); + return ZK_LEDGERS_ROOT_PATH_KEY.getString(this); } /** @@ -491,7 +885,7 @@ public String getZkLedgersRootPath() { * @return zookeeper access request rate limit. */ public double getZkRequestRateLimit() { - return getDouble(ZK_REQUEST_RATE_LIMIT, 0); + return ZK_REQUEST_RATE_LIMIT_KEY.getDouble(this); } /** @@ -501,7 +895,7 @@ public double getZkRequestRateLimit() { * zookeeper access request rate limit. */ public void setZkRequestRateLimit(double rateLimit) { - setProperty(ZK_REQUEST_RATE_LIMIT, rateLimit); + ZK_REQUEST_RATE_LIMIT_KEY.set(this, rateLimit); } /** @@ -510,7 +904,7 @@ public void setZkRequestRateLimit(double rateLimit) { * @return usage of secure ZooKeeper ACLs */ public boolean isZkEnableSecurity() { - return getBoolean(ZK_ENABLE_SECURITY, false); + return ZK_ENABLE_SECURITY_KEY.getBoolean(this); } /** @@ -519,7 +913,7 @@ public boolean isZkEnableSecurity() { * @param zkEnableSecurity */ public void setZkEnableSecurity(boolean zkEnableSecurity) { - setProperty(ZK_ENABLE_SECURITY, zkEnableSecurity); + ZK_ENABLE_SECURITY_KEY.set(this, zkEnableSecurity); } /** @@ -540,14 +934,14 @@ public String getZkAvailableBookiesPath() { * wise. */ public void setRereplicationEntryBatchSize(long rereplicationEntryBatchSize) { - setProperty(REREPLICATION_ENTRY_BATCH_SIZE, rereplicationEntryBatchSize); + REREPLICATION_ENTRY_BATCH_SIZE_KEY.set(this, rereplicationEntryBatchSize); } /** * Get the re-replication entry batch size. */ public long getRereplicationEntryBatchSize() { - return getLong(REREPLICATION_ENTRY_BATCH_SIZE, 10); + return REREPLICATION_ENTRY_BATCH_SIZE_KEY.getLong(this); } /** @@ -556,7 +950,7 @@ public long getRereplicationEntryBatchSize() { * @return metastore implementation class name. */ public String getMetastoreImplClass() { - return getString(METASTORE_IMPL_CLASS); + return METASTORE_IMPL_CLASS_KEY.getString(this); } /** @@ -566,7 +960,7 @@ public String getMetastoreImplClass() { * Metastore implementation Class name. */ public void setMetastoreImplClass(String metastoreImplClass) { - setProperty(METASTORE_IMPL_CLASS, metastoreImplClass); + METASTORE_IMPL_CLASS_KEY.set(this, metastoreImplClass); } /** @@ -575,7 +969,7 @@ public void setMetastoreImplClass(String metastoreImplClass) { * @return max entries per scan in metastore. */ public int getMetastoreMaxEntriesPerScan() { - return getInt(METASTORE_MAX_ENTRIES_PER_SCAN, 50); + return METASTORE_MAX_ENTRIES_PER_SCAN_KEY.getInt(this); } /** @@ -585,7 +979,7 @@ public int getMetastoreMaxEntriesPerScan() { * Max entries per scan in metastore. */ public void setMetastoreMaxEntriesPerScan(int maxEntries) { - setProperty(METASTORE_MAX_ENTRIES_PER_SCAN, maxEntries); + METASTORE_MAX_ENTRIES_PER_SCAN_KEY.set(this, maxEntries); } public void setFeature(String configProperty, Feature feature) { @@ -607,7 +1001,7 @@ public Feature getFeature(String configProperty, Feature defaultValue) { * LedgerIdFormatter Class */ public void setLedgerIdFormatterClass(Class formatterClass) { - setProperty(LEDGERID_FORMATTER_CLASS, formatterClass.getName()); + LEDGERID_FORMATTER_CLASS_KEY.set(this, formatterClass); } /** @@ -615,10 +1009,8 @@ public void setLedgerIdFormatterClass(Class formatt * * @return LedgerIdFormatter class */ - public Class getLedgerIdFormatterClass() - throws ConfigurationException { - return ReflectionUtils.getClass(this, LEDGERID_FORMATTER_CLASS, DEFAULT_LEDGERID_FORMATTER, - LedgerIdFormatter.class, DEFAULT_LOADER); + public Class getLedgerIdFormatterClass() { + return LEDGERID_FORMATTER_CLASS_KEY.getClass(this, LedgerIdFormatter.class); } /** @@ -628,7 +1020,7 @@ public Class getLedgerIdFormatterClass() * EntryFormatter Class */ public void setEntryFormatterClass(Class formatterClass) { - setProperty(ENTRY_FORMATTER_CLASS, formatterClass.getName()); + ENTRY_FORMATTER_CLASS_KEY.set(this, formatterClass); } /** @@ -636,10 +1028,8 @@ public void setEntryFormatterClass(Class formatterClas * * @return EntryFormatter class */ - public Class getEntryFormatterClass() - throws ConfigurationException { - return ReflectionUtils.getClass(this, ENTRY_FORMATTER_CLASS, DEFAULT_ENTRY_FORMATTER, EntryFormatter.class, - DEFAULT_LOADER); + public Class getEntryFormatterClass(){ + return ENTRY_FORMATTER_CLASS_KEY.getClass(this, EntryFormatter.class); } /** @@ -652,7 +1042,7 @@ public Class getEntryFormatterClass() */ public T setClientAuthProviderFactoryClass( String factoryClass) { - setProperty(CLIENT_AUTH_PROVIDER_FACTORY_CLASS, factoryClass); + CLIENT_AUTH_PROVIDER_FACTORY_CLASS_KEY.set(this, factoryClass); return getThis(); } @@ -663,7 +1053,7 @@ public T setClientAuthProviderFactoryClass( * @return the client authentication provider factory class name or null. */ public String getClientAuthProviderFactoryClass() { - return getString(CLIENT_AUTH_PROVIDER_FACTORY_CLASS, null); + return CLIENT_AUTH_PROVIDER_FACTORY_CLASS_KEY.getString(this); } /** @@ -673,7 +1063,7 @@ public String getClientAuthProviderFactoryClass() { * @return the maximum netty frame size in bytes. */ public int getNettyMaxFrameSizeBytes() { - return getInt(NETTY_MAX_FRAME_SIZE, DEFAULT_NETTY_MAX_FRAME_SIZE); + return NETTY_MAX_FRAME_SIZE_KEY.getInt(this); } /** @@ -685,7 +1075,7 @@ public int getNettyMaxFrameSizeBytes() { * @return server configuration */ public T setNettyMaxFrameSizeBytes(int maxSize) { - setProperty(NETTY_MAX_FRAME_SIZE, String.valueOf(maxSize)); + NETTY_MAX_FRAME_SIZE_KEY.set(this, maxSize); return getThis(); } @@ -695,7 +1085,7 @@ public T setNettyMaxFrameSizeBytes(int maxSize) { * @return the security provider factory class name or null. */ public String getTLSProviderFactoryClass() { - return getString(TLS_PROVIDER_FACTORY_CLASS, null); + return TLS_PROVIDER_FACTORY_CLASS_KEY.getString(this); } /** @@ -706,7 +1096,7 @@ public String getTLSProviderFactoryClass() { * @return client configuration */ public T setTLSProviderFactoryClass(String factoryClass) { - setProperty(TLS_PROVIDER_FACTORY_CLASS, factoryClass); + TLS_PROVIDER_FACTORY_CLASS_KEY.set(this, factoryClass); return getThis(); } @@ -716,7 +1106,7 @@ public T setTLSProviderFactoryClass(String factoryClass) { * @return the TLS provider to use in creating TLS Context */ public String getTLSProvider() { - return getString(TLS_PROVIDER, "OpenSSL"); + return TLS_PROVIDER_KEY.getString(this); } /** @@ -727,7 +1117,7 @@ public String getTLSProvider() { * @return Client Configuration */ public T setTLSProvider(String provider) { - setProperty(TLS_PROVIDER, provider); + TLS_PROVIDER_KEY.set(this, provider); return getThis(); } @@ -738,7 +1128,7 @@ public T setTLSProvider(String provider) { * @return whether TLS is enabled on the bookie or not. */ public boolean getTLSClientAuthentication() { - return getBoolean(TLS_CLIENT_AUTHENTICATION, false); + return TLS_CLIENT_AUTHENTICATION_KEY.getBoolean(this); } /** @@ -749,7 +1139,26 @@ public boolean getTLSClientAuthentication() { * @return client configuration */ public T setTLSClientAuthentication(boolean enabled) { - setProperty(TLS_CLIENT_AUTHENTICATION, enabled); + TLS_CLIENT_AUTHENTICATION_KEY.set(this, enabled); + return getThis(); + } + + /** + * Get the path to file containing TLS Certificate. + * + * @return + */ + public String getTLSCertificatePath() { + return TLS_CERTIFICATE_PATH_KEY.getString(this); + } + + /** + * Set the path to file containing TLS Certificate. + * + * @return + */ + public T setTLSCertificatePath(String arg) { + TLS_CLIENT_AUTHENTICATION_KEY.set(this, arg); return getThis(); } @@ -763,7 +1172,7 @@ public T setTLSClientAuthentication(boolean enabled) { */ public T setTLSEnabledCipherSuites( String list) { - setProperty(TLS_ENABLED_CIPHER_SUITES, list); + TLS_ENABLED_CIPHER_SUITES_KEY.set(this, list); return getThis(); } @@ -775,7 +1184,7 @@ public T setTLSEnabledCipherSuites( * @see #setTLSEnabledCipherSuites(java.lang.String) */ public String getTLSEnabledCipherSuites() { - return getString(TLS_ENABLED_CIPHER_SUITES, null); + return TLS_ENABLED_CIPHER_SUITES_KEY.getString(this); } /** @@ -788,7 +1197,7 @@ public String getTLSEnabledCipherSuites() { */ public T setTLSEnabledProtocols( String list) { - setProperty(TLS_ENABLED_PROTOCOLS, list); + TLS_ENABLED_PROTOCOLS_KEY.set(this, list); return getThis(); } @@ -800,35 +1209,35 @@ public T setTLSEnabledProtocols( * @see #setTLSEnabledProtocols(java.lang.String) */ public String getTLSEnabledProtocols() { - return getString(TLS_ENABLED_PROTOCOLS, null); + return TLS_ENABLED_PROTOCOLS_KEY.getString(this); } /** * Set the minimum number of racks per write quorum. */ public void setMinNumRacksPerWriteQuorum(int minNumRacksPerWriteQuorum) { - setProperty(MIN_NUM_RACKS_PER_WRITE_QUORUM, minNumRacksPerWriteQuorum); + MIN_NUM_RACKS_PER_WRITE_QUORUM_KEY.set(this, minNumRacksPerWriteQuorum); } /** * Get the minimum number of racks per write quorum. */ public int getMinNumRacksPerWriteQuorum() { - return getInteger(MIN_NUM_RACKS_PER_WRITE_QUORUM, 2); + return MIN_NUM_RACKS_PER_WRITE_QUORUM_KEY.getInt(this); } /** * Set the flag to enforce minimum number of racks per write quorum. */ public void setEnforceMinNumRacksPerWriteQuorum(boolean enforceMinNumRacksPerWriteQuorum) { - setProperty(ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM, enforceMinNumRacksPerWriteQuorum); + ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM_KEY.set(this, enforceMinNumRacksPerWriteQuorum); } /** * Get the flag which enforces the minimum number of racks per write quorum. */ public boolean getEnforceMinNumRacksPerWriteQuorum() { - return getBoolean(ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM, false); + return ENFORCE_MIN_NUM_RACKS_PER_WRITE_QUORUM_KEY.getBoolean(this); } /** @@ -843,7 +1252,7 @@ public boolean getEnforceMinNumRacksPerWriteQuorum() { * underreplicated ledger mark time. */ public T setStoreSystemTimeAsLedgerUnderreplicatedMarkTime(boolean enabled) { - setProperty(STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME, enabled); + STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME_KEY.set(this, enabled); return getThis(); } @@ -855,7 +1264,7 @@ public T setStoreSystemTimeAsLedgerUnderreplicatedMarkTime(boolean enabled) { * underreplicated ledger mark time. */ public boolean getStoreSystemTimeAsLedgerUnderreplicatedMarkTime() { - return getBoolean(STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME, true); + return STORE_SYSTEMTIME_AS_LEDGER_UNDERREPLICATED_MARK_TIME_KEY.getBoolean(this); } /** @@ -864,7 +1273,7 @@ public boolean getStoreSystemTimeAsLedgerUnderreplicatedMarkTime() { * @return flag to enable/disable MDC preservation in Executor. */ public boolean getPreserveMdcForTaskExecution() { - return getBoolean(PRESERVE_MDC_FOR_TASK_EXECUTION, false); + return PRESERVE_MDC_FOR_TASK_EXECUTION_KEY.getBoolean(this); } /** @@ -875,7 +1284,7 @@ public boolean getPreserveMdcForTaskExecution() { * @return configuration. */ public T setPreserveMdcForTaskExecution(boolean enabled) { - setProperty(PRESERVE_MDC_FOR_TASK_EXECUTION, enabled); + PRESERVE_MDC_FOR_TASK_EXECUTION_KEY.set(this, enabled); return getThis(); } @@ -886,7 +1295,7 @@ public T setPreserveMdcForTaskExecution(boolean enabled) { * the boolean flag indicating whether to limit stats logging */ public boolean getLimitStatsLogging() { - return getBoolean(LIMIT_STATS_LOGGING, false); + return LIMIT_STATS_LOGGING_KEY.getBoolean(this); } /** @@ -897,7 +1306,7 @@ public boolean getLimitStatsLogging() { * @return configuration. */ public T setLimitStatsLogging(boolean limitStatsLogging) { - setProperty(LIMIT_STATS_LOGGING, limitStatsLogging); + LIMIT_STATS_LOGGING_KEY.set(this, limitStatsLogging); return getThis(); } diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ClientConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ClientConfiguration.java index 7d0d319882b..6236a495e2d 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ClientConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ClientConfiguration.java @@ -178,12 +178,12 @@ public class ClientConfiguration extends AbstractConfiguration { + // + // Security Settings + // + + protected static final String BOOKIE_AUTH_PROVIDER_FACTORY_CLASS = "bookieAuthProviderFactoryClass"; + protected static final ConfigKey BOOKIE_AUTH_PROVIDER_FACTORY_CLASS_KEY = + ConfigKey.builder(BOOKIE_AUTH_PROVIDER_FACTORY_CLASS) + .type(Type.CLASS) + .description("The bookie authentication provider factory class name") + .documentation("If this is null, no authentication will take place") + .group(GROUP_SECURITY) + .orderInGroup(100) + .build(); + + public static final String PERMITTED_STARTUP_USERS = "permittedStartupUsers"; + protected static final ConfigKey PERMITTED_STARTUP_USERS_KEY = ConfigKey.builder(PERMITTED_STARTUP_USERS) + .type(Type.ARRAY) + .description("The list of users are permitted to run the bookie process. any users can run the bookie" + + " process if it is not set.") + .documentation("Example settings: permittedStartupUsers=user1,user2,user3") + .group(GROUP_SECURITY) + .orderInGroup(101) + .build(); + + // + // Metadata Settings + // + + protected static final String REGISTRATION_MANAGER_CLASS = "registrationManagerClass"; + protected static final ConfigKey REGISTRATION_MANAGER_CLASS_KEY = ConfigKey.builder(REGISTRATION_MANAGER_CLASS) + .type(Type.CLASS) + .description("The registration manager implementation used for registering bookies for service discovery") + .defaultValue(ZKRegistrationManager.class) + .group(GROUP_METADATA_SERVICE) + .orderInGroup(100) + .build(); + + // + // Discovery Settings + // + + private static final ConfigKeyGroup GROUP_BOOKIE_DISCOVERY = ConfigKeyGroup.builder("discovery") + .description("Bookie discovery related settings (e.g. nic & port to listen on, advertised address, and etc)") + .order(100) + .build(); + + protected static final String BOOKIE_PORT = "bookiePort"; + protected static final ConfigKey BOOKIE_PORT_KEY = ConfigKey.builder(BOOKIE_PORT) + .type(Type.INT) + .description("The port that the bookie server listens on") + .defaultValue(3181) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(100) + .build(); + + protected static final String LISTENING_INTERFACE = "listeningInterface"; + protected static final ConfigKey LISTENING_INTERFACE_KEY = ConfigKey.builder(LISTENING_INTERFACE) + .type(Type.STRING) + .description("Set the network interface that the bookie should listen on") + .documentation("If not set, the bookie will listen on all interfaces") + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(101) + .build(); + + protected static final String ADVERTISED_ADDRESS = "advertisedAddress"; + protected static final ConfigKey ADVERTISED_ADDRESS_KEY = ConfigKey.builder(ADVERTISED_ADDRESS) + .type(Type.STRING) + .description("Configure a specific hostname or IP address that the bookie should use to" + + " advertise itself to clients") + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(102) + .build(); + + protected static final String ALLOW_LOOPBACK = "allowLoopback"; + protected static final ConfigKey ALLOW_LOOPBACK_KEY = ConfigKey.builder(ALLOW_LOOPBACK) + .type(Type.BOOLEAN) + .description("Whether the bookie allowed to use a loopback interface as its primary" + + " interface(i.e. the interface it uses to establish its identity)?") + .documentation("By default, loopback interfaces are not allowed as the primary interface." + + " Using a loopback interface as the primary interface usually indicates a configuration" + + " error. For example, its fairly common in some VPS setups to not configure a hostname," + + " or to have the hostname resolve to 127.0.0.1. If this is the case, then all bookies in" + + " the cluster will establish their identities as 127.0.0.1:3181, and only one will be able" + + " to join the cluster. For VPSs configured like this, you should explicitly set the listening" + + " interface.") + .defaultValue(false) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(103) + .build(); + + protected static final String ALLOW_EPHEMERAL_PORTS = "allowEphemeralPorts"; + protected static final ConfigKey ALLOW_EPHEMERAL_PORTS_KEY = ConfigKey.builder(ALLOW_EPHEMERAL_PORTS) + .type(Type.BOOLEAN) + .description("Whether the bookie is allowed to use an ephemeral port (port 0) as its server port") + .documentation("By default, an ephemeral port is not allowed. Using an ephemeral port as the service" + + " port usually indicates a configuration error. However, in unit tests, using an ephemeral" + + " port will address port conflict problems and allow running tests in parallel") + .defaultValue(false) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(104) + .build(); + + + protected static final String USE_HOST_NAME_AS_BOOKIE_ID = "useHostNameAsBookieID"; + protected static final String USE_SHORT_HOST_NAME = "useShortHostName"; + + protected static final ConfigKey USE_HOST_NAME_AS_BOOKIE_ID_KEY = ConfigKey.builder(USE_HOST_NAME_AS_BOOKIE_ID) + .type(Type.BOOLEAN) + .description("Whether the bookie should use its hostname to register with the co-ordination service" + + " (eg: Zookeeper service)") + .documentation("When false, bookie will use its ipaddress of '" + LISTENING_INTERFACE + + "' for the registration") + .defaultValue(false) + .dependents(Lists.newArrayList(USE_SHORT_HOST_NAME)) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(105) + .build(); + + protected static final ConfigKey USE_SHORT_HOST_NAME_KEY = ConfigKey.builder(USE_SHORT_HOST_NAME) + .type(Type.BOOLEAN) + .description("If bookie is using hostname for registration and in ledger metadata then whether" + + " to use short hostname or FQDN hostname") + .defaultValue(false) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(106) + .build(); + + protected static final String ENABLE_LOCAL_TRANSPORT = "enableLocalTransport"; + protected static final ConfigKey ENABLE_LOCAL_TRANSPORT_KEY = ConfigKey.builder(ENABLE_LOCAL_TRANSPORT) + .type(Type.BOOLEAN) + .description("Whether allow the bookie to listen for BookKeeper clients executed on the local JVM") + .defaultValue(false) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(107) + .build(); + + protected static final String DISABLE_SERVER_SOCKET_BIND = "disableServerSocketBind"; + protected static final ConfigKey DISABLE_SERVER_SOCKET_BIND_KEY = ConfigKey.builder(DISABLE_SERVER_SOCKET_BIND) + .type(Type.BOOLEAN) + .description("Whether allow the bookie to disable bind on network interfaces, this bookie" + + " will be available only to BookKeeper clients executed on the local JVM") + .defaultValue(false) + .group(GROUP_BOOKIE_DISCOVERY) + .orderInGroup(108) + .build(); + + // + // Server Settings + // + + private static final ConfigKeyGroup GROUP_SERVER = ConfigKeyGroup.builder("server") + .description("Generic bookie server settings") + .order(110) + .build(); + + protected static final String ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION = + "allowMultipleDirsUnderSameDiskPartition"; + protected static final ConfigKey ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION_KEY = + ConfigKey.builder(ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION) + .type(Type.BOOLEAN) + .description("Configure the bookie to allow/disallow multiple ledger/index/journal directories" + + " in the same filesystem disk partition") + .defaultValue(true) + .group(GROUP_SERVER) + .orderInGroup(100) + .build(); + + protected static final String DEATH_WATCH_INTERVAL = "bookieDeathWatchInterval"; + protected static final ConfigKey DEATH_WATCH_INTERVAL_KEY = ConfigKey.builder(DEATH_WATCH_INTERVAL) + .type(Type.INT) + .description("Interval to watch whether bookie is dead or not, in milliseconds") + .defaultValue(1000) + .group(GROUP_SERVER) + .orderInGroup(101) + .build(); + + // Lifecycle Components + protected static final String EXTRA_SERVER_COMPONENTS = "extraServerComponents"; + protected static final ConfigKey EXTRA_SERVER_COMPONENTS_KEY = ConfigKey.builder(EXTRA_SERVER_COMPONENTS) + .type(Type.ARRAY) + .description("Configure a list of server components to enable and load on a bookie server") + .documentation("This provides the plugin run extra services along with a bookie server.\n\n" + + "NOTE: if bookie fails to load any of extra components configured below, bookie will continue" + + " functioning by ignoring the components configured below.") + .optionValues(Lists.newArrayList( + "org.apache.bookkeeper.stream.server.StreamStorageLifecycleComponent" + )) + .group(GROUP_SERVER) + .orderInGroup(102) + .build(); + + protected static final String IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES = + "ignoreExtraServerComponentsStartupFailures"; + protected static final ConfigKey IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES_KEY = + ConfigKey.builder(IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES) + .type(Type.BOOLEAN) + .description("Whether the bookie should ignore startup failures on loading server components specified" + + " by `" + EXTRA_SERVER_COMPONENTS + "`") + .defaultValue(false) + .group(GROUP_SERVER) + .orderInGroup(103) + .build(); + + // + // Thread settings + // + + private static final ConfigKeyGroup GROUP_THREAD = ConfigKeyGroup.builder("thread") + .description("Thread related settings") + .order(120) + .build(); + + protected static final String NUM_ADD_WORKER_THREADS = "numAddWorkerThreads"; + protected static final ConfigKey NUM_ADD_WORKER_THREADS_KEY = ConfigKey.builder(NUM_ADD_WORKER_THREADS) + .type(Type.INT) + .description("Number of threads that should handle write requests") + .documentation("If zero, the writes would be handled by netty threads directly") + .defaultValue(1) + .group(GROUP_THREAD) + .orderInGroup(100) + .build(); + + protected static final String NUM_READ_WORKER_THREADS = "numReadWorkerThreads"; + protected static final ConfigKey NUM_READ_WORKER_THREADS_KEY = ConfigKey.builder(NUM_READ_WORKER_THREADS) + .type(Type.INT) + .description("Number of threads that should handle read requests") + .documentation("If zero, the reads would be handled by netty threads directly") + .defaultValue(8) + .group(GROUP_THREAD) + .orderInGroup(101) + .build(); + + protected static final String NUM_LONG_POLL_WORKER_THREADS = "numLongPollWorkerThreads"; + protected static final ConfigKey NUM_LONG_POLL_WORKER_THREADS_KEY = ConfigKey.builder(NUM_LONG_POLL_WORKER_THREADS) + .type(Type.INT) + .description("Number of threads that should handle read requests") + .documentation("If zero, the reads would be handled by netty threads directly") + .defaultValue(0) + .group(GROUP_THREAD) + .orderInGroup(102) + .build(); + + protected static final String NUM_JOURNAL_CALLBACK_THREADS = "numJournalCallbackThreads"; + protected static final ConfigKey NUM_JOURNAL_CALLBACK_THREADS_KEY = ConfigKey.builder(NUM_JOURNAL_CALLBACK_THREADS) + .type(Type.INT) + .description("The number of threads used for handling journal callback") + .documentation("If a zero or negative number is provided, the callbacks are executed" + + " directly at force write threads") + .defaultValue(1) + .group(GROUP_THREAD) + .orderInGroup(103) + .build(); + + protected static final String NUM_HIGH_PRIORITY_WORKER_THREADS = "numHighPriorityWorkerThreads"; + protected static final ConfigKey NUM_HIGH_PRIORITY_WORKER_THREADS_KEY = + ConfigKey.builder(NUM_HIGH_PRIORITY_WORKER_THREADS) + .type(Type.INT) + .description("Number of threads that should be used for high priority requests" + + " (i.e. recovery reads and adds, and fencing)") + .defaultValue(8) + .group(GROUP_THREAD) + .orderInGroup(104) + .build(); + + protected static final String MAX_PENDING_READ_REQUESTS_PER_THREAD = "maxPendingReadRequestsPerThread"; + protected static final ConfigKey MAX_PENDING_READ_REQUESTS_PER_THREAD_KEY = + ConfigKey.builder(MAX_PENDING_READ_REQUESTS_PER_THREAD) + .type(Type.INT) + .description("If read workers threads are enabled, limit the number of pending requests," + + " to avoid the executor queue to grow indefinitely") + .defaultValue(10000) + .group(GROUP_THREAD) + .orderInGroup(105) + .build(); + + protected static final String MAX_PENDING_ADD_REQUESTS_PER_THREAD = "maxPendingAddRequestsPerThread"; + protected static final ConfigKey MAX_PENDING_ADD_REQUESTS_PER_THREAD_KEY = + ConfigKey.builder(MAX_PENDING_ADD_REQUESTS_PER_THREAD) + .type(Type.INT) + .description("If add workers threads are enabled, limit the number of pending requests," + + " to avoid the executor queue to grow indefinitely") + .defaultValue(10000) + .group(GROUP_THREAD) + .orderInGroup(106) + .build(); + + // + // LongPoll Settings + // + + private static final ConfigKeyGroup GROUP_LONGPOLL = ConfigKeyGroup.builder("longpoll") + .description("Long poll related settings") + .order(130) + .build(); + + protected static final String REQUEST_TIMER_TICK_DURATION_MILLISEC = "requestTimerTickDurationMs"; + protected static final ConfigKey REQUEST_TIMER_TICK_DURATION_MILLISEC_KEY = + ConfigKey.builder(REQUEST_TIMER_TICK_DURATION_MILLISEC) + .type(Type.INT) + .description("The tick duration in milliseconds for long poll requests") + .defaultValue(10) + .group(GROUP_LONGPOLL) + .orderInGroup(100) + .build(); + + protected static final String REQUEST_TIMER_NO_OF_TICKS = "requestTimerNumTicks"; + protected static final ConfigKey REQUEST_TIMER_NO_OF_TICKS_KEY = + ConfigKey.builder(REQUEST_TIMER_NO_OF_TICKS) + .type(Type.INT) + .description("The number of ticks per wheel for the long poll request timer") + .defaultValue(1024) + .group(GROUP_LONGPOLL) + .orderInGroup(101) + .build(); + + // + // Backpressure control settings + // + + private static final ConfigKeyGroup GROUP_BACKPRESSURE = ConfigKeyGroup.builder("backpressure") + .description("Backpressure control related settings") + .order(140) + .build(); + + protected static final String MAX_ADDS_IN_PROGRESS_LIMIT = "maxAddsInProgressLimit"; + protected static final ConfigKey MAX_ADDS_IN_PROGRESS_LIMIT_KEY = + ConfigKey.builder(MAX_ADDS_IN_PROGRESS_LIMIT) + .type(Type.INT) + .description("max number of adds in progress. 0 == unlimited") + .documentation("If the number of add requests in progress reaches this threshold, bookie" + + " will be blocking the add threads util some add requests are completed") + .defaultValue(0) + .group(GROUP_BACKPRESSURE) + .orderInGroup(100) + .build(); + + protected static final String MAX_READS_IN_PROGRESS_LIMIT = "maxReadsInProgressLimit"; + protected static final ConfigKey MAX_READS_IN_PROGRESS_LIMIT_KEY = + ConfigKey.builder(MAX_READS_IN_PROGRESS_LIMIT) + .type(Type.INT) + .description("max number of adds in progress. 0 == unlimited") + .documentation("If the number of read requests in progress reaches this threshold, bookie" + + " will be blocking the read threads util some read requests are completed") + .defaultValue(0) + .group(GROUP_BACKPRESSURE) + .orderInGroup(101) + .build(); + + protected static final String WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE = "waitTimeoutOnResponseBackpressureMs"; + protected static final ConfigKey WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE_KEY = + ConfigKey.builder(WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE) + .type(Type.LONG) + .description("Timeout controlling wait on response send in case of unresponsive client" + + " (i.e. client in long GC etc.)") + .documentation("negative value disables the feature, 0 to allow request to fail immediately") + .defaultValue(-1L) + .group(GROUP_BACKPRESSURE) + .orderInGroup(102) + .build(); + + protected static final String CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT = "closeChannelOnResponseTimeout"; + protected static final ConfigKey CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT_KEY = + ConfigKey.builder(CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT) + .type(Type.BOOLEAN) + .documentation("Configures action in case if server timed out sending response to the client." + + " `true` == close the channel and drop response; `false` == drop response. It requires" + + " `" + WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE + "` >= 0 otherwise ignored.") + .defaultValue(false) + .group(GROUP_BACKPRESSURE) + .orderInGroup(103) + .build(); + + // + // Read-only mode support + // + + private static final ConfigKeyGroup GROUP_READONLY = ConfigKeyGroup.builder("readonly") + .description("Read-only mode related settings") + .order(150) + .build(); + + protected static final String READ_ONLY_MODE_ENABLED = "readOnlyModeEnabled"; + protected static final ConfigKey READ_ONLY_MODE_ENABLED_KEY = ConfigKey.builder(READ_ONLY_MODE_ENABLED) + .type(Type.BOOLEAN) + .description("If all ledger directories configured are full, then support only read requests for clients") + .documentation("If `" + READ_ONLY_MODE_ENABLED + "=true` then on all ledger disks full," + + " bookie will be converted to read-only mode and serve only read requests." + + " Otherwise the bookie will be shutdown. By default this will be disabled.") + .defaultValue(true) + .group(GROUP_READONLY) + .orderInGroup(100) + .build(); + + + protected static final String FORCE_READ_ONLY_BOOKIE = "forceReadOnlyBookie"; + protected static final ConfigKey FORCE_READ_ONLY_BOOKIE_KEY = ConfigKey.builder(FORCE_READ_ONLY_BOOKIE) + .type(Type.BOOLEAN) + .description("Whether the bookie is force started in read only mode or not") + .defaultValue(false) + .group(GROUP_READONLY) + .orderInGroup(101) + .build(); + + //Whether to persist the bookie status + protected static final String PERSIST_BOOKIE_STATUS_ENABLED = "persistBookieStatusEnabled"; + protected static final ConfigKey PERSIST_BOOKIE_STATUS_ENABLED_KEY = + ConfigKey.builder(PERSIST_BOOKIE_STATUS_ENABLED) + .type(Type.BOOLEAN) + .description("Persist the bookie status locally on the disks. So the bookies can keep their" + + " status upon restarts") + .defaultValue(false) + .group(GROUP_READONLY) + .orderInGroup(102) + .since("4.6") + .build(); + + // + // Netty Server Settings + // + + protected static final String SERVER_TCP_NODELAY = "serverTcpNoDelay"; + protected static final ConfigKey SERVER_TCP_NODELAY_KEY = ConfigKey.builder(SERVER_TCP_NODELAY) + .type(Type.BOOLEAN) + .description("This settings is used to enabled/disabled Nagle's algorithm") + .documentation("The Nagle's algorithm is a means of improving the efficiency of" + + " TCP/IP networks by reducing the number of packets that need to be sent" + + " over the network. If you are sending many small messages, such that more" + + " than one can fit in a single IP packet, setting server.tcpnodelay to false" + + " to enable Nagle algorithm can provide better performance.") + .defaultValue(true) + .group(GROUP_NETTY) + .orderInGroup(100) + .build(); + + protected static final String SERVER_SOCK_KEEPALIVE = "serverSockKeepalive"; + protected static final ConfigKey SERVER_SOCK_KEEPALIVE_KEY = ConfigKey.builder(SERVER_SOCK_KEEPALIVE) + .type(Type.BOOLEAN) + .description("This setting is used to send keep-alive messages on connection-oriented sockets") + .defaultValue(true) + .group(GROUP_NETTY) + .orderInGroup(101) + .build(); + + protected static final String SERVER_SOCK_LINGER = "serverTcpLinger"; + protected static final ConfigKey SERVER_SOCK_LINGER_KEY = ConfigKey.builder(SERVER_SOCK_LINGER) + .type(Type.INT) + .description("The socket linger timeout on close") + .documentation("When enabled, a close or shutdown will not return until all queued messages for" + + " the socket have been successfully sent or the linger timeout has been reached." + + " Otherwise, the call returns immediately and the closing is done in the background") + .defaultValue(0) + .group(GROUP_NETTY) + .orderInGroup(102) + .build(); + + protected static final String SERVER_WRITEBUFFER_LOW_WATER_MARK = "serverWriteBufferLowWaterMark"; + protected static final ConfigKey SERVER_WRITEBUFFER_LOW_WATER_MARK_KEY = + ConfigKey.builder(SERVER_WRITEBUFFER_LOW_WATER_MARK) + .type(Type.INT) + .description("server netty channel write buffer low water mark") + .documentation("Once the number of bytes queued in the write buffer exceeded the `" + + SERVER_WRITEBUFFER_LOW_WATER_MARK + "` and then dropped down below this value," + + " a netty channel `Channel.isWritable()` will start to return true again.") + .defaultValue(384 * 1024) + .group(GROUP_NETTY) + .orderInGroup(103) + .build(); + + protected static final String SERVER_WRITEBUFFER_HIGH_WATER_MARK = "serverWriteBufferHighWaterMark"; + protected static final ConfigKey SERVER_WRITEBUFFER_HIGH_WATER_MARK_KEY = + ConfigKey.builder(SERVER_WRITEBUFFER_HIGH_WATER_MARK) + .type(Type.INT) + .description("server netty channel write buffer high water mark") + .documentation("If the number of bytes queued in the write buffer exceeds this value," + + " a netty channel `Channel.isWritable()` will start to return false.") + .defaultValue(512 * 1024) + .group(GROUP_NETTY) + .orderInGroup(104) + .build(); + + protected static final String SERVER_NUM_IO_THREADS = "serverNumIOThreads"; + protected static final ConfigKey SERVER_NUM_IO_THREADS_KEY = ConfigKey.builder(SERVER_NUM_IO_THREADS) + .type(Type.INT) + .description("The number of netty IO threads") + .documentation("This is the number of threads used by Netty to handle TCP connections") + .defaultValueSupplier(conf -> 2 * Runtime.getRuntime().availableProcessors()) + .group(GROUP_NETTY) + .orderInGroup(105) + .build(); + + protected static final String BYTEBUF_ALLOCATOR_SIZE_INITIAL = "byteBufAllocatorSizeInitial"; + protected static final ConfigKey BYTEBUF_ALLOCATOR_SIZE_INITIAL_KEY = + ConfigKey.builder(BYTEBUF_ALLOCATOR_SIZE_INITIAL) + .type(Type.INT) + .description("The Recv ByteBuf allocator initial buf size") + .defaultValue(66536) + .group(GROUP_NETTY) + .orderInGroup(106) + .build(); + + protected static final String BYTEBUF_ALLOCATOR_SIZE_MIN = "byteBufAllocatorSizeMin"; + protected static final ConfigKey BYTEBUF_ALLOCATOR_SIZE_MIN_KEY = + ConfigKey.builder(BYTEBUF_ALLOCATOR_SIZE_MIN) + .type(Type.INT) + .description("The Recv ByteBuf allocator min buf size") + .defaultValue(66536) + .group(GROUP_NETTY) + .orderInGroup(107) + .build(); + + protected static final String BYTEBUF_ALLOCATOR_SIZE_MAX = "byteBufAllocatorSizeMax"; + protected static final ConfigKey BYTEBUF_ALLOCATOR_SIZE_MAX_KEY = + ConfigKey.builder(BYTEBUF_ALLOCATOR_SIZE_MAX) + .type(Type.INT) + .description("The Recv ByteBuf allocator max buf size") + .defaultValue(1048576) + .group(GROUP_NETTY) + .orderInGroup(108) + .build(); + + // + // Http Server Settings + // + + private static final ConfigKeyGroup GROUP_HTTP = ConfigKeyGroup.builder("http") + .description("Admin http server related settings") + .order(160) + .build(); + + protected static final String HTTP_SERVER_ENABLED = "httpServerEnabled"; + protected static final ConfigKey HTTP_SERVER_ENABLED_KEY = ConfigKey.builder(HTTP_SERVER_ENABLED) + .type(Type.BOOLEAN) + .description("The flag enables/disables starting the admin http server") + .defaultValue(false) + .group(GROUP_HTTP) + .orderInGroup(100) + .build(); + + protected static final String HTTP_SERVER_PORT = "httpServerPort"; + protected static final ConfigKey HTTP_SERVER_PORT_KEY = ConfigKey.builder(HTTP_SERVER_PORT) + .type(Type.INT) + .description("The http server port to listen on") + .defaultValue(8080) + .group(GROUP_HTTP) + .orderInGroup(101) + .build(); + + protected static final String HTTP_SERVER_CLASS = "httpServerClass"; + protected static final ConfigKey HTTP_SERVER_CLASS_KEY = ConfigKey.builder(HTTP_SERVER_CLASS) + .type(Type.CLASS) + .description("The http server class") + .defaultValue("org.apache.bookkeeper.http.vertx.VertxHttpServer") + .group(GROUP_HTTP) + .orderInGroup(102) + .build(); + + // + // Journal Settings + // + + private static final ConfigKeyGroup GROUP_JOURNAL = ConfigKeyGroup.builder("journal") + .description("Journal related settings") + .order(170) + .build(); + + protected static final String JOURNAL_DIRS = "journalDirectories"; + protected static final ConfigKey JOURNAL_DIRS_KEY = ConfigKey.builder(JOURNAL_DIRS) + .type(Type.ARRAY) + .description("Directories BookKeeper outputs its write ahead log") + .documentation("You could define multi directories to store write head logs, separated by ','." + + " For example: `journalDirectories=/tmp/bk-journal1,/tmp/bk-journal2`. If journalDirectories" + + " is set, bookies will skip journalDirectory and use this setting directory.") + .defaultValue("/tmp/bk-txn") + .group(GROUP_JOURNAL) + .orderInGroup(100) + .deprecated(true) + .deprecatedSince("4.5.0") + .deprecatedByConfigKey(JOURNAL_DIRS) + .build(); + + protected static final String JOURNAL_DIR = "journalDirectory"; + protected static final ConfigKey JOURNAL_DIR_KEY = ConfigKey.builder(JOURNAL_DIR) + .type(Type.STRING) + .description("Directory Bookkeeper outputs its write ahead log") + .defaultValue("/tmp/bk-txn") + .group(GROUP_JOURNAL) + .orderInGroup(100) + .deprecated(true) + .deprecatedSince("4.5.0") + .deprecatedByConfigKey(JOURNAL_DIRS) + .build(); + + protected static final String JOURNAL_ALIGNMENT_SIZE = "journalAlignmentSize"; + + protected static final String JOURNAL_FORMAT_VERSION_TO_WRITE = "journalFormatVersionToWrite"; + protected static final ConfigKey JOURNAL_FORMAT_VERSION_TO_WRITE_KEY = + ConfigKey.builder(JOURNAL_FORMAT_VERSION_TO_WRITE) + .type(Type.INT) + .description("The journal format version to write") + .documentation("If you'd like to disable persisting ExplicitLac, you can set this" + + " config to < `6` and also # fileInfoFormatVersionToWrite should be set" + + " to 0. If there is mismatch then the serverconfig is considered invalid." + + " You can disable `padding-writes` by setting journal version back to `4`." + + " This feature is available since 4.5.0 and onward versions.") + .optionValues(Lists.newArrayList( + " 1: no header", + " 2: a header section was added", + " 3: ledger key was introduced", + " 4: fencing key was introduced", + " 5: expanding header to 512 and padding writes to align sector size configured" + + " by `" + JOURNAL_ALIGNMENT_SIZE + "`", + " 6: persisting explicitLac is introduced" + )) + .defaultValue(6) + .group(GROUP_JOURNAL) + .orderInGroup(101) + .build(); + + protected static final String MAX_JOURNAL_SIZE = "journalMaxSizeMB"; + protected static final ConfigKey MAX_JOURNAL_SIZE_KEY = ConfigKey.builder(MAX_JOURNAL_SIZE) + .type(Type.LONG) + .description("Max file size of journal file, in mega bytes") + .documentation("A new journal file will be created when the old one reaches the file size limitation") + .defaultValue(2048L) + .group(GROUP_JOURNAL) + .orderInGroup(102) + .build(); + + protected static final String MAX_BACKUP_JOURNALS = "journalMaxBackups"; + protected static final ConfigKey MAX_BACKUP_JOURNALS_KEY = ConfigKey.builder(MAX_BACKUP_JOURNALS) + .type(Type.INT) + .description("Max number of old journal file to kept") + .documentation("Keep a number of old journal files would help data recovery in special case") + .defaultValue(5) + .group(GROUP_JOURNAL) + .orderInGroup(103) + .build(); + + protected static final String JOURNAL_PRE_ALLOC_SIZE = "journalPreAllocSizeMB"; + protected static final ConfigKey JOURNAL_PRE_ALLOC_SIZE_KEY = ConfigKey.builder(JOURNAL_PRE_ALLOC_SIZE) + .type(Type.INT) + .description("How much space should we pre-allocate at a time in the journal") + .defaultValue(16) + .group(GROUP_JOURNAL) + .orderInGroup(104) + .build(); + + protected static final String JOURNAL_WRITE_BUFFER_SIZE = "journalWriteBufferSizeKB"; + protected static final ConfigKey JOURNAL_WRITE_BUFFER_SIZE_KEY = ConfigKey.builder(JOURNAL_WRITE_BUFFER_SIZE) + .type(Type.INT) + .description("Size of the write buffers used for the journal") + .defaultValue(64) + .group(GROUP_JOURNAL) + .orderInGroup(105) + .build(); + + protected static final String JOURNAL_REMOVE_FROM_PAGE_CACHE = "journalRemoveFromPageCache"; + protected static final ConfigKey JOURNAL_REMOVE_FROM_PAGE_CACHE_KEY = + ConfigKey.builder(JOURNAL_REMOVE_FROM_PAGE_CACHE) + .type(Type.BOOLEAN) + .description("Should we remove pages from page cache after force write") + .defaultValue(true) + .group(GROUP_JOURNAL) + .orderInGroup(106) + .build(); + + protected static final String JOURNAL_SYNC_DATA = "journalSyncData";; + protected static final ConfigKey JOURNAL_SYNC_DATA_KEY = ConfigKey.builder(JOURNAL_SYNC_DATA) + .type(Type.BOOLEAN) + .description("Should the data be fsynced on journal before acknowledgment") + .documentation("By default, data sync is enabled to guarantee durability of writes." + + " Beware: while disabling data sync in the Bookie journal might improve the" + + " bookie write performance, it will also introduce the possibility of data" + + " loss. With no sync, the journal entries are written in the OS page cache" + + " but not flushed to disk. In case of power failure, the affected bookie might" + + " lose the unflushed data. If the ledger is replicated to multiple bookies," + + " the chances of data loss are reduced though still present.") + .defaultValue(true) + .group(GROUP_JOURNAL) + .orderInGroup(107) + .build(); + + protected static final String JOURNAL_ADAPTIVE_GROUP_WRITES = "journalAdaptiveGroupWrites"; + protected static final ConfigKey JOURNAL_ADAPTIVE_GROUP_WRITES_KEY = + ConfigKey.builder(JOURNAL_ADAPTIVE_GROUP_WRITES) + .type(Type.BOOLEAN) + .description("Should we group journal force writes, which optimize group commit for higher throughput") + .defaultValue(true) + .group(GROUP_JOURNAL) + .orderInGroup(108) + .build(); + + protected static final String JOURNAL_MAX_GROUP_WAIT_MSEC = "journalMaxGroupWaitMSec"; + protected static final ConfigKey JOURNAL_MAX_GROUP_WAIT_MSEC_KEY = + ConfigKey.builder(JOURNAL_MAX_GROUP_WAIT_MSEC) + .type(Type.LONG) + .description("Maximum latency to impose on a journal write to achieve grouping") + .defaultValue(2L) + .group(GROUP_JOURNAL) + .orderInGroup(109) + .build(); + + protected static final String JOURNAL_BUFFERED_WRITES_THRESHOLD = "journalBufferedWritesThreshold"; + protected static final ConfigKey JOURNAL_BUFFERED_WRITES_THRESHOLD_KEY = + ConfigKey.builder(JOURNAL_BUFFERED_WRITES_THRESHOLD) + .type(Type.LONG) + .description("Maximum bytes to buffer to achieve grouping. 0 or negative value means disabling" + + " bytes-based grouping") + .defaultValue(524288L) + .group(GROUP_JOURNAL) + .orderInGroup(110) + .build(); + + protected static final String JOURNAL_BUFFERED_ENTRIES_THRESHOLD = "journalBufferedEntriesThreshold"; + protected static final ConfigKey JOURNAL_BUFFERED_ENTRIES_THRESHOLD_KEY = + ConfigKey.builder(JOURNAL_BUFFERED_ENTRIES_THRESHOLD) + .type(Type.LONG) + .description("Maximum entries to buffer to impose on a journal write to achieve grouping." + + " 0 or negative value means disable entries-based grouping") + .defaultValue(0L) + .group(GROUP_JOURNAL) + .orderInGroup(111) + .build(); + + protected static final String JOURNAL_FLUSH_WHEN_QUEUE_EMPTY = "journalFlushWhenQueueEmpty"; + protected static final ConfigKey JOURNAL_FLUSH_WHEN_QUEUE_EMPTY_KEY = + ConfigKey.builder(JOURNAL_FLUSH_WHEN_QUEUE_EMPTY) + .type(Type.BOOLEAN) + .description("If we should flush the journal when journal queue is empty") + .defaultValue(false) + .group(GROUP_JOURNAL) + .orderInGroup(112) + .build(); + + protected static final ConfigKey JOURNAL_ALIGNMENT_SIZE_KEY = ConfigKey.builder(JOURNAL_ALIGNMENT_SIZE) + .type(Type.INT) + .description("All the journal writes and commits should be aligned to given size") + .documentation("If not, zeros will be padded to align to given size. It only takes effects" + + " when `" + JOURNAL_FORMAT_VERSION_TO_WRITE + "` is set to 5") + .defaultValue(512) + .validator(new Validator() { + @Override + public boolean validate(String name, Object value) { + if (value instanceof Number) { + int size = ((Number) value).intValue(); + return size >= 512 && (size % 512) == 0; + } else { + return false; + } + } + + @Override + public String toString() { + return "(n * 512) bytes"; + } + }) + .group(GROUP_JOURNAL) + .orderInGroup(113) + .build(); + + // + // Entry Logger Settings + // + + private static final ConfigKeyGroup GROUP_LEDGER_STORAGE_ENTRY_LOGGER = ConfigKeyGroup.builder("entrylogger") + .description("EntryLogger related settings") + .order(180) + .build(); + + protected static final String ENTRY_LOG_SIZE_LIMIT = "logSizeLimit"; + protected static final ConfigKey ENTRY_LOG_SIZE_LIMIT_KEY = ConfigKey.builder(ENTRY_LOG_SIZE_LIMIT) + .type(Type.LONG) + .description("Max file size of entry logger, in bytes") + .documentation("A new entry log file will be created when the old one reaches this file size limitation") + .defaultValue(MAX_LOG_SIZE_LIMIT) + .validator(RangeValidator.between(0, MAX_LOG_SIZE_LIMIT)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(0) + .build(); + + protected static final String ENTRY_LOG_FILE_PREALLOCATION_ENABLED = "entryLogFilePreallocationEnabled"; + protected static final ConfigKey ENTRY_LOG_FILE_PREALLOCATION_ENABLED_KEY = + ConfigKey.builder(ENTRY_LOG_FILE_PREALLOCATION_ENABLED) + .type(Type.BOOLEAN) + .description("Enable/Disable entry logger preallocation") + .defaultValue(true) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(1) + .build(); + + protected static final String FLUSH_ENTRYLOG_INTERVAL_BYTES = "flushEntrylogBytes"; + protected static final ConfigKey FLUSH_ENTRYLOG_INTERVAL_BYTES_KEY = + ConfigKey.builder(FLUSH_ENTRYLOG_INTERVAL_BYTES) + .type(Type.LONG) + .description("Entry log flush interval in bytes") + .documentation("Default is 0. 0 or less disables this feature and effectively flush" + + " happens on log rotation.\nFlushing in smaller chunks but more frequently" + + " reduces spikes in disk I/O. Flushing too frequently may also affect" + + " performance negatively.") + .defaultValue(0) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(2) + .build(); + + protected static final String READ_BUFFER_SIZE = "readBufferSizeBytes"; + protected static final ConfigKey READ_BUFFER_SIZE_KEY = ConfigKey.builder(READ_BUFFER_SIZE) + .type(Type.INT) + .description("The number of bytes we should use as capacity for BufferedReadChannel. Default is 512 bytes.") + .defaultValue(512) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(3) + .build(); + + protected static final String WRITE_BUFFER_SIZE = "writeBufferSizeBytes"; + protected static final ConfigKey WRITE_BUFFER_SIZE_KEY = ConfigKey.builder(WRITE_BUFFER_SIZE) + .type(Type.INT) + .description("The number of bytes used as capacity for the write buffer. Default is 64KB.") + .defaultValue(64 * 1024) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(4) + .build(); + + protected static final String ENTRY_LOG_PER_LEDGER_ENABLED = "entryLogPerLedgerEnabled"; + protected static final String NUMBER_OF_MEMTABLE_FLUSH_THREADS = "numOfMemtableFlushThreads"; + protected static final String ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS = "entrylogMapAccessExpiryTimeInSeconds"; + protected static final String MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS = "maximumNumberOfActiveEntryLogs"; + protected static final String ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR = + "entryLogPerLedgerCounterLimitsMultFactor"; + + protected static final ConfigKey ENTRY_LOG_PER_LEDGER_ENABLED_KEY = ConfigKey.builder(ENTRY_LOG_PER_LEDGER_ENABLED) + .type(Type.BOOLEAN) + .description("Specifies if entryLog per ledger is enabled/disabled") + .documentation("If it is enabled, then there would be a active entrylog for each ledger." + + " It would be ideal to enable this feature if the underlying storage device has" + + " multiple DiskPartitions or SSD and if in a given moment, entries of fewer number" + + " of active ledgers are written to a bookie.") + .defaultValue(false) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(5) + .dependents(Lists.newArrayList( + NUMBER_OF_MEMTABLE_FLUSH_THREADS, + ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS, + MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS + )) + .build(); + + protected static final ConfigKey NUMBER_OF_MEMTABLE_FLUSH_THREADS_KEY = + ConfigKey.builder(NUMBER_OF_MEMTABLE_FLUSH_THREADS) + .type(Type.INT) + .description("In the case of multipleentrylogs, multiple threads can be used to flush the memtable") + .defaultValue(8) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(6) + .build(); + + protected static final ConfigKey ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS_KEY = + ConfigKey.builder(ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS) + .type(Type.INT) + .description("The amount of time EntryLogManagerForEntryLogPerLedger should wait for closing" + + " the entrylog file after the last addEntry call for that ledger, if explicit writeclose" + + " for that ledger is not received") + .defaultValue(300) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(7) + .build(); + + protected static final ConfigKey MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS_KEY = + ConfigKey.builder(MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS) + .type(Type.INT) + .description("In entryLogPerLedger feature, this specifies the maximum number of entrylogs that" + + " can be active at a given point in time") + .documentation("If there are more number of active entryLogs then the `" + + MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS + "` then the entrylog will be evicted from the cache.") + .defaultValue(500) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(8) + .build(); + + protected static final ConfigKey ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR_KEY = + ConfigKey.builder(ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR) + .type(Type.INT) + .description("In entryLogPerLedger feature, this config value specifies the metrics cache size" + + " limits in multiples of entrylogMap cache size limits") + .defaultValue(10) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) + .orderInGroup(9) + .build(); + + // // Ledger Storage Settings + // private static final ConfigKeyGroup GROUP_LEDGER_STORAGE = ConfigKeyGroup.builder("ledgerstorage") .description("Ledger Storage related settings") - .order(10) // place a place holder here + .order(190) // place a place holder here .build(); protected static final String LEDGER_STORAGE_CLASS = "ledgerStorageClass"; @@ -66,219 +962,708 @@ public class ServerConfiguration extends AbstractConfiguration 1.2 * ENTRY_LOG_SIZE_LIMIT_KEY.getLong(conf)) + .group(GROUP_LEDGER_STORAGE) + .orderInGroup(5) + .build(); + protected static final String MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES = "minUsableSizeForHighPriorityWrites"; + protected static final ConfigKey MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES_KEY = + ConfigKey.builder(MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES) + .type(Type.LONG) + .description("Minimum safe usable size to be available in ledger directory for bookie to accept" + + " high priority writes even it is in readonly mode.") + .documentation("If not set, it is the value of `" + MIN_USABLESIZE_FOR_ENTRYLOG_CREATION + "`") + .validator(RangeValidator.atLeast(0L)) + .defaultValueSupplier(conf -> MIN_USABLESIZE_FOR_ENTRYLOG_CREATION_KEY.getLong(conf)) + .group(GROUP_LEDGER_STORAGE) + .orderInGroup(6) + .build(); + + protected static final String FLUSH_INTERVAL = "flushInterval"; + protected static final ConfigKey FLUSH_INTERVAL_KEY = ConfigKey.builder(FLUSH_INTERVAL) + .type(Type.INT) + .description("Interval that a bookie flushes ledger storage to disk, in milliseconds") + .documentation("When `entryLogPerLedgerEnabled` is enabled, checkpoint doesn't happen" + + " when a new active entrylog is created / previous one is rolled over." + + " Instead SyncThread checkpoints periodically with 'flushInterval' delay" + + " (in milliseconds) in between executions. Checkpoint flushes both ledger" + + " entryLogs and ledger index pages to disk. \n" + + "Flushing entrylog and index files will introduce much random disk I/O." + + " If separating journal dir and ledger dirs each on different devices," + + " flushing would not affect performance. But if putting journal dir" + + " and ledger dirs on same device, performance degrade significantly" + + " on too frequent flushing. You can consider increment flush interval" + + " to get better performance, but you need to pay more time on bookie" + + " server restart after failure.\n" + + "This config is used only when entryLogPerLedgerEnabled is enabled or" + + " `DbLedgerStorage` is used.") + .defaultValue(10000) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_LEDGER_STORAGE) + .orderInGroup(7) + .build(); + + protected static final String ALLOW_STORAGE_EXPANSION = "allowStorageExpansion"; + protected static final ConfigKey ALLOW_STORAGE_EXPANSION_KEY = ConfigKey.builder(ALLOW_STORAGE_EXPANSION) + .type(Type.BOOLEAN) + .description("Allow the expansion of bookie storage capacity") + .documentation("Newly added ledger and index dirs must be empty") + .defaultValue(false) + .group(GROUP_LEDGER_STORAGE) + .orderInGroup(8) + .build(); + + // + // Entry Logger Compaction Settings + // + + private static final ConfigKeyGroup GROUP_ENTRY_LOGGER_COMPACTION = ConfigKeyGroup.builder("compaction") + .description("Entry log compaction related settings") + .order(200) + .build(); + + protected static final String COMPACTION_RATE = "compactionRate"; + protected static final String COMPACTION_RATE_BY_ENTRIES = "compactionRateByEntries"; + protected static final String COMPACTION_RATE_BY_BYTES = "compactionRateByBytes"; + + protected static final ConfigKey COMPACTION_RATE_KEY = ConfigKey.builder(COMPACTION_RATE) + .type(Type.INT) + .description("Set the rate at which compaction will readd entries. The unit is adds per second.") + .defaultValue(1000) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(0) + .deprecated(true) + .deprecatedByConfigKey(COMPACTION_RATE_BY_ENTRIES) + .build(); + protected static final ConfigKey COMPACTION_RATE_BY_ENTRIES_KEY = ConfigKey.builder(COMPACTION_RATE_BY_ENTRIES) + .type(Type.INT) + .description("Set the rate at which compaction will readd entries. The unit is adds per second.") + .defaultValueSupplier(conf -> COMPACTION_RATE_KEY.getInt(conf)) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(1) + .build(); + protected static final ConfigKey COMPACTION_RATE_BY_BYTES_KEY = ConfigKey.builder(COMPACTION_RATE_BY_BYTES) + .type(Type.INT) + .description("Set the rate at which compaction will readd entries. The unit is bytes per second.") + .defaultValue(1000000) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(2) + .build(); + + protected static final String IS_THROTTLE_BY_BYTES = "isThrottleByBytes"; + protected static final ConfigKey IS_THROTTLE_BY_BYTES_KEY = ConfigKey.builder(IS_THROTTLE_BY_BYTES) + .type(Type.BOOLEAN) + .description("Throttle compaction by bytes or by entries.") + .defaultValue(false) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(3) + .build(); + + protected static final String COMPACTION_MAX_OUTSTANDING_REQUESTS = "compactionMaxOutstandingRequests"; + protected static final ConfigKey COMPACTION_MAX_OUTSTANDING_REQUESTS_KEY = + ConfigKey.builder(COMPACTION_MAX_OUTSTANDING_REQUESTS) + .type(Type.INT) + .description("Set the maximum number of entries which can be compacted without flushing") + .documentation("When compacting, the entries are written to the entrylog and the new offsets" + + " are cached in memory. Once the entrylog is flushed the index is updated with the new" + + " offsets. This parameter controls the number of entries added to the entrylog before" + + " a flush is forced. A higher value for this parameter means more memory will be used" + + " for offsets. Each offset consists of 3 longs. This parameter should _not_ be modified" + + " unless you know what you're doing.") + .defaultValue(100000) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(4) + .build(); + + protected static final String USE_TRANSACTIONAL_COMPACTION = "useTransactionalCompaction"; + protected static final ConfigKey USE_TRANSACTIONAL_COMPACTION_KEY = ConfigKey.builder(USE_TRANSACTIONAL_COMPACTION) + .type(Type.BOOLEAN) + .description("Flag to enable/disable transactional compaction") + .documentation("If it is set to true, it will use transactional compaction, which it will" + + " use new entry log files to store compacted entries during compaction; if it is set" + + " to false, it will use normal compaction, which it shares same entry log file with" + + " normal add operations") + .defaultValue(false) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(5) + .build(); protected static final String MINOR_COMPACTION_INTERVAL = "minorCompactionInterval"; + protected static final ConfigKey MINOR_COMPACTION_INTERVAL_KEY = ConfigKey.builder(MINOR_COMPACTION_INTERVAL) + .type(Type.LONG) + .description("Interval to run minor compaction, in seconds") + .documentation("If it is set to less than zero, the minor compaction is disabled") + .defaultValue(3600) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(6) + .build(); + protected static final String MINOR_COMPACTION_THRESHOLD = "minorCompactionThreshold"; + protected static final ConfigKey MINOR_COMPACTION_THRESHOLD_KEY = ConfigKey.builder(MINOR_COMPACTION_THRESHOLD) + .type(Type.DOUBLE) + .description("Threshold of minor compaction") + .documentation("For those entry log files whose remaining size percentage reaches below" + + " this threshold will be compacted in a minor compaction. If it is set to less than zero," + + " the minor compaction is disabled.") + .defaultValue(0.2f) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(7) + .build(); + protected static final String MAJOR_COMPACTION_INTERVAL = "majorCompactionInterval"; + protected static final ConfigKey MAJOR_COMPACTION_INTERVAL_KEY = ConfigKey.builder(MAJOR_COMPACTION_INTERVAL) + .type(Type.LONG) + .description("Interval to run major compaction, in seconds") + .documentation("If it is set to less than zero, the major compaction is disabled") + .defaultValue(86400) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(8) + .build(); + protected static final String MAJOR_COMPACTION_THRESHOLD = "majorCompactionThreshold"; - protected static final String IS_THROTTLE_BY_BYTES = "isThrottleByBytes"; - protected static final String COMPACTION_MAX_OUTSTANDING_REQUESTS = "compactionMaxOutstandingRequests"; - protected static final String COMPACTION_RATE = "compactionRate"; - protected static final String COMPACTION_RATE_BY_ENTRIES = "compactionRateByEntries"; - protected static final String COMPACTION_RATE_BY_BYTES = "compactionRateByBytes"; + protected static final ConfigKey MAJOR_COMPACTION_THRESHOLD_KEY = ConfigKey.builder(MAJOR_COMPACTION_THRESHOLD) + .type(Type.DOUBLE) + .description("Threshold of major compaction") + .documentation("For those entry log files whose remaining size percentage reaches below" + + " this threshold will be compacted in a major compaction." + + " Those entry log files whose remaining size percentage is still" + + " higher than the threshold will never be compacted." + + " If it is set to less than zero, the major compaction is disabled.") + .defaultValue(0.8f) + .group(GROUP_ENTRY_LOGGER_COMPACTION) + .orderInGroup(9) + .build(); + + // + // Garbage Collection Settings + // + + private static final ConfigKeyGroup GROUP_GC = ConfigKeyGroup.builder("gc") + .description("Garbage collection related settings") + .order(210) + .build(); - // Gc Parameters protected static final String GC_WAIT_TIME = "gcWaitTime"; - protected static final String IS_FORCE_GC_ALLOW_WHEN_NO_SPACE = "isForceGCAllowWhenNoSpace"; + protected static final ConfigKey GC_WAIT_TIME_KEY = ConfigKey.builder(GC_WAIT_TIME) + .type(Type.LONG) + .description("How long the interval to trigger next garbage collection, in milliseconds") + .documentation("Since garbage collection is running in background, too frequent gc will" + + " heart performance. It is better to give a higher number of gc interval if" + + " there is enough disk capacity.") + .defaultValue(600000) + .group(GROUP_GC) + .orderInGroup(0) + .build(); + protected static final String GC_OVERREPLICATED_LEDGER_WAIT_TIME = "gcOverreplicatedLedgerWaitTime"; - protected static final String USE_TRANSACTIONAL_COMPACTION = "useTransactionalCompaction"; + protected static final ConfigKey GC_OVERREPLICATED_LEDGER_WAIT_TIME_KEY = + ConfigKey.builder(GC_OVERREPLICATED_LEDGER_WAIT_TIME) + .type(Type.LONG) + .description("How long the interval to trigger next garbage collection of overreplicated" + + " ledgers, in milliseconds") + .documentation("This should not be run very frequently since we read the metadata for all" + + " the ledgers on the bookie from zk") + .defaultValue(TimeUnit.DAYS.toMillis(1)) + .group(GROUP_GC) + .orderInGroup(1) + .build(); + + protected static final String IS_FORCE_GC_ALLOW_WHEN_NO_SPACE = "isForceGCAllowWhenNoSpace"; + protected static final ConfigKey IS_FORCE_GC_ALLOW_WHEN_NO_SPACE_KEY = + ConfigKey.builder(IS_FORCE_GC_ALLOW_WHEN_NO_SPACE) + .type(Type.BOOLEAN) + .description("Whether force compaction is allowed when the disk is full or almost full") + .documentation("Forcing GC may get some space back, but may also fill up disk space more" + + " quickly. This is because new log files are created before GC, while old garbage" + + " log files are deleted after GC.") + .defaultValue(false) + .group(GROUP_GC) + .orderInGroup(2) + .build(); + protected static final String VERIFY_METADATA_ON_GC = "verifyMetadataOnGC"; - // Scrub Parameters - protected static final String LOCAL_SCRUB_PERIOD = "localScrubInterval"; - protected static final String LOCAL_SCRUB_RATE_LIMIT = "localScrubRateLimit"; - // Sync Parameters - protected static final String FLUSH_INTERVAL = "flushInterval"; - protected static final String FLUSH_ENTRYLOG_INTERVAL_BYTES = "flushEntrylogBytes"; - // Bookie death watch interval - protected static final String DEATH_WATCH_INTERVAL = "bookieDeathWatchInterval"; - // Ledger Cache Parameters - protected static final String OPEN_FILE_LIMIT = "openFileLimit"; - protected static final String PAGE_LIMIT = "pageLimit"; - protected static final String PAGE_SIZE = "pageSize"; - protected static final String FILEINFO_CACHE_INITIAL_CAPACITY = "fileInfoCacheInitialCapacity"; - protected static final String FILEINFO_MAX_IDLE_TIME = "fileInfoMaxIdleTime"; - protected static final String FILEINFO_FORMAT_VERSION_TO_WRITE = "fileInfoFormatVersionToWrite"; - // Journal Parameters - protected static final String MAX_JOURNAL_SIZE = "journalMaxSizeMB"; - protected static final String MAX_BACKUP_JOURNALS = "journalMaxBackups"; - protected static final String JOURNAL_SYNC_DATA = "journalSyncData"; - protected static final String JOURNAL_ADAPTIVE_GROUP_WRITES = "journalAdaptiveGroupWrites"; - protected static final String JOURNAL_MAX_GROUP_WAIT_MSEC = "journalMaxGroupWaitMSec"; - protected static final String JOURNAL_BUFFERED_WRITES_THRESHOLD = "journalBufferedWritesThreshold"; - protected static final String JOURNAL_BUFFERED_ENTRIES_THRESHOLD = "journalBufferedEntriesThreshold"; - protected static final String JOURNAL_FLUSH_WHEN_QUEUE_EMPTY = "journalFlushWhenQueueEmpty"; - protected static final String JOURNAL_REMOVE_FROM_PAGE_CACHE = "journalRemoveFromPageCache"; - protected static final String JOURNAL_PRE_ALLOC_SIZE = "journalPreAllocSizeMB"; - protected static final String JOURNAL_WRITE_BUFFER_SIZE = "journalWriteBufferSizeKB"; - protected static final String JOURNAL_ALIGNMENT_SIZE = "journalAlignmentSize"; - protected static final String NUM_JOURNAL_CALLBACK_THREADS = "numJournalCallbackThreads"; - protected static final String JOURNAL_FORMAT_VERSION_TO_WRITE = "journalFormatVersionToWrite"; - // backpressure control - protected static final String MAX_ADDS_IN_PROGRESS_LIMIT = "maxAddsInProgressLimit"; - protected static final String MAX_READS_IN_PROGRESS_LIMIT = "maxReadsInProgressLimit"; - protected static final String CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT = "closeChannelOnResponseTimeout"; - protected static final String WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE = "waitTimeoutOnResponseBackpressureMs"; + protected static final ConfigKey VERIFY_METADATA_ON_GC_KEY = ConfigKey.builder(VERIFY_METADATA_ON_GC) + .type(Type.BOOLEAN) + .description("True if the bookie should double check readMetadata prior to gc") + .defaultValue(false) + .group(GROUP_GC) + .orderInGroup(3) + .build(); - // Bookie Parameters - protected static final String BOOKIE_PORT = "bookiePort"; - protected static final String LISTENING_INTERFACE = "listeningInterface"; - protected static final String ALLOW_LOOPBACK = "allowLoopback"; - protected static final String ADVERTISED_ADDRESS = "advertisedAddress"; - protected static final String ALLOW_EPHEMERAL_PORTS = "allowEphemeralPorts"; + // + // Disk Utilization Settings + // - protected static final String JOURNAL_DIR = "journalDirectory"; - protected static final String JOURNAL_DIRS = "journalDirectories"; - protected static final String LEDGER_DIRS = "ledgerDirectories"; - protected static final String INDEX_DIRS = "indexDirectories"; - protected static final String ALLOW_STORAGE_EXPANSION = "allowStorageExpansion"; - // NIO and Netty Parameters - protected static final String SERVER_TCP_NODELAY = "serverTcpNoDelay"; - protected static final String SERVER_SOCK_KEEPALIVE = "serverSockKeepalive"; - protected static final String SERVER_SOCK_LINGER = "serverTcpLinger"; - protected static final String SERVER_WRITEBUFFER_LOW_WATER_MARK = "serverWriteBufferLowWaterMark"; - protected static final String SERVER_WRITEBUFFER_HIGH_WATER_MARK = "serverWriteBufferHighWaterMark"; - protected static final String SERVER_NUM_IO_THREADS = "serverNumIOThreads"; + private static final ConfigKeyGroup GROUP_DISK = ConfigKeyGroup.builder("disk") + .description("Disk related settings") + .order(220) + .build(); - // Zookeeper Parameters - protected static final String ZK_RETRY_BACKOFF_START_MS = "zkRetryBackoffStartMs"; - protected static final String ZK_RETRY_BACKOFF_MAX_MS = "zkRetryBackoffMaxMs"; - protected static final String OPEN_LEDGER_REREPLICATION_GRACE_PERIOD = "openLedgerRereplicationGracePeriod"; - protected static final String LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD = "lockReleaseOfFailedLedgerGracePeriod"; - //ReadOnly mode support on all disk full - protected static final String READ_ONLY_MODE_ENABLED = "readOnlyModeEnabled"; - //Whether the bookie is force started in ReadOnly mode - protected static final String FORCE_READ_ONLY_BOOKIE = "forceReadOnlyBookie"; - //Whether to persist the bookie status - protected static final String PERSIST_BOOKIE_STATUS_ENABLED = "persistBookieStatusEnabled"; - //Disk utilization protected static final String DISK_USAGE_THRESHOLD = "diskUsageThreshold"; + protected static final ConfigKey DISK_USAGE_THRESHOLD_KEY = ConfigKey.builder(DISK_USAGE_THRESHOLD) + .type(Type.FLOAT) + .description("For each ledger dir, maximum disk space which can be used") + .documentation("Default is 0.95f. i.e. 95% of disk can be used at most after which nothing will" + + " be written to that partition. If all ledger dir partions are full, then bookie will turn" + + " to readonly mode if 'readOnlyModeEnabled=true' is set, else it will shutdown.") + .defaultValue(0.95f) + .validator(RangeValidator.between(0f, 1f)) + .group(GROUP_DISK) + .orderInGroup(0) + .build(); + protected static final String DISK_USAGE_WARN_THRESHOLD = "diskUsageWarnThreshold"; + protected static final ConfigKey DISK_USAGE_WARN_THRESHOLD_KEY = ConfigKey.builder(DISK_USAGE_WARN_THRESHOLD) + .type(Type.FLOAT) + .description("The disk free space warn threshold") + .documentation("Disk is considered full when usage threshold is exceeded." + + " Disk returns back to non-full state when usage is below low water mark threshold." + + " This prevents it from going back and forth between these states frequently when" + + " concurrent writes and compaction are happening. This also prevent bookie from" + + " switching frequently between read-only and read-writes states in the same cases.") + .defaultValue(0.95f) + .validator(RangeValidator.between(0f, 1f)) + .group(GROUP_DISK) + .orderInGroup(1) + .build(); + protected static final String DISK_USAGE_LWM_THRESHOLD = "diskUsageLwmThreshold"; + protected static final ConfigKey DISK_USAGE_LWM_THRESHOLD_KEY = ConfigKey.builder(DISK_USAGE_LWM_THRESHOLD) + .type(Type.FLOAT) + .description("The disk free space low water mark threshold") + .documentation("Disk is considered full when usage threshold is exceeded." + + " Disk returns back to non-full state when usage is below low water" + + " mark threshold. This prevents it from going back and forth between" + + " these states frequently when concurrent writes and compaction are " + + " happening. This also prevent bookie from switching frequently between" + + " read-only and read-writes states in the same cases.") + .defaultValueSupplier((conf) -> DISK_USAGE_THRESHOLD_KEY.getFloat(conf)) + .validator(RangeValidator.between(0f, 1f)) + .group(GROUP_DISK) + .orderInGroup(2) + .build(); + protected static final String DISK_CHECK_INTERVAL = "diskCheckInterval"; + protected static final ConfigKey DISK_CHECK_INTERVAL_KEY = ConfigKey.builder(DISK_CHECK_INTERVAL) + .type(Type.INT) + .description("Disk check interval in milli seconds") + .documentation("Interval to check the ledger dirs usage. Default is 10000") + .defaultValue(TimeUnit.SECONDS.toMillis(10)) + .validator(RangeValidator.atLeast(0)) + .group(GROUP_DISK) + .orderInGroup(3) + .build(); - // Replication parameters - protected static final String AUDITOR_PERIODIC_CHECK_INTERVAL = "auditorPeriodicCheckInterval"; - protected static final String AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL = "auditorPeriodicBookieCheckInterval"; - protected static final String AUDITOR_LEDGER_VERIFICATION_PERCENTAGE = "auditorLedgerVerificationPercentage"; - protected static final String AUTO_RECOVERY_DAEMON_ENABLED = "autoRecoveryDaemonEnabled"; - protected static final String LOST_BOOKIE_RECOVERY_DELAY = "lostBookieRecoveryDelay"; - protected static final String RW_REREPLICATE_BACKOFF_MS = "rwRereplicateBackoffMs"; + // + // Disk Scrub Settings + // - // Worker Thread parameters. - protected static final String NUM_ADD_WORKER_THREADS = "numAddWorkerThreads"; - protected static final String NUM_READ_WORKER_THREADS = "numReadWorkerThreads"; - protected static final String MAX_PENDING_READ_REQUESTS_PER_THREAD = "maxPendingReadRequestsPerThread"; - protected static final String MAX_PENDING_ADD_REQUESTS_PER_THREAD = "maxPendingAddRequestsPerThread"; - protected static final String NUM_LONG_POLL_WORKER_THREADS = "numLongPollWorkerThreads"; - protected static final String NUM_HIGH_PRIORITY_WORKER_THREADS = "numHighPriorityWorkerThreads"; + private static final ConfigKeyGroup GROUP_SCRUB = ConfigKeyGroup.builder("scrub") + .description("Local Scrub related settings") + .order(230) + .build(); - // Long poll parameters - protected static final String REQUEST_TIMER_TICK_DURATION_MILLISEC = "requestTimerTickDurationMs"; - protected static final String REQUEST_TIMER_NO_OF_TICKS = "requestTimerNumTicks"; + protected static final String LOCAL_SCRUB_PERIOD = "localScrubInterval"; + protected static final ConfigKey LOCAL_SCRUB_PERIOD_KEY = ConfigKey.builder(LOCAL_SCRUB_PERIOD) + .type(Type.LONG) + .description("Set local scrub period in seconds (<= 0 for disabled)") + .documentation("Scrub will be scheduled at delays chosen from the interval (.5 * interval, 1.5 * interval)") + .defaultValue(0) + .group(GROUP_SCRUB) + .orderInGroup(0) + .build(); - protected static final String READ_BUFFER_SIZE = "readBufferSizeBytes"; - protected static final String WRITE_BUFFER_SIZE = "writeBufferSizeBytes"; - // Whether the bookie should use its hostname or ipaddress for the - // registration. - protected static final String USE_HOST_NAME_AS_BOOKIE_ID = "useHostNameAsBookieID"; - protected static final String USE_SHORT_HOST_NAME = "useShortHostName"; - protected static final String ENABLE_LOCAL_TRANSPORT = "enableLocalTransport"; - protected static final String DISABLE_SERVER_SOCKET_BIND = "disableServerSocketBind"; + protected static final String LOCAL_SCRUB_RATE_LIMIT = "localScrubRateLimit"; + protected static final ConfigKey LOCAL_SCRUB_RATE_LIMIT_KEY = ConfigKey.builder(LOCAL_SCRUB_RATE_LIMIT) + .type(Type.DOUBLE) + .description("local scrub rate limit (entries/second)") + .defaultValue(60) + .group(GROUP_SCRUB) + .orderInGroup(1) + .build(); + + protected static final String LOCAL_CONSISTENCY_CHECK_ON_STARTUP = "localConsistencyCheckOnStartup"; + protected static final ConfigKey LOCAL_CONSISTENCY_CHECK_ON_STARTUP_KEY = + ConfigKey.builder(LOCAL_CONSISTENCY_CHECK_ON_STARTUP) + .type(Type.BOOLEAN) + .description("True if a local consistency check should be performed on startup.") + .defaultValue(false) + .group(GROUP_SCRUB) + .orderInGroup(2) + .build(); + + // + // Sorted Ledger Storage Settings + // + + private static final ConfigKeyGroup GROUP_SORTED_LEDGER_STORAGE = ConfigKeyGroup.builder("sortedledgerstorage") + .description("SortedLedgerStorage related settings") + .order(240) + .build(); - protected static final String SORTED_LEDGER_STORAGE_ENABLED = "sortedLedgerStorageEnabled"; protected static final String SKIP_LIST_SIZE_LIMIT = "skipListSizeLimit"; + protected static final ConfigKey SKIP_LIST_SIZE_LIMIT_KEY = ConfigKey.builder(SKIP_LIST_SIZE_LIMIT) + .type(Type.LONG) + .description("The skip list data size limitation in EntryMemTable") + .defaultValue(64 * 1024 * 1024L) + .validator(RangeValidator.between(0, (Integer.MAX_VALUE - 1) / 2)) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(100) + .build(); + protected static final String SKIP_LIST_CHUNK_SIZE_ENTRY = "skipListArenaChunkSize"; + protected static final ConfigKey SKIP_LIST_CHUNK_SIZE_ENTRY_KEY = ConfigKey.builder(SKIP_LIST_CHUNK_SIZE_ENTRY) + .type(Type.INT) + .description("The number of bytes we should use as chunk allocation for" + + " org.apache.bookkeeper.bookie.SkipListArena") + .defaultValue(4096 * 1024) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(101) + .build(); + protected static final String SKIP_LIST_MAX_ALLOC_ENTRY = "skipListArenaMaxAllocSize"; + protected static final ConfigKey SKIP_LIST_MAX_ALLOC_ENTRY_KEY = ConfigKey.builder(SKIP_LIST_MAX_ALLOC_ENTRY) + .type(Type.INT) + .description("The max size we should allocate from the skiplist arena") + .documentation("Allocations larger than this should be allocated directly by the VM to avoid fragmentation.") + .defaultValue(128 * 1024) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(102) + .build(); - // Statistics Parameters - protected static final String ENABLE_STATISTICS = "enableStatistics"; - protected static final String STATS_PROVIDER_CLASS = "statsProviderClass"; + protected static final String OPEN_FILE_LIMIT = "openFileLimit"; + protected static final ConfigKey OPEN_FILE_LIMIT_KEY = ConfigKey.builder(OPEN_FILE_LIMIT) + .type(Type.INT) + .description("Max number of ledger index files could be opened in bookie server") + .documentation("If number of ledger index files reaches this limitation, bookie" + + " server started to swap some ledgers from memory to disk. Too frequent swap" + + " will affect performance. You can tune this number to gain performance according your requirements.") + .defaultValue(20000) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(103) + .build(); + protected static final String FILEINFO_CACHE_INITIAL_CAPACITY = "fileInfoCacheInitialCapacity"; + protected static final ConfigKey FILEINFO_CACHE_INITIAL_CAPACITY_KEY = + ConfigKey.builder(FILEINFO_CACHE_INITIAL_CAPACITY) + .type(Type.INT) + .description("The minimum total size of the internal file info cache table") + .documentation("Providing a large enough estimate at construction time avoids the need" + + " for expensive resizing operations later, but setting this value unnecessarily" + + " high wastes memory. The default value is `1/4` of # `" + OPEN_FILE_LIMIT + "`" + + " if " + OPEN_FILE_LIMIT + " is positive, otherwise it is 64.") + .defaultValueSupplier(conf -> Math.max(OPEN_FILE_LIMIT_KEY.getInt(conf) / 4, 64)) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(104) + .build(); - // Rx adaptive ByteBuf allocator parameters - protected static final String BYTEBUF_ALLOCATOR_SIZE_INITIAL = "byteBufAllocatorSizeInitial"; - protected static final String BYTEBUF_ALLOCATOR_SIZE_MIN = "byteBufAllocatorSizeMin"; - protected static final String BYTEBUF_ALLOCATOR_SIZE_MAX = "byteBufAllocatorSizeMax"; + protected static final String FILEINFO_MAX_IDLE_TIME = "fileInfoMaxIdleTime"; + protected static final ConfigKey FILEINFO_MAX_IDLE_TIME_KEY = ConfigKey.builder(FILEINFO_MAX_IDLE_TIME) + .type(Type.LONG) + .description("The max idle time allowed for an open file info existed in the file info cache") + .documentation("If the file info is idle for a long time, exceed the given time period. The file info" + + " will be evicted and closed. If the value is zero or negative, the file info is evicted" + + " only when opened files reached openFileLimit.") + .defaultValue(0) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(105) + .build(); - // Bookie auth provider factory class name - protected static final String BOOKIE_AUTH_PROVIDER_FACTORY_CLASS = "bookieAuthProviderFactoryClass"; + protected static final String FILEINFO_FORMAT_VERSION_TO_WRITE = "fileInfoFormatVersionToWrite"; + protected static final ConfigKey FILEINFO_FORMAT_VERSION_TO_WRITE_KEY = + ConfigKey.builder(FILEINFO_FORMAT_VERSION_TO_WRITE) + .type(Type.INT) + .description("The fileinfo format version to write") + .documentation("If you'd like to disable persisting ExplicitLac, you can set this config to 0 and" + + " also journalFormatVersionToWrite should be set to < 6. If there is mismatch then the" + + " server config is considered invalid") + .optionValues(Lists.newArrayList( + "0: Initial version", + "1: persisting explicitLac is introduced" + )) + .defaultValue(1) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(106) + .build(); - protected static final String MIN_USABLESIZE_FOR_INDEXFILE_CREATION = "minUsableSizeForIndexFileCreation"; - protected static final String MIN_USABLESIZE_FOR_ENTRYLOG_CREATION = "minUsableSizeForEntryLogCreation"; - protected static final String MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES = "minUsableSizeForHighPriorityWrites"; + protected static final String PAGE_SIZE = "pageSize"; + protected static final ConfigKey PAGE_SIZE_KEY = ConfigKey.builder(PAGE_SIZE) + .type(Type.INT) + .description("Size of a index page in ledger cache, in bytes") + .documentation("A larger index page can improve performance writing page to disk, which is efficent" + + " when you have small number of ledgers and these ledgers have similar number of entries. If" + + " you have large number of ledgers and each ledger has fewer entries, smaller index page would" + + " improve memory usage.") + .defaultValue(8192) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(107) + .build(); - protected static final String ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION = - "allowMultipleDirsUnderSameDiskPartition"; + protected static final String PAGE_LIMIT = "pageLimit"; + protected static final ConfigKey PAGE_LIMIT_KEY = ConfigKey.builder(PAGE_LIMIT) + .type(Type.INT) + .description("How many index pages provided in ledger cache") + .documentation("If number of index pages reaches this limitation, bookie server starts to swap some ledgers" + + " from memory to disk. You can increment this value when you found swap became more frequent." + + " But make sure pageLimit*pageSize should not more than JVM max memory limitation, otherwise you would" + + " got OutOfMemoryException. In general, incrementing pageLimit, using smaller index page would gain" + + " bettern performance in lager number of ledgers with fewer entries case If pageLimit is -1, bookie" + + " server will use 1/3 of JVM memory to compute the limitation of number of index pages.") + .defaultValue(-1) + .group(GROUP_SORTED_LEDGER_STORAGE) + .orderInGroup(108) + .build(); - // Http Server parameters - protected static final String HTTP_SERVER_ENABLED = "httpServerEnabled"; - protected static final String HTTP_SERVER_PORT = "httpServerPort"; + // + // Db Ledger Storage Settings + // - // Lifecycle Components - protected static final String EXTRA_SERVER_COMPONENTS = "extraServerComponents"; - protected static final String IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES = - "ignoreExtraServerComponentsStartupFailures"; + private static final ConfigKeyGroup GROUP_DB_LEDGER_STORAGE = ConfigKeyGroup.builder("dbledgerstorage") + .description("DbLedgerStorage related settings") + .order(250) + .build(); - // Registration - protected static final String REGISTRATION_MANAGER_CLASS = "registrationManagerClass"; - // Stats + // + // ZK metadata service settings + // + + protected static final String ZK_RETRY_BACKOFF_START_MS = "zkRetryBackoffStartMs"; + protected static final ConfigKey ZK_RETRY_BACKOFF_START_MS_KEY = ConfigKey.builder(ZK_RETRY_BACKOFF_START_MS) + .type(Type.INT) + .description("The Zookeeper client backoff retry start time in millis") + .defaultValueSupplier(conf -> ZK_TIMEOUT_KEY.getInt(conf)) + .group(GROUP_ZK) + .orderInGroup(100) + .build(); + + protected static final String ZK_RETRY_BACKOFF_MAX_MS = "zkRetryBackoffMaxMs"; + protected static final ConfigKey ZK_RETRY_BACKOFF_MAX_MS_KEY = ConfigKey.builder(ZK_RETRY_BACKOFF_MAX_MS) + .type(Type.INT) + .description("The Zookeeper client backoff retry max time in millis") + .defaultValueSupplier(conf -> ZK_TIMEOUT_KEY.getInt(conf)) + .group(GROUP_ZK) + .orderInGroup(101) + .build(); + + // + // Statistics Settings + // + + private static final ConfigKeyGroup GROUP_STATS = ConfigKeyGroup.builder("stats") + .description("Stats related settings") + .order(260) + .children(Lists.newArrayList( + "org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider", + "org.apache.bookkeeper.stats.codahale.CodahaleMetricsProvider", + "org.apache.bookkeeper.stats.twitter.finagle.FinagleStatsProvider", + "org.apache.bookkeeper.stats.twitter.ostrich.OstrichProvider", + "org.apache.bookkeeper.stats.twitter.science.TwitterStatsProvider" + )) + .build(); + + protected static final String ENABLE_STATISTICS = "enableStatistics"; + protected static final ConfigKey ENABLE_STATISTICS_KEY = ConfigKey.builder(ENABLE_STATISTICS) + .type(Type.BOOLEAN) + .description("Turn on/off statistics") + .defaultValue(true) + .group(GROUP_STATS) + .orderInGroup(100) + .build(); + protected static final String ENABLE_TASK_EXECUTION_STATS = "enableTaskExecutionStats"; + protected static final ConfigKey ENABLE_TASK_EXECUTION_STATS_KEY = ConfigKey.builder(ENABLE_TASK_EXECUTION_STATS) + .type(Type.BOOLEAN) + .description("The flag to enable recording task execution stats") + .defaultValue(false) + .group(GROUP_STATS) + .orderInGroup(101) + .build(); - /* - * config specifying if the entrylog per ledger is enabled or not. - */ - protected static final String ENTRY_LOG_PER_LEDGER_ENABLED = "entryLogPerLedgerEnabled"; - // In the case of multipleentrylogs, multiple threads can be used to flush the memtable parallelly. - protected static final String NUMBER_OF_MEMTABLE_FLUSH_THREADS = "numOfMemtableFlushThreads"; + protected static final String STATS_PROVIDER_CLASS = "statsProviderClass"; + protected static final ConfigKey STATS_PROVIDER_CLASS_KEY = ConfigKey.builder(STATS_PROVIDER_CLASS) + .type(Type.CLASS) + .description("Stats Provider Class (if `" + ENABLE_STATISTICS + "` are enabled)") + .defaultValue(NullStatsProvider.class) + .optionValues(Lists.newArrayList( + "Prometheus : org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider", + "Codahale : org.apache.bookkeeper.stats.codahale.CodahaleMetricsProvider", + "Twitter Finagle : org.apache.bookkeeper.stats.twitter.finagle.FinagleStatsProvider", + "Twitter Ostrich : org.apache.bookkeeper.stats.twitter.ostrich.OstrichProvider", + "Twitter Science : org.apache.bookkeeper.stats.twitter.science.TwitterStatsProvider" + )) + .group(GROUP_STATS) + .orderInGroup(102) + .build(); + // + // Replication Worker Settings + // - /* - * config specifying if the entrylog per ledger is enabled, then the amount - * of time EntryLogManagerForEntryLogPerLedger should wait for closing the - * entrylog file after the last addEntry call for that ledger, if explicit - * writeclose for that ledger is not received. - */ - protected static final String ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS = "entrylogMapAccessExpiryTimeInSeconds"; + protected static final String OPEN_LEDGER_REREPLICATION_GRACE_PERIOD = "openLedgerRereplicationGracePeriod"; + protected static final ConfigKey OPEN_LEDGER_REREPLICATION_GRACE_PERIOD_KEY = + ConfigKey.builder(OPEN_LEDGER_REREPLICATION_GRACE_PERIOD) + .type(Type.INT) + .description("The grace period, in seconds, that the replication worker waits" + + " before fencing and replicating a ledger fragment that's still being" + + " written to upon bookie failure.") + .defaultValue(30) + .group(GROUP_REPLICATION_WORKER) + .orderInGroup(100) + .build(); - /* - * in entryLogPerLedger feature, this specifies the maximum number of - * entrylogs that can be active at a given point in time. If there are more - * number of active entryLogs then the maximumNumberOfActiveEntryLogs then - * the entrylog will be evicted from the cache. - */ - protected static final String MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS = "maximumNumberOfActiveEntryLogs"; + protected static final String RW_REREPLICATE_BACKOFF_MS = "rwRereplicateBackoffMs"; + protected static final ConfigKey RW_REREPLICATE_BACKOFF_MS_KEY = + ConfigKey.builder(RW_REREPLICATE_BACKOFF_MS) + .type(Type.INT) + .description("The time to backoff when replication worker encounters exceptions on" + + " replicating a ledger, in milliseconds") + .defaultValue(5000) + .group(GROUP_REPLICATION_WORKER) + .orderInGroup(101) + .build(); - /* - * in EntryLogManagerForEntryLogPerLedger, this config value specifies the - * metrics cache size limits in multiples of entrylogMap cache size limits. - */ - protected static final String ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR = - "entryLogPerLedgerCounterLimitsMultFactor"; + protected static final String LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD = "lockReleaseOfFailedLedgerGracePeriod"; + protected static final ConfigKey LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD_KEY = + ConfigKey.builder(LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD) + .type(Type.INT) + .description("The grace period, in milliseconds, if the replication worker fails to replicate" + + " a underreplicatedledger for more than `10` times, then instead of releasing the lock" + + " immediately after failed attempt, it will hold under replicated ledger lock for this" + + " grace period and then it will release the lock.") + .defaultValue(60000) + .group(GROUP_REPLICATION_WORKER) + .orderInGroup(102) + .build(); + + // + // Auditor Settings + // - // Perform local consistency check on bookie startup - protected static final String LOCAL_CONSISTENCY_CHECK_ON_STARTUP = "localConsistencyCheckOnStartup"; + protected static final String AUDITOR_PERIODIC_CHECK_INTERVAL = "auditorPeriodicCheckInterval"; + protected static final ConfigKey AUDITOR_PERIODIC_CHECK_INTERVAL_KEY = + ConfigKey.builder(AUDITOR_PERIODIC_CHECK_INTERVAL) + .type(Type.INT) + .description("The interval between auditor bookie checks, in seconds") + .documentation("The auditor bookie check, checks ledger metadata to see which bookies should" + + " contain entries for each ledger. If a bookie which should contain entries is " + + " unavailable, then the ledger containing that entry is marked for recovery." + + " Setting this to 0 disabled the periodic check. Bookie checks will still run when" + + " a bookie fails") + .defaultValue(604800) + .group(GROUP_AUDITOR) + .orderInGroup(100) + .build(); + + protected static final String AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL = "auditorPeriodicBookieCheckInterval"; + protected static final ConfigKey AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL_KEY = + ConfigKey.builder(AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL) + .type(Type.INT) + .description("Interval at which the auditor will do a check of all ledgers in the cluster, in seconds") + .documentation("To disable the periodic check completely, set this to 0. Note that periodic checking" + + " will put extra load on the cluster, so it should not be run more frequently than once a day.") + .defaultValue(86400) + .group(GROUP_AUDITOR) + .orderInGroup(101) + .build(); + + protected static final String AUDITOR_LEDGER_VERIFICATION_PERCENTAGE = "auditorLedgerVerificationPercentage"; + protected static final ConfigKey AUDITOR_LEDGER_VERIFICATION_PERCENTAGE_KEY = + ConfigKey.builder(AUDITOR_LEDGER_VERIFICATION_PERCENTAGE) + .type(Type.INT) + .description("The percentage of a ledger (fragment)'s entries will be verified before claiming this" + + " fragment as missing fragment") + .documentation("Default is 0, which only verify the first and last entries of a given fragment") + .defaultValue(0) + .group(GROUP_AUDITOR) + .orderInGroup(102) + .build(); + + protected static final String LOST_BOOKIE_RECOVERY_DELAY = "lostBookieRecoveryDelay"; + protected static final ConfigKey LOST_BOOKIE_RECOVERY_DELAY_KEY = ConfigKey.builder(LOST_BOOKIE_RECOVERY_DELAY) + .type(Type.INT) + .description("How long to wait, in seconds, before starting auto recovery of a lost bookie") + .defaultValue(0) + .group(GROUP_AUDITOR) + .orderInGroup(103) + .build(); + + // + // AutoRecovery Settings + // + + protected static final String AUTO_RECOVERY_DAEMON_ENABLED = "autoRecoveryDaemonEnabled"; + protected static final ConfigKey AUTO_RECOVERY_DAEMON_ENABLED_KEY = + ConfigKey.builder(AUTO_RECOVERY_DAEMON_ENABLED) + .type(Type.BOOLEAN) + .description("Whether the bookie itself can start auto-recovery service also or not") + .defaultValue(false) + .group(GROUP_AUTORECOVERY) + .orderInGroup(100) + .build(); /** * Construct a default configuration object. @@ -324,7 +1709,7 @@ public ServerConfiguration setEntryLogSizeLimit(long logSizeLimit) { * @return whether entry log file preallocation is enabled or not. */ public boolean isEntryLogFilePreAllocationEnabled() { - return this.getBoolean(ENTRY_LOG_FILE_PREALLOCATION_ENABLED, true); + return ENTRY_LOG_FILE_PREALLOCATION_ENABLED_KEY.getBoolean(this); } /** @@ -335,7 +1720,7 @@ public boolean isEntryLogFilePreAllocationEnabled() { * @return server configuration object. */ public ServerConfiguration setEntryLogFilePreAllocationEnabled(boolean enabled) { - this.setProperty(ENTRY_LOG_FILE_PREALLOCATION_ENABLED, enabled); + ENTRY_LOG_FILE_PREALLOCATION_ENABLED_KEY.set(this, enabled); return this; } @@ -348,7 +1733,7 @@ public ServerConfiguration setEntryLogFilePreAllocationEnabled(boolean enabled) * @return gc wait time */ public long getGcWaitTime() { - return this.getLong(GC_WAIT_TIME, 600000); + return GC_WAIT_TIME_KEY.getLong(this); } /** @@ -359,7 +1744,7 @@ public long getGcWaitTime() { * @return server configuration */ public ServerConfiguration setGcWaitTime(long gcWaitTime) { - this.setProperty(GC_WAIT_TIME, Long.toString(gcWaitTime)); + GC_WAIT_TIME_KEY.set(this, gcWaitTime); return this; } @@ -369,7 +1754,7 @@ public ServerConfiguration setGcWaitTime(long gcWaitTime) { * @return gc wait time */ public long getGcOverreplicatedLedgerWaitTimeMillis() { - return this.getLong(GC_OVERREPLICATED_LEDGER_WAIT_TIME, TimeUnit.DAYS.toMillis(1)); + return GC_OVERREPLICATED_LEDGER_WAIT_TIME_KEY.getLong(this); } /** @@ -386,7 +1771,7 @@ public long getGcOverreplicatedLedgerWaitTimeMillis() { * @return server configuration */ public ServerConfiguration setGcOverreplicatedLedgerWaitTime(long gcWaitTime, TimeUnit unit) { - this.setProperty(GC_OVERREPLICATED_LEDGER_WAIT_TIME, Long.toString(unit.toMillis(gcWaitTime))); + GC_OVERREPLICATED_LEDGER_WAIT_TIME_KEY.set(this, gcWaitTime); return this; } @@ -396,7 +1781,7 @@ public ServerConfiguration setGcOverreplicatedLedgerWaitTime(long gcWaitTime, Ti * @return use transactional compaction */ public boolean getUseTransactionalCompaction() { - return this.getBoolean(USE_TRANSACTIONAL_COMPACTION, false); + return USE_TRANSACTIONAL_COMPACTION_KEY.getBoolean(this); } /** @@ -405,7 +1790,7 @@ public boolean getUseTransactionalCompaction() { * @return server configuration */ public ServerConfiguration setUseTransactionalCompaction(boolean useTransactionalCompaction) { - this.setProperty(USE_TRANSACTIONAL_COMPACTION, useTransactionalCompaction); + USE_TRANSACTIONAL_COMPACTION_KEY.set(this, useTransactionalCompaction); return this; } @@ -415,7 +1800,7 @@ public ServerConfiguration setUseTransactionalCompaction(boolean useTransactiona * @return use transactional compaction */ public boolean getVerifyMetadataOnGC() { - return this.getBoolean(VERIFY_METADATA_ON_GC, false); + return VERIFY_METADATA_ON_GC_KEY.getBoolean(this); } /** @@ -424,7 +1809,7 @@ public boolean getVerifyMetadataOnGC() { * @return server configuration */ public ServerConfiguration setVerifyMetadataOnGc(boolean verifyMetadataOnGC) { - this.setProperty(VERIFY_METADATA_ON_GC, verifyMetadataOnGC); + VERIFY_METADATA_ON_GC_KEY.set(this, verifyMetadataOnGC); return this; } @@ -443,15 +1828,16 @@ public boolean isLocalScrubEnabled() { * @return Number of seconds between scrubs, <= 0 for disabled. */ public long getLocalScrubPeriod() { - return this.getLong(LOCAL_SCRUB_PERIOD, 0); + return LOCAL_SCRUB_PERIOD_KEY.getLong(this); } /** * Set local scrub period in seconds (<= 0 for disabled). Scrub will be scheduled at delays * chosen from the interval (.5 * interval, 1.5 * interval) */ - public void setLocalScrubPeriod(long period) { - this.setProperty(LOCAL_SCRUB_PERIOD, period); + public ServerConfiguration setLocalScrubPeriod(long period) { + LOCAL_SCRUB_PERIOD_KEY.set(this, period); + return this; } /** @@ -460,7 +1846,7 @@ public void setLocalScrubPeriod(long period) { * @return Max number of entries to scrub per second, 0 for disabled. */ public double getLocalScrubRateLimit() { - return this.getDouble(LOCAL_SCRUB_RATE_LIMIT, 60); + return LOCAL_SCRUB_RATE_LIMIT_KEY.getDouble(this); } /** @@ -468,8 +1854,9 @@ public double getLocalScrubRateLimit() { * * @param scrubRateLimit Max number of entries per second to scan. */ - public void setLocalScrubRateLimit(double scrubRateLimit) { - this.setProperty(LOCAL_SCRUB_RATE_LIMIT, scrubRateLimit); + public ServerConfiguration setLocalScrubRateLimit(double scrubRateLimit) { + LOCAL_SCRUB_RATE_LIMIT_KEY.set(this, scrubRateLimit); + return this; } /** @@ -480,7 +1867,7 @@ public void setLocalScrubRateLimit(double scrubRateLimit) { * @return flush interval */ public int getFlushInterval() { - return this.getInt(FLUSH_INTERVAL, 10000); + return FLUSH_INTERVAL_KEY.getInt(this); } /** @@ -491,7 +1878,7 @@ public int getFlushInterval() { * @return server configuration */ public ServerConfiguration setFlushInterval(int flushInterval) { - this.setProperty(FLUSH_INTERVAL, Integer.toString(flushInterval)); + FLUSH_INTERVAL_KEY.set(this, flushInterval); return this; } @@ -507,7 +1894,7 @@ public ServerConfiguration setFlushInterval(int flushInterval) { * @return Entry log flush interval in bytes */ public long getFlushIntervalInBytes() { - return this.getLong(FLUSH_ENTRYLOG_INTERVAL_BYTES, 0); + return FLUSH_ENTRYLOG_INTERVAL_BYTES_KEY.getLong(this); } /** @@ -517,18 +1904,17 @@ public long getFlushIntervalInBytes() { * @return server configuration */ public ServerConfiguration setFlushIntervalInBytes(long flushInterval) { - this.setProperty(FLUSH_ENTRYLOG_INTERVAL_BYTES, Long.toString(flushInterval)); + FLUSH_ENTRYLOG_INTERVAL_BYTES_KEY.set(this, flushInterval); return this; } - /** * Get bookie death watch interval. * * @return watch interval */ public int getDeathWatchInterval() { - return this.getInt(DEATH_WATCH_INTERVAL, 1000); + return DEATH_WATCH_INTERVAL_KEY.getInt(this); } /** @@ -537,7 +1923,7 @@ public int getDeathWatchInterval() { * @return max number of files to open */ public int getOpenFileLimit() { - return this.getInt(OPEN_FILE_LIMIT, 20000); + return OPEN_FILE_LIMIT_KEY.getInt(this); } /** @@ -548,7 +1934,7 @@ public int getOpenFileLimit() { * @return server configuration */ public ServerConfiguration setOpenFileLimit(int fileLimit) { - setProperty(OPEN_FILE_LIMIT, fileLimit); + OPEN_FILE_LIMIT_KEY.set(this, fileLimit); return this; } @@ -558,7 +1944,7 @@ public ServerConfiguration setOpenFileLimit(int fileLimit) { * @return max number of index pages in ledger cache */ public int getPageLimit() { - return this.getInt(PAGE_LIMIT, -1); + return PAGE_LIMIT_KEY.getInt(this); } /** @@ -569,7 +1955,7 @@ public int getPageLimit() { * @return server configuration */ public ServerConfiguration setPageLimit(int pageLimit) { - this.setProperty(PAGE_LIMIT, pageLimit); + PAGE_LIMIT_KEY.set(this, pageLimit); return this; } @@ -579,7 +1965,7 @@ public ServerConfiguration setPageLimit(int pageLimit) { * @return page size in ledger cache */ public int getPageSize() { - return this.getInt(PAGE_SIZE, 8192); + return PAGE_SIZE_KEY.getInt(this); } /** @@ -592,7 +1978,7 @@ public int getPageSize() { * @return Server Configuration */ public ServerConfiguration setPageSize(int pageSize) { - this.setProperty(PAGE_SIZE, pageSize); + PAGE_SIZE_KEY.set(this, pageSize); return this; } @@ -605,7 +1991,7 @@ public ServerConfiguration setPageSize(int pageSize) { * @return minimum size of initial file info cache. */ public int getFileInfoCacheInitialCapacity() { - return getInt(FILEINFO_CACHE_INITIAL_CAPACITY, Math.max(getOpenFileLimit() / 4, 64)); + return FILEINFO_CACHE_INITIAL_CAPACITY_KEY.getInt(this); } /** @@ -616,7 +2002,7 @@ public int getFileInfoCacheInitialCapacity() { * @return server configuration instance. */ public ServerConfiguration setFileInfoCacheInitialCapacity(int initialCapacity) { - setProperty(FILEINFO_CACHE_INITIAL_CAPACITY, initialCapacity); + FILEINFO_CACHE_INITIAL_CAPACITY_KEY.set(this, initialCapacity); return this; } @@ -630,7 +2016,7 @@ public ServerConfiguration setFileInfoCacheInitialCapacity(int initialCapacity) * @return max idle time of a file info in the file info cache. */ public long getFileInfoMaxIdleTime() { - return this.getLong(FILEINFO_MAX_IDLE_TIME, 0L); + return FILEINFO_MAX_IDLE_TIME_KEY.getLong(this); } /** @@ -642,7 +2028,7 @@ public long getFileInfoMaxIdleTime() { * @return server configuration object. */ public ServerConfiguration setFileInfoMaxIdleTime(long idleTime) { - setProperty(FILEINFO_MAX_IDLE_TIME, idleTime); + FILEINFO_MAX_IDLE_TIME_KEY.set(this, idleTime); return this; } @@ -652,7 +2038,7 @@ public ServerConfiguration setFileInfoMaxIdleTime(long idleTime) { * @return fileinfo format version to write. */ public int getFileInfoFormatVersionToWrite() { - return this.getInt(FILEINFO_FORMAT_VERSION_TO_WRITE, 1); + return FILEINFO_FORMAT_VERSION_TO_WRITE_KEY.getInt(this); } /** @@ -663,7 +2049,7 @@ public int getFileInfoFormatVersionToWrite() { * @return server configuration. */ public ServerConfiguration setFileInfoFormatVersionToWrite(int version) { - this.setProperty(FILEINFO_FORMAT_VERSION_TO_WRITE, version); + FILEINFO_FORMAT_VERSION_TO_WRITE_KEY.set(this, version); return this; } @@ -673,7 +2059,7 @@ public ServerConfiguration setFileInfoFormatVersionToWrite(int version) { * @return max journal file size */ public long getMaxJournalSizeMB() { - return this.getLong(MAX_JOURNAL_SIZE, 2 * 1024); + return MAX_JOURNAL_SIZE_KEY.getLong(this); } /** @@ -684,7 +2070,7 @@ public long getMaxJournalSizeMB() { * @return server configuration */ public ServerConfiguration setMaxJournalSizeMB(long maxJournalSize) { - this.setProperty(MAX_JOURNAL_SIZE, Long.toString(maxJournalSize)); + MAX_JOURNAL_SIZE_KEY.set(this, maxJournalSize); return this; } @@ -694,7 +2080,7 @@ public ServerConfiguration setMaxJournalSizeMB(long maxJournalSize) { * @return journal pre-allocation size in MB */ public int getJournalPreAllocSizeMB() { - return this.getInt(JOURNAL_PRE_ALLOC_SIZE, 16); + return JOURNAL_PRE_ALLOC_SIZE_KEY.getInt(this); } /** @@ -703,7 +2089,7 @@ public int getJournalPreAllocSizeMB() { * @return journal write buffer size in KB */ public int getJournalWriteBufferSizeKB() { - return this.getInt(JOURNAL_WRITE_BUFFER_SIZE, 64); + return JOURNAL_WRITE_BUFFER_SIZE_KEY.getInt(this); } /** @@ -712,7 +2098,7 @@ public int getJournalWriteBufferSizeKB() { * @return max number of older journal files to kept */ public int getMaxBackupJournals() { - return this.getInt(MAX_BACKUP_JOURNALS, 5); + return MAX_BACKUP_JOURNALS_KEY.getInt(this); } /** @@ -723,7 +2109,7 @@ public int getMaxBackupJournals() { * @return server configuration */ public ServerConfiguration setMaxBackupJournals(int maxBackupJournals) { - this.setProperty(MAX_BACKUP_JOURNALS, Integer.toString(maxBackupJournals)); + MAX_JOURNAL_SIZE_KEY.set(this, maxBackupJournals); return this; } @@ -734,7 +2120,7 @@ public ServerConfiguration setMaxBackupJournals(int maxBackupJournals) { * @return journal alignment size */ public int getJournalAlignmentSize() { - return this.getInt(JOURNAL_ALIGNMENT_SIZE, 512); + return JOURNAL_ALIGNMENT_SIZE_KEY.getInt(this); } /** @@ -745,7 +2131,7 @@ public int getJournalAlignmentSize() { * @return server configuration. */ public ServerConfiguration setJournalAlignmentSize(int size) { - this.setProperty(JOURNAL_ALIGNMENT_SIZE, size); + JOURNAL_ALIGNMENT_SIZE_KEY.set(this, size); return this; } @@ -755,7 +2141,7 @@ public ServerConfiguration setJournalAlignmentSize(int size) { * @return journal format version to write. */ public int getJournalFormatVersionToWrite() { - return this.getInt(JOURNAL_FORMAT_VERSION_TO_WRITE, 6); + return JOURNAL_FORMAT_VERSION_TO_WRITE_KEY.getInt(this); } /** @@ -766,7 +2152,7 @@ public int getJournalFormatVersionToWrite() { * @return server configuration. */ public ServerConfiguration setJournalFormatVersionToWrite(int version) { - this.setProperty(JOURNAL_FORMAT_VERSION_TO_WRITE, version); + JOURNAL_FORMAT_VERSION_TO_WRITE_KEY.set(this, version); return this; } @@ -776,7 +2162,7 @@ public ServerConfiguration setJournalFormatVersionToWrite(int version) { * @return Max number of adds in progress. */ public int getMaxAddsInProgressLimit() { - return this.getInt(MAX_ADDS_IN_PROGRESS_LIMIT, 0); + return MAX_ADDS_IN_PROGRESS_LIMIT_KEY.getInt(this); } /** @@ -787,7 +2173,7 @@ public int getMaxAddsInProgressLimit() { * @return server configuration. */ public ServerConfiguration setMaxAddsInProgressLimit(int value) { - this.setProperty(MAX_ADDS_IN_PROGRESS_LIMIT, value); + MAX_ADDS_IN_PROGRESS_LIMIT_KEY.set(this, value); return this; } @@ -797,7 +2183,7 @@ public ServerConfiguration setMaxAddsInProgressLimit(int value) { * @return Max number of reads in progress. */ public int getMaxReadsInProgressLimit() { - return this.getInt(MAX_READS_IN_PROGRESS_LIMIT, 0); + return MAX_READS_IN_PROGRESS_LIMIT_KEY.getInt(this); } /** @@ -808,7 +2194,7 @@ public int getMaxReadsInProgressLimit() { * @return server configuration. */ public ServerConfiguration setMaxReadsInProgressLimit(int value) { - this.setProperty(MAX_READS_IN_PROGRESS_LIMIT, value); + MAX_READS_IN_PROGRESS_LIMIT_KEY.set(this, value); return this; } @@ -821,7 +2207,7 @@ public ServerConfiguration setMaxReadsInProgressLimit(int value) { * @return value indicating if channel should be closed. */ public boolean getCloseChannelOnResponseTimeout(){ - return this.getBoolean(CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT, false); + return CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT_KEY.getBoolean(this); } /** @@ -834,7 +2220,7 @@ public boolean getCloseChannelOnResponseTimeout(){ * @return server configuration. */ public ServerConfiguration setCloseChannelOnResponseTimeout(boolean value) { - this.setProperty(CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT, value); + CLOSE_CHANNEL_ON_RESPONSE_TIMEOUT_KEY.set(this, value); return this; } @@ -848,7 +2234,7 @@ public ServerConfiguration setCloseChannelOnResponseTimeout(boolean value) { * Default is -1 (disabled) */ public long getWaitTimeoutOnResponseBackpressureMillis() { - return getLong(WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE, -1); + return WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE_KEY.getLong(this); } /** @@ -862,7 +2248,7 @@ public long getWaitTimeoutOnResponseBackpressureMillis() { * @return client configuration. */ public ServerConfiguration setWaitTimeoutOnResponseBackpressureMillis(long value) { - setProperty(WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE, value); + WAIT_TIMEOUT_ON_RESPONSE_BACKPRESSURE_KEY.set(this, value); return this; } @@ -872,7 +2258,7 @@ public ServerConfiguration setWaitTimeoutOnResponseBackpressureMillis(long value * @return bookie port */ public int getBookiePort() { - return this.getInt(BOOKIE_PORT, 3181); + return BOOKIE_PORT_KEY.getInt(this); } /** @@ -883,7 +2269,7 @@ public int getBookiePort() { * @return server configuration */ public ServerConfiguration setBookiePort(int port) { - this.setProperty(BOOKIE_PORT, Integer.toString(port)); + BOOKIE_PORT_KEY.set(this, port); return this; } @@ -896,7 +2282,7 @@ public ServerConfiguration setBookiePort(int port) { * null if none is specified */ public String getListeningInterface() { - return this.getString(LISTENING_INTERFACE); + return LISTENING_INTERFACE_KEY.getString(this); } /** @@ -906,7 +2292,7 @@ public String getListeningInterface() { * @param iface the interface to listen on */ public ServerConfiguration setListeningInterface(String iface) { - this.setProperty(LISTENING_INTERFACE, iface); + LISTENING_INTERFACE_KEY.set(this, iface); return this; } @@ -929,7 +2315,7 @@ public ServerConfiguration setListeningInterface(String iface) { * @return whether a loopback interface can be used as the primary interface */ public boolean getAllowLoopback() { - return this.getBoolean(ALLOW_LOOPBACK, false); + return ALLOW_LOOPBACK_KEY.getBoolean(this); } /** @@ -941,7 +2327,7 @@ public boolean getAllowLoopback() { * @return server configuration */ public ServerConfiguration setAllowLoopback(boolean allow) { - this.setProperty(ALLOW_LOOPBACK, allow); + ALLOW_LOOPBACK_KEY.set(this, allow); return this; } @@ -956,7 +2342,7 @@ public ServerConfiguration setAllowLoopback(boolean allow) { * @return the configure address to be advertised */ public String getAdvertisedAddress() { - return this.getString(ADVERTISED_ADDRESS, null); + return ADVERTISED_ADDRESS_KEY.getString(this); } /** @@ -978,7 +2364,7 @@ public String getAdvertisedAddress() { * @return server configuration */ public ServerConfiguration setAdvertisedAddress(String advertisedAddress) { - this.setProperty(ADVERTISED_ADDRESS, advertisedAddress); + ADVERTISED_ADDRESS_KEY.set(this, advertisedAddress); return this; } @@ -993,7 +2379,7 @@ public ServerConfiguration setAdvertisedAddress(String advertisedAddress) { * @return whether is allowed to use an ephemeral port. */ public boolean getAllowEphemeralPorts() { - return this.getBoolean(ALLOW_EPHEMERAL_PORTS, false); + return ALLOW_EPHEMERAL_PORTS_KEY.getBoolean(this); } /** @@ -1003,7 +2389,7 @@ public boolean getAllowEphemeralPorts() { * @return server configuration */ public ServerConfiguration setAllowEphemeralPorts(boolean allow) { - this.setProperty(ALLOW_EPHEMERAL_PORTS, allow); + ALLOW_EPHEMERAL_PORTS_KEY.set(this, allow); return this; } @@ -1013,7 +2399,7 @@ public ServerConfiguration setAllowEphemeralPorts(boolean allow) { * @return true if the addition is allowed; false otherwise */ public boolean getAllowStorageExpansion() { - return this.getBoolean(ALLOW_STORAGE_EXPANSION, false); + return ALLOW_STORAGE_EXPANSION_KEY.getBoolean(this); } /** @@ -1025,7 +2411,7 @@ public boolean getAllowStorageExpansion() { * @return server configuration */ public ServerConfiguration setAllowStorageExpansion(boolean val) { - this.setProperty(ALLOW_STORAGE_EXPANSION, val); + ALLOW_STORAGE_EXPANSION_KEY.set(this, val); return this; } @@ -1035,7 +2421,7 @@ public ServerConfiguration setAllowStorageExpansion(boolean val) { * @return journal dir name */ public String[] getJournalDirNames() { - String[] journalDirs = this.getStringArray(JOURNAL_DIRS); + String[] journalDirs = JOURNAL_DIRS_KEY.getArray(this); if (journalDirs == null || journalDirs.length == 0) { return new String[] {getJournalDirName()}; } @@ -1049,7 +2435,7 @@ public String[] getJournalDirNames() { */ @Deprecated public String getJournalDirName() { - return this.getString(JOURNAL_DIR, "/tmp/bk-txn"); + return JOURNAL_DIR_KEY.getString(this); } /** @@ -1058,7 +2444,7 @@ public String getJournalDirName() { * @return journal dir name */ public String getJournalDirNameWithoutDefault() { - return this.getString(JOURNAL_DIR); + return JOURNAL_DIR_KEY.getStringWithoutDefault(this); } @@ -1070,7 +2456,7 @@ public String getJournalDirNameWithoutDefault() { * @return server configuration */ public ServerConfiguration setJournalDirName(String journalDir) { - this.setProperty(JOURNAL_DIRS, new String[] {journalDir}); + JOURNAL_DIRS_KEY.set(this, new String[] { journalDir }); return this; } @@ -1082,7 +2468,7 @@ public ServerConfiguration setJournalDirName(String journalDir) { * @return server configuration */ public ServerConfiguration setJournalDirsName(String[] journalDirs) { - this.setProperty(JOURNAL_DIRS, journalDirs); + JOURNAL_DIRS_KEY.set(this, journalDirs); return this; } @@ -1106,7 +2492,7 @@ public File[] getJournalDirs() { * @return ledger dir names, if not provided return null */ public String[] getLedgerDirWithoutDefault() { - return this.getStringArray(LEDGER_DIRS); + return LEDGER_DIRS_KEY.getArrayWithoutDefault(this); } /** @@ -1115,11 +2501,7 @@ public String[] getLedgerDirWithoutDefault() { * @return ledger dir names, if not provided return null */ public String[] getLedgerDirNames() { - String[] ledgerDirs = this.getStringArray(LEDGER_DIRS); - if ((null == ledgerDirs) || (0 == ledgerDirs.length)) { - return new String[] { "/tmp/bk-data" }; - } - return ledgerDirs; + return LEDGER_DIRS_KEY.getArray(this); } /** @@ -1130,10 +2512,7 @@ public String[] getLedgerDirNames() { * @return server configuration */ public ServerConfiguration setLedgerDirNames(String[] ledgerDirs) { - if (null == ledgerDirs) { - return this; - } - this.setProperty(LEDGER_DIRS, ledgerDirs); + LEDGER_DIRS_KEY.set(this, ledgerDirs); return this; } @@ -1158,10 +2537,7 @@ public File[] getLedgerDirs() { * @return ledger index dir name, if no index dirs provided return null */ public String[] getIndexDirNames() { - if (!this.containsKey(INDEX_DIRS)) { - return null; - } - return this.getStringArray(INDEX_DIRS); + return INDEX_DIRS_KEY.getArrayWithoutDefault(this); } /** @@ -1172,7 +2548,7 @@ public String[] getIndexDirNames() { * @return server configuration. */ public ServerConfiguration setIndexDirName(String[] indexDirs) { - this.setProperty(INDEX_DIRS, indexDirs); + INDEX_DIRS_KEY.set(this, indexDirs); return this; } @@ -1199,7 +2575,7 @@ public File[] getIndexDirs() { * @return tcp socket nodelay setting */ public boolean getServerTcpNoDelay() { - return getBoolean(SERVER_TCP_NODELAY, true); + return SERVER_TCP_NODELAY_KEY.getBoolean(this); } /** @@ -1210,7 +2586,7 @@ public boolean getServerTcpNoDelay() { * @return server configuration */ public ServerConfiguration setServerTcpNoDelay(boolean noDelay) { - setProperty(SERVER_TCP_NODELAY, Boolean.toString(noDelay)); + SERVER_TCP_NODELAY_KEY.set(this, noDelay); return this; } @@ -1221,7 +2597,7 @@ public ServerConfiguration setServerTcpNoDelay(boolean noDelay) { * @return the number of IO threads */ public int getServerNumIOThreads() { - return getInt(SERVER_NUM_IO_THREADS, 2 * Runtime.getRuntime().availableProcessors()); + return SERVER_NUM_IO_THREADS_KEY.getInt(this); } /** @@ -1236,7 +2612,7 @@ public int getServerNumIOThreads() { * @return client configuration */ public ServerConfiguration setServerNumIOThreads(int numThreads) { - setProperty(SERVER_NUM_IO_THREADS, Integer.toString(numThreads)); + SERVER_NUM_IO_THREADS_KEY.set(this, numThreads); return this; } @@ -1246,7 +2622,7 @@ public ServerConfiguration setServerNumIOThreads(int numThreads) { * @return socket linger setting */ public int getServerSockLinger() { - return getInt(SERVER_SOCK_LINGER, 0); + return SERVER_SOCK_LINGER_KEY.getInt(this); } /** @@ -1261,7 +2637,7 @@ public int getServerSockLinger() { * @return server configuration */ public ServerConfiguration setServerSockLinger(int linger) { - setProperty(SERVER_SOCK_LINGER, Integer.toString(linger)); + SERVER_SOCK_LINGER_KEY.set(this, linger); return this; } @@ -1271,7 +2647,7 @@ public ServerConfiguration setServerSockLinger(int linger) { * @return socket keepalive setting */ public boolean getServerSockKeepalive() { - return getBoolean(SERVER_SOCK_KEEPALIVE, true); + return SERVER_SOCK_KEEPALIVE_KEY.getBoolean(this); } /** @@ -1284,7 +2660,7 @@ public boolean getServerSockKeepalive() { * @return server configuration */ public ServerConfiguration setServerSockKeepalive(boolean keepalive) { - setProperty(SERVER_SOCK_KEEPALIVE, Boolean.toString(keepalive)); + SERVER_SOCK_KEEPALIVE_KEY.set(this, keepalive); return this; } @@ -1294,7 +2670,7 @@ public ServerConfiguration setServerSockKeepalive(boolean keepalive) { * @return zk backoff retry start time in millis. */ public int getZkRetryBackoffStartMs() { - return getInt(ZK_RETRY_BACKOFF_START_MS, getZkTimeout()); + return ZK_RETRY_BACKOFF_START_MS_KEY.getInt(this); } /** @@ -1305,7 +2681,7 @@ public int getZkRetryBackoffStartMs() { * @return server configuration. */ public ServerConfiguration setZkRetryBackoffStartMs(int retryMs) { - setProperty(ZK_RETRY_BACKOFF_START_MS, retryMs); + ZK_RETRY_BACKOFF_START_MS_KEY.set(this, retryMs); return this; } @@ -1315,7 +2691,7 @@ public ServerConfiguration setZkRetryBackoffStartMs(int retryMs) { * @return zk backoff retry max time in millis. */ public int getZkRetryBackoffMaxMs() { - return getInt(ZK_RETRY_BACKOFF_MAX_MS, getZkTimeout()); + return ZK_RETRY_BACKOFF_MAX_MS_KEY.getInt(this); } /** @@ -1326,7 +2702,7 @@ public int getZkRetryBackoffMaxMs() { * @return server configuration. */ public ServerConfiguration setZkRetryBackoffMaxMs(int retryMs) { - setProperty(ZK_RETRY_BACKOFF_MAX_MS, retryMs); + ZK_RETRY_BACKOFF_MAX_MS_KEY.set(this, retryMs); return this; } @@ -1336,7 +2712,7 @@ public ServerConfiguration setZkRetryBackoffMaxMs(int retryMs) { * @return is statistics enabled */ public boolean isStatisticsEnabled() { - return getBoolean(ENABLE_STATISTICS, true); + return ENABLE_STATISTICS_KEY.getBoolean(this); } /** @@ -1347,7 +2723,7 @@ public boolean isStatisticsEnabled() { * @return server configuration */ public ServerConfiguration setStatisticsEnabled(boolean enabled) { - setProperty(ENABLE_STATISTICS, Boolean.toString(enabled)); + ENABLE_STATISTICS_KEY.set(this, enabled); return this; } @@ -1362,7 +2738,7 @@ public ServerConfiguration setStatisticsEnabled(boolean enabled) { * @return threshold of minor compaction */ public double getMinorCompactionThreshold() { - return getDouble(MINOR_COMPACTION_THRESHOLD, 0.2f); + return MINOR_COMPACTION_THRESHOLD_KEY.getDouble(this); } /** @@ -1375,7 +2751,7 @@ public double getMinorCompactionThreshold() { * @return server configuration */ public ServerConfiguration setMinorCompactionThreshold(double threshold) { - setProperty(MINOR_COMPACTION_THRESHOLD, threshold); + MINOR_COMPACTION_THRESHOLD_KEY.set(this, threshold); return this; } @@ -1390,7 +2766,7 @@ public ServerConfiguration setMinorCompactionThreshold(double threshold) { * @return threshold of major compaction */ public double getMajorCompactionThreshold() { - return getDouble(MAJOR_COMPACTION_THRESHOLD, 0.8f); + return MAJOR_COMPACTION_THRESHOLD_KEY.getDouble(this); } /** @@ -1403,7 +2779,7 @@ public double getMajorCompactionThreshold() { * @return server configuration */ public ServerConfiguration setMajorCompactionThreshold(double threshold) { - setProperty(MAJOR_COMPACTION_THRESHOLD, threshold); + MAJOR_COMPACTION_THRESHOLD_KEY.set(this, threshold); return this; } @@ -1415,7 +2791,7 @@ public ServerConfiguration setMajorCompactionThreshold(double threshold) { * @return threshold of minor compaction */ public long getMinorCompactionInterval() { - return getLong(MINOR_COMPACTION_INTERVAL, 3600); + return MINOR_COMPACTION_INTERVAL_KEY.getLong(this); } /** @@ -1428,7 +2804,7 @@ public long getMinorCompactionInterval() { * @return server configuration */ public ServerConfiguration setMinorCompactionInterval(long interval) { - setProperty(MINOR_COMPACTION_INTERVAL, interval); + MINOR_COMPACTION_INTERVAL_KEY.set(this, interval); return this; } @@ -1440,7 +2816,7 @@ public ServerConfiguration setMinorCompactionInterval(long interval) { * @return high water mark */ public long getMajorCompactionInterval() { - return getLong(MAJOR_COMPACTION_INTERVAL, 86400); + return MAJOR_COMPACTION_INTERVAL_KEY.getLong(this); } /** @@ -1453,7 +2829,7 @@ public long getMajorCompactionInterval() { * @return server configuration */ public ServerConfiguration setMajorCompactionInterval(long interval) { - setProperty(MAJOR_COMPACTION_INTERVAL, interval); + MAJOR_COMPACTION_INTERVAL_KEY.set(this, interval); return this; } @@ -1468,7 +2844,7 @@ public ServerConfiguration setMajorCompactionInterval(long interval) { * false - suspend GC when disk full. */ public boolean getIsForceGCAllowWhenNoSpace() { - return getBoolean(IS_FORCE_GC_ALLOW_WHEN_NO_SPACE, false); + return IS_FORCE_GC_ALLOW_WHEN_NO_SPACE_KEY.getBoolean(this); } /** @@ -1479,7 +2855,7 @@ public boolean getIsForceGCAllowWhenNoSpace() { * @return ServerConfiguration */ public ServerConfiguration setIsForceGCAllowWhenNoSpace(boolean force) { - setProperty(IS_FORCE_GC_ALLOW_WHEN_NO_SPACE, force); + IS_FORCE_GC_ALLOW_WHEN_NO_SPACE_KEY.set(this, force); return this; } @@ -1499,7 +2875,7 @@ public ServerConfiguration setIsForceGCAllowWhenNoSpace(boolean force) { * @param waitTime time to wait before replicating ledger fragment */ public void setOpenLedgerRereplicationGracePeriod(String waitTime) { - setProperty(OPEN_LEDGER_REREPLICATION_GRACE_PERIOD, waitTime); + OPEN_LEDGER_REREPLICATION_GRACE_PERIOD_KEY.set(this, waitTime); } /** @@ -1510,7 +2886,7 @@ public void setOpenLedgerRereplicationGracePeriod(String waitTime) { * @return long */ public long getOpenLedgerRereplicationGracePeriod() { - return getLong(OPEN_LEDGER_REREPLICATION_GRACE_PERIOD, 30000); + return OPEN_LEDGER_REREPLICATION_GRACE_PERIOD_KEY.getLong(this); } /** @@ -1523,8 +2899,8 @@ public long getOpenLedgerRereplicationGracePeriod() { * * @param waitTime */ - public void setLockReleaseOfFailedLedgerGracePeriod(String waitTime) { - setProperty(LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD, waitTime); + public void setLockReleaseOfFailedLedgerGracePeriod(long waitTime) { + LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD_KEY.set(this, waitTime); } /** @@ -1537,7 +2913,7 @@ public void setLockReleaseOfFailedLedgerGracePeriod(String waitTime) { * @return */ public long getLockReleaseOfFailedLedgerGracePeriod() { - return getLong(LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD, 60000); + return LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD_KEY.getLong(this); } /** @@ -1547,7 +2923,7 @@ public long getLockReleaseOfFailedLedgerGracePeriod() { * @return read buffer size */ public int getReadBufferBytes() { - return getInt(READ_BUFFER_SIZE, 512); + return READ_BUFFER_SIZE_KEY.getInt(this); } /** @@ -1559,7 +2935,7 @@ public int getReadBufferBytes() { * @return server configuration */ public ServerConfiguration setReadBufferBytes(int readBufferSize) { - setProperty(READ_BUFFER_SIZE, readBufferSize); + READ_BUFFER_SIZE_KEY.set(this, readBufferSize); return this; } @@ -1571,7 +2947,7 @@ public ServerConfiguration setReadBufferBytes(int readBufferSize) { * @return server configuration */ public ServerConfiguration setNumAddWorkerThreads(int numThreads) { - setProperty(NUM_ADD_WORKER_THREADS, numThreads); + NUM_ADD_WORKER_THREADS_KEY.set(this, numThreads); return this; } @@ -1581,7 +2957,7 @@ public ServerConfiguration setNumAddWorkerThreads(int numThreads) { * @return the number of threads that handle write requests. */ public int getNumAddWorkerThreads() { - return getInt(NUM_ADD_WORKER_THREADS, 1); + return NUM_ADD_WORKER_THREADS_KEY.getInt(this); } /** @@ -1592,7 +2968,7 @@ public int getNumAddWorkerThreads() { * @return server configuration */ public ServerConfiguration setNumLongPollWorkerThreads(int numThreads) { - setProperty(NUM_LONG_POLL_WORKER_THREADS, numThreads); + NUM_LONG_POLL_WORKER_THREADS_KEY.set(this, numThreads); return this; } @@ -1606,7 +2982,7 @@ public ServerConfiguration setNumLongPollWorkerThreads(int numThreads) { * @return the number of threads that should handle long poll requests, default value is 0. */ public int getNumLongPollWorkerThreads() { - return getInt(NUM_LONG_POLL_WORKER_THREADS, 0); + return NUM_LONG_POLL_WORKER_THREADS_KEY.getInt(this); } /** @@ -1618,7 +2994,7 @@ public int getNumLongPollWorkerThreads() { * @return server configuration */ public ServerConfiguration setNumHighPriorityWorkerThreads(int numThreads) { - setProperty(NUM_HIGH_PRIORITY_WORKER_THREADS, numThreads); + NUM_HIGH_PRIORITY_WORKER_THREADS_KEY.set(this, numThreads); return this; } @@ -1628,7 +3004,7 @@ public ServerConfiguration setNumHighPriorityWorkerThreads(int numThreads) { * @return */ public int getNumHighPriorityWorkerThreads() { - return getInt(NUM_HIGH_PRIORITY_WORKER_THREADS, 8); + return NUM_HIGH_PRIORITY_WORKER_THREADS_KEY.getInt(this); } @@ -1640,7 +3016,7 @@ public int getNumHighPriorityWorkerThreads() { * @return server configuration */ public ServerConfiguration setNumReadWorkerThreads(int numThreads) { - setProperty(NUM_READ_WORKER_THREADS, numThreads); + NUM_READ_WORKER_THREADS_KEY.set(this, numThreads); return this; } @@ -1648,7 +3024,7 @@ public ServerConfiguration setNumReadWorkerThreads(int numThreads) { * Get the number of threads that should handle read requests. */ public int getNumReadWorkerThreads() { - return getInt(NUM_READ_WORKER_THREADS, 8); + return NUM_READ_WORKER_THREADS_KEY.getInt(this); } /** @@ -1659,7 +3035,7 @@ public int getNumReadWorkerThreads() { * @return server configuration */ public ServerConfiguration setRequestTimerTickDurationMs(int tickDuration) { - setProperty(REQUEST_TIMER_TICK_DURATION_MILLISEC, tickDuration); + REQUEST_TIMER_TICK_DURATION_MILLISEC_KEY.set(this, tickDuration); return this; } @@ -1671,7 +3047,7 @@ public ServerConfiguration setRequestTimerTickDurationMs(int tickDuration) { * @return server configuration */ public ServerConfiguration setMaxPendingReadRequestPerThread(int maxPendingReadRequestsPerThread) { - setProperty(MAX_PENDING_READ_REQUESTS_PER_THREAD, maxPendingReadRequestsPerThread); + MAX_PENDING_READ_REQUESTS_PER_THREAD_KEY.set(this, maxPendingReadRequestsPerThread); return this; } @@ -1680,7 +3056,7 @@ public ServerConfiguration setMaxPendingReadRequestPerThread(int maxPendingReadR * indefinitely (default: 10000 entries). */ public int getMaxPendingReadRequestPerThread() { - return getInt(MAX_PENDING_READ_REQUESTS_PER_THREAD, 10000); + return MAX_PENDING_READ_REQUESTS_PER_THREAD_KEY.getInt(this); } /** @@ -1691,7 +3067,7 @@ public int getMaxPendingReadRequestPerThread() { * @return server configuration */ public ServerConfiguration setMaxPendingAddRequestPerThread(int maxPendingAddRequestsPerThread) { - setProperty(MAX_PENDING_ADD_REQUESTS_PER_THREAD, maxPendingAddRequestsPerThread); + MAX_PENDING_ADD_REQUESTS_PER_THREAD_KEY.set(this, maxPendingAddRequestsPerThread); return this; } @@ -1700,17 +3076,15 @@ public ServerConfiguration setMaxPendingAddRequestPerThread(int maxPendingAddReq * indefinitely (default: 10000 entries). */ public int getMaxPendingAddRequestPerThread() { - return getInt(MAX_PENDING_ADD_REQUESTS_PER_THREAD, 10000); + return MAX_PENDING_ADD_REQUESTS_PER_THREAD_KEY.getInt(this); } - - /** * Get the tick duration in milliseconds. * @return */ public int getRequestTimerTickDurationMs() { - return getInt(REQUEST_TIMER_TICK_DURATION_MILLISEC, 10); + return REQUEST_TIMER_TICK_DURATION_MILLISEC_KEY.getInt(this); } /** @@ -1721,7 +3095,7 @@ public int getRequestTimerTickDurationMs() { * @return server configuration */ public ServerConfiguration setRequestTimerNumTicks(int tickCount) { - setProperty(REQUEST_TIMER_NO_OF_TICKS, tickCount); + REQUEST_TIMER_NO_OF_TICKS_KEY.set(this, tickCount); return this; } @@ -1730,7 +3104,7 @@ public ServerConfiguration setRequestTimerNumTicks(int tickCount) { * @return */ public int getRequestTimerNumTicks() { - return getInt(REQUEST_TIMER_NO_OF_TICKS, 1024); + return REQUEST_TIMER_NO_OF_TICKS_KEY.getInt(this); } /** @@ -1740,7 +3114,7 @@ public int getRequestTimerNumTicks() { * @return the size of the write buffer in bytes */ public int getWriteBufferBytes() { - return getInt(WRITE_BUFFER_SIZE, 65536); + return WRITE_BUFFER_SIZE_KEY.getInt(this); } /** @@ -1751,7 +3125,7 @@ public int getWriteBufferBytes() { * @return server configuration */ public ServerConfiguration setWriteBufferBytes(int writeBufferBytes) { - setProperty(WRITE_BUFFER_SIZE, writeBufferBytes); + WRITE_BUFFER_SIZE_KEY.set(this, writeBufferBytes); return this; } @@ -1763,7 +3137,7 @@ public ServerConfiguration setWriteBufferBytes(int writeBufferBytes) { * @return server configuration */ public ServerConfiguration setNumJournalCallbackThreads(int numThreads) { - setProperty(NUM_JOURNAL_CALLBACK_THREADS, numThreads); + NUM_JOURNAL_CALLBACK_THREADS_KEY.set(this, numThreads); return this; } @@ -1773,7 +3147,7 @@ public ServerConfiguration setNumJournalCallbackThreads(int numThreads) { * @return the number of threads that handle journal callbacks. */ public int getNumJournalCallbackThreads() { - return getInt(NUM_JOURNAL_CALLBACK_THREADS, 1); + return NUM_JOURNAL_CALLBACK_THREADS_KEY.getInt(this); } /** @@ -1783,7 +3157,7 @@ public int getNumJournalCallbackThreads() { * @param enabled */ public ServerConfiguration setSortedLedgerStorageEnabled(boolean enabled) { - this.setProperty(SORTED_LEDGER_STORAGE_ENABLED, enabled); + SORTED_LEDGER_STORAGE_ENABLED_KEY.set(this, enabled); return this; } @@ -1793,7 +3167,7 @@ public ServerConfiguration setSortedLedgerStorageEnabled(boolean enabled) { * @return true if sorted ledger storage is enabled, false otherwise */ public boolean getSortedLedgerStorageEnabled() { - return this.getBoolean(SORTED_LEDGER_STORAGE_ENABLED, true); + return SORTED_LEDGER_STORAGE_ENABLED_KEY.getBoolean(this); } /** @@ -1803,7 +3177,7 @@ public boolean getSortedLedgerStorageEnabled() { * @return skip list data size limitation */ public long getSkipListSizeLimit() { - return this.getLong(SKIP_LIST_SIZE_LIMIT, 64 * 1024 * 1024L); + return SKIP_LIST_SIZE_LIMIT_KEY.getLong(this); } /** @@ -1813,11 +3187,7 @@ public long getSkipListSizeLimit() { * @return server configuration object. */ public ServerConfiguration setSkipListSizeLimit(int size) { - if (size > (Integer.MAX_VALUE - 1) / 2) { - // gives max of 2*1023MB for mem table (one being checkpointed and still writable). - throw new IllegalArgumentException("skiplist size over " + ((Integer.MAX_VALUE - 1) / 2)); - } - setProperty(SKIP_LIST_SIZE_LIMIT, size); + SKIP_LIST_SIZE_LIMIT_KEY.set(this, size); return this; } @@ -1828,7 +3198,7 @@ public ServerConfiguration setSkipListSizeLimit(int size) { * @return the number of bytes to use for each chunk in the skiplist arena */ public int getSkipListArenaChunkSize() { - return getInt(SKIP_LIST_CHUNK_SIZE_ENTRY, 4096 * 1024); + return SKIP_LIST_CHUNK_SIZE_ENTRY_KEY.getInt(this); } /** @@ -1839,7 +3209,7 @@ public int getSkipListArenaChunkSize() { * @return server configuration object. */ public ServerConfiguration setSkipListArenaChunkSize(int size) { - setProperty(SKIP_LIST_CHUNK_SIZE_ENTRY, size); + SKIP_LIST_CHUNK_SIZE_ENTRY_KEY.set(this, size); return this; } @@ -1850,7 +3220,7 @@ public ServerConfiguration setSkipListArenaChunkSize(int size) { * @return max size allocatable from the skiplist arena (Default is 128 KB) */ public int getSkipListArenaMaxAllocSize() { - return getInt(SKIP_LIST_MAX_ALLOC_ENTRY, 128 * 1024); + return SKIP_LIST_MAX_ALLOC_ENTRY_KEY.getInt(this); } /** @@ -1861,7 +3231,7 @@ public int getSkipListArenaMaxAllocSize() { * @return server configuration object. */ public ServerConfiguration setSkipListArenaMaxAllocSize(int size) { - setProperty(SKIP_LIST_MAX_ALLOC_ENTRY, size); + SKIP_LIST_MAX_ALLOC_ENTRY_KEY.set(this, size); return this; } @@ -1873,7 +3243,7 @@ public ServerConfiguration setSkipListArenaMaxAllocSize(int size) { * @return */ public boolean getJournalSyncData() { - return getBoolean(JOURNAL_SYNC_DATA, true); + return JOURNAL_SYNC_DATA_KEY.getBoolean(this); } /** @@ -1891,7 +3261,7 @@ public boolean getJournalSyncData() { * @return server configuration object */ public ServerConfiguration setJournalSyncData(boolean syncData) { - setProperty(JOURNAL_SYNC_DATA, syncData); + JOURNAL_SYNC_DATA_KEY.set(this, syncData); return this; } @@ -1901,7 +3271,7 @@ public ServerConfiguration setJournalSyncData(boolean syncData) { * @return group journal force writes */ public boolean getJournalAdaptiveGroupWrites() { - return getBoolean(JOURNAL_ADAPTIVE_GROUP_WRITES, true); + return JOURNAL_ADAPTIVE_GROUP_WRITES_KEY.getBoolean(this); } /** @@ -1910,7 +3280,7 @@ public boolean getJournalAdaptiveGroupWrites() { * @param enabled flag to enable/disable group journal force writes */ public ServerConfiguration setJournalAdaptiveGroupWrites(boolean enabled) { - setProperty(JOURNAL_ADAPTIVE_GROUP_WRITES, enabled); + JOURNAL_ADAPTIVE_GROUP_WRITES_KEY.set(this, enabled); return this; } @@ -1920,7 +3290,7 @@ public ServerConfiguration setJournalAdaptiveGroupWrites(boolean enabled) { * @return max wait for grouping */ public long getJournalMaxGroupWaitMSec() { - return getLong(JOURNAL_MAX_GROUP_WAIT_MSEC, 2); + return JOURNAL_MAX_GROUP_WAIT_MSEC_KEY.getLong(this); } /** @@ -1931,7 +3301,7 @@ public long getJournalMaxGroupWaitMSec() { * @return server configuration. */ public ServerConfiguration setJournalMaxGroupWaitMSec(long journalMaxGroupWaitMSec) { - setProperty(JOURNAL_MAX_GROUP_WAIT_MSEC, journalMaxGroupWaitMSec); + JOURNAL_MAX_GROUP_WAIT_MSEC_KEY.set(this, journalMaxGroupWaitMSec); return this; } @@ -1941,7 +3311,7 @@ public ServerConfiguration setJournalMaxGroupWaitMSec(long journalMaxGroupWaitMS * @return max bytes to buffer */ public long getJournalBufferedWritesThreshold() { - return getLong(JOURNAL_BUFFERED_WRITES_THRESHOLD, 512 * 1024); + return JOURNAL_BUFFERED_WRITES_THRESHOLD_KEY.getLong(this); } /** @@ -1952,7 +3322,7 @@ public long getJournalBufferedWritesThreshold() { * @return max entries to buffer. */ public long getJournalBufferedEntriesThreshold() { - return getLong(JOURNAL_BUFFERED_ENTRIES_THRESHOLD, 0); + return JOURNAL_BUFFERED_ENTRIES_THRESHOLD_KEY.getLong(this); } /** @@ -1973,7 +3343,7 @@ public ServerConfiguration setJournalBufferedEntriesThreshold(int maxEntries) { * Set if we should flush the journal when queue is empty. */ public ServerConfiguration setJournalFlushWhenQueueEmpty(boolean enabled) { - setProperty(JOURNAL_FLUSH_WHEN_QUEUE_EMPTY, enabled); + JOURNAL_FLUSH_WHEN_QUEUE_EMPTY_KEY.set(this, enabled); return this; } @@ -1983,7 +3353,7 @@ public ServerConfiguration setJournalFlushWhenQueueEmpty(boolean enabled) { * @return flush when queue is empty */ public boolean getJournalFlushWhenQueueEmpty() { - return getBoolean(JOURNAL_FLUSH_WHEN_QUEUE_EMPTY, false); + return JOURNAL_FLUSH_WHEN_QUEUE_EMPTY_KEY.getBoolean(this); } /** @@ -1996,7 +3366,7 @@ public boolean getJournalFlushWhenQueueEmpty() { * @return ServerConfiguration */ public ServerConfiguration setReadOnlyModeEnabled(boolean enabled) { - setProperty(READ_ONLY_MODE_ENABLED, enabled); + READ_ONLY_MODE_ENABLED_KEY.set(this, enabled); return this; } @@ -2006,7 +3376,7 @@ public ServerConfiguration setReadOnlyModeEnabled(boolean enabled) { * @return boolean */ public boolean isReadOnlyModeEnabled() { - return getBoolean(READ_ONLY_MODE_ENABLED, true); + return READ_ONLY_MODE_ENABLED_KEY.getBoolean(this); } /** @@ -2017,7 +3387,7 @@ public boolean isReadOnlyModeEnabled() { * @return ServerConfiguration */ public ServerConfiguration setDiskUsageWarnThreshold(float threshold) { - setProperty(DISK_USAGE_WARN_THRESHOLD, threshold); + DISK_USAGE_WARN_THRESHOLD_KEY.set(this, threshold); return this; } @@ -2027,7 +3397,7 @@ public ServerConfiguration setDiskUsageWarnThreshold(float threshold) { * @return the percentage at which a disk usage warning will trigger */ public float getDiskUsageWarnThreshold() { - return getFloat(DISK_USAGE_WARN_THRESHOLD, 0.90f); + return DISK_USAGE_WARN_THRESHOLD_KEY.getFloat(this); } /** @@ -2039,7 +3409,7 @@ public float getDiskUsageWarnThreshold() { * @return ServerConfiguration */ public ServerConfiguration setPersistBookieStatusEnabled(boolean enabled) { - setProperty(PERSIST_BOOKIE_STATUS_ENABLED, enabled); + PERSIST_BOOKIE_STATUS_ENABLED_KEY.set(this, enabled); return this; } @@ -2050,7 +3420,7 @@ public ServerConfiguration setPersistBookieStatusEnabled(boolean enabled) { * @return true - if need to start a bookie in read only mode. Otherwise false. */ public boolean isPersistBookieStatusEnabled() { - return getBoolean(PERSIST_BOOKIE_STATUS_ENABLED, false); + return PERSIST_BOOKIE_STATUS_ENABLED_KEY.getBoolean(this); } /** @@ -2062,7 +3432,7 @@ public boolean isPersistBookieStatusEnabled() { * @return ServerConfiguration */ public ServerConfiguration setDiskUsageThreshold(float threshold) { - setProperty(DISK_USAGE_THRESHOLD, threshold); + DISK_USAGE_THRESHOLD_KEY.set(this, threshold); return this; } @@ -2072,7 +3442,7 @@ public ServerConfiguration setDiskUsageThreshold(float threshold) { * @return the percentage at which a disk will be considered full */ public float getDiskUsageThreshold() { - return getFloat(DISK_USAGE_THRESHOLD, 0.95f); + return DISK_USAGE_THRESHOLD_KEY.getFloat(this); } /** @@ -2088,7 +3458,7 @@ public float getDiskUsageThreshold() { * @return ServerConfiguration */ public ServerConfiguration setDiskLowWaterMarkUsageThreshold(float threshold) { - setProperty(DISK_USAGE_LWM_THRESHOLD, threshold); + DISK_USAGE_LWM_THRESHOLD_KEY.set(this, threshold); return this; } @@ -2099,7 +3469,7 @@ public ServerConfiguration setDiskLowWaterMarkUsageThreshold(float threshold) { * @return the percentage below which a disk will NOT be considered full */ public float getDiskLowWaterMarkUsageThreshold() { - return getFloat(DISK_USAGE_LWM_THRESHOLD, getDiskUsageThreshold()); + return DISK_USAGE_LWM_THRESHOLD_KEY.getFloat(this); } /** @@ -2110,7 +3480,7 @@ public float getDiskLowWaterMarkUsageThreshold() { * @return ServerConfiguration */ public ServerConfiguration setDiskCheckInterval(int interval) { - setProperty(DISK_CHECK_INTERVAL, interval); + DISK_CHECK_INTERVAL_KEY.set(this, interval); return this; } @@ -2120,7 +3490,7 @@ public ServerConfiguration setDiskCheckInterval(int interval) { * @return int */ public int getDiskCheckInterval() { - return getInt(DISK_CHECK_INTERVAL, 10 * 1000); + return DISK_CHECK_INTERVAL_KEY.getInt(this); } /** @@ -2132,7 +3502,7 @@ public int getDiskCheckInterval() { * @param interval The interval in seconds. e.g. 86400 = 1 day, 604800 = 1 week */ public void setAuditorPeriodicCheckInterval(long interval) { - setProperty(AUDITOR_PERIODIC_CHECK_INTERVAL, interval); + AUDITOR_PERIODIC_CHECK_INTERVAL_KEY.set(this, interval); } /** @@ -2140,7 +3510,7 @@ public void setAuditorPeriodicCheckInterval(long interval) { * @return The interval in seconds. Default is 604800 (1 week). */ public long getAuditorPeriodicCheckInterval() { - return getLong(AUDITOR_PERIODIC_CHECK_INTERVAL, 604800); + return AUDITOR_PERIODIC_CHECK_INTERVAL_KEY.getLong(this); } /** @@ -2154,7 +3524,7 @@ public long getAuditorPeriodicCheckInterval() { * @param interval The period in seconds. */ public void setAuditorPeriodicBookieCheckInterval(long interval) { - setProperty(AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL, interval); + AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL_KEY.set(this, interval); } /** @@ -2163,7 +3533,7 @@ public void setAuditorPeriodicBookieCheckInterval(long interval) { * @return the interval between bookie check runs, in seconds. Default is 86400 (= 1 day) */ public long getAuditorPeriodicBookieCheckInterval() { - return getLong(AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL, 86400); + return AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL_KEY.getLong(this); } /** @@ -2175,7 +3545,7 @@ public long getAuditorPeriodicBookieCheckInterval() { * @return ServerConfiguration */ public ServerConfiguration setAuditorLedgerVerificationPercentage(long auditorLedgerVerificationPercentage) { - setProperty(AUDITOR_LEDGER_VERIFICATION_PERCENTAGE, auditorLedgerVerificationPercentage); + AUDITOR_LEDGER_VERIFICATION_PERCENTAGE_KEY.set(this, auditorLedgerVerificationPercentage); return this; } @@ -2185,7 +3555,7 @@ public ServerConfiguration setAuditorLedgerVerificationPercentage(long auditorLe * @return percentage of a ledger (fragment)'s entries will be verified. Default is 0. */ public long getAuditorLedgerVerificationPercentage() { - return getLong(AUDITOR_LEDGER_VERIFICATION_PERCENTAGE, 0); + return AUDITOR_LEDGER_VERIFICATION_PERCENTAGE_KEY.getLong(this); } /** @@ -2198,7 +3568,7 @@ public long getAuditorLedgerVerificationPercentage() { * @return ServerConfiguration */ public ServerConfiguration setAutoRecoveryDaemonEnabled(boolean enabled) { - setProperty(AUTO_RECOVERY_DAEMON_ENABLED, enabled); + AUTO_RECOVERY_DAEMON_ENABLED_KEY.set(this, enabled); return this; } @@ -2209,7 +3579,7 @@ public ServerConfiguration setAutoRecoveryDaemonEnabled(boolean enabled) { * it. false otherwise. */ public boolean isAutoRecoveryDaemonEnabled() { - return getBoolean(AUTO_RECOVERY_DAEMON_ENABLED, false); + return AUTO_RECOVERY_DAEMON_ENABLED_KEY.getBoolean(this); } /** @@ -2218,14 +3588,14 @@ public boolean isAutoRecoveryDaemonEnabled() { * @return delay interval in seconds */ public int getLostBookieRecoveryDelay() { - return getInt(LOST_BOOKIE_RECOVERY_DELAY, 0); + return LOST_BOOKIE_RECOVERY_DELAY_KEY.getInt(this); } /** * Set the delay interval for starting recovery of a lost bookie. */ public void setLostBookieRecoveryDelay(int interval) { - setProperty(LOST_BOOKIE_RECOVERY_DELAY, interval); + LOST_BOOKIE_RECOVERY_DELAY_KEY.set(this, interval); } /** @@ -2234,7 +3604,7 @@ public void setLostBookieRecoveryDelay(int interval) { * @return backoff time in milliseconds */ public int getRwRereplicateBackoffMs() { - return getInt(RW_REREPLICATE_BACKOFF_MS, 5000); + return RW_REREPLICATE_BACKOFF_MS_KEY.getInt(this); } /** @@ -2243,7 +3613,7 @@ public int getRwRereplicateBackoffMs() { * @param backoffMs backoff time in milliseconds */ public void setRwRereplicateBackoffMs(int backoffMs) { - setProperty(RW_REREPLICATE_BACKOFF_MS, backoffMs); + RW_REREPLICATE_BACKOFF_MS_KEY.set(this, backoffMs); } /** @@ -2255,7 +3625,7 @@ public void setRwRereplicateBackoffMs(int backoffMs) { * @return ServerConfiguration */ public ServerConfiguration setForceReadOnlyBookie(boolean enabled) { - setProperty(FORCE_READ_ONLY_BOOKIE, enabled); + FORCE_READ_ONLY_BOOKIE_KEY.set(this, enabled); return this; } @@ -2266,7 +3636,7 @@ public ServerConfiguration setForceReadOnlyBookie(boolean enabled) { * false. */ public boolean isForceReadOnlyBookie() { - return getBoolean(FORCE_READ_ONLY_BOOKIE, false); + return FORCE_READ_ONLY_BOOKIE_KEY.getBoolean(this); } /** @@ -2276,7 +3646,7 @@ public boolean isForceReadOnlyBookie() { * false - use Entries. */ public boolean getIsThrottleByBytes() { - return getBoolean(IS_THROTTLE_BY_BYTES, false); + return IS_THROTTLE_BY_BYTES_KEY.getBoolean(this); } /** @@ -2287,7 +3657,7 @@ public boolean getIsThrottleByBytes() { * @return ServerConfiguration */ public ServerConfiguration setIsThrottleByBytes(boolean byBytes) { - setProperty(IS_THROTTLE_BY_BYTES, byBytes); + IS_THROTTLE_BY_BYTES_KEY.set(this, byBytes); return this; } @@ -2298,7 +3668,7 @@ public ServerConfiguration setIsThrottleByBytes(boolean byBytes) { * @return the maximum number of unflushed entries */ public int getCompactionMaxOutstandingRequests() { - return getInt(COMPACTION_MAX_OUTSTANDING_REQUESTS, 100000); + return COMPACTION_MAX_OUTSTANDING_REQUESTS_KEY.getInt(this); } /** @@ -2318,7 +3688,7 @@ public int getCompactionMaxOutstandingRequests() { * @return ServerConfiguration */ public ServerConfiguration setCompactionMaxOutstandingRequests(int maxOutstandingRequests) { - setProperty(COMPACTION_MAX_OUTSTANDING_REQUESTS, maxOutstandingRequests); + COMPACTION_MAX_OUTSTANDING_REQUESTS_KEY.set(this, maxOutstandingRequests); return this; } @@ -2330,7 +3700,7 @@ public ServerConfiguration setCompactionMaxOutstandingRequests(int maxOutstandin */ @Deprecated public int getCompactionRate() { - return getInt(COMPACTION_RATE, 1000); + return COMPACTION_RATE_KEY.getInt(this); } /** @@ -2341,7 +3711,7 @@ public int getCompactionRate() { * @return ServerConfiguration */ public ServerConfiguration setCompactionRate(int rate) { - setProperty(COMPACTION_RATE, rate); + COMPACTION_RATE_KEY.set(this, rate); return this; } @@ -2351,7 +3721,7 @@ public ServerConfiguration setCompactionRate(int rate) { * @return rate of compaction (adds entries per second) */ public int getCompactionRateByEntries() { - return getInt(COMPACTION_RATE_BY_ENTRIES, getCompactionRate()); + return COMPACTION_RATE_BY_ENTRIES_KEY.getInt(this); } /** @@ -2362,7 +3732,7 @@ public int getCompactionRateByEntries() { * @return ServerConfiguration */ public ServerConfiguration setCompactionRateByEntries(int rate) { - setProperty(COMPACTION_RATE_BY_ENTRIES, rate); + COMPACTION_RATE_BY_ENTRIES_KEY.set(this, rate); return this; } @@ -2372,7 +3742,7 @@ public ServerConfiguration setCompactionRateByEntries(int rate) { * @return rate of compaction (adds bytes per second) */ public int getCompactionRateByBytes() { - return getInt(COMPACTION_RATE_BY_BYTES, 1000000); + return COMPACTION_RATE_BY_BYTES_KEY.getInt(this); } /** @@ -2383,7 +3753,7 @@ public int getCompactionRateByBytes() { * @return ServerConfiguration */ public ServerConfiguration setCompactionRateByBytes(int rate) { - setProperty(COMPACTION_RATE_BY_BYTES, rate); + COMPACTION_RATE_BY_BYTES_KEY.set(this, rate); return this; } @@ -2394,7 +3764,7 @@ public ServerConfiguration setCompactionRateByBytes(int rate) { */ @Beta public boolean getJournalRemovePagesFromCache() { - return getBoolean(JOURNAL_REMOVE_FROM_PAGE_CACHE, true); + return JOURNAL_REMOVE_FROM_PAGE_CACHE_KEY.getBoolean(this); } /** @@ -2405,7 +3775,7 @@ public boolean getJournalRemovePagesFromCache() { * @return ServerConfiguration */ public ServerConfiguration setJournalRemovePagesFromCache(boolean enabled) { - setProperty(JOURNAL_REMOVE_FROM_PAGE_CACHE, enabled); + JOURNAL_REMOVE_FROM_PAGE_CACHE_KEY.set(this, enabled); return this; } @@ -2451,7 +3821,7 @@ public ServerConfiguration setLedgerStorageClass(String ledgerStorageClass) { * use its ipaddress */ public boolean getUseHostNameAsBookieID() { - return getBoolean(USE_HOST_NAME_AS_BOOKIE_ID, false); + return USE_HOST_NAME_AS_BOOKIE_ID_KEY.getBoolean(this); } /** @@ -2464,7 +3834,7 @@ public boolean getUseHostNameAsBookieID() { * @return server configuration */ public ServerConfiguration setUseHostNameAsBookieID(boolean useHostName) { - setProperty(USE_HOST_NAME_AS_BOOKIE_ID, useHostName); + USE_HOST_NAME_AS_BOOKIE_ID_KEY.set(this, useHostName); return this; } @@ -2477,7 +3847,7 @@ public ServerConfiguration setUseHostNameAsBookieID(boolean useHostName) { * will use its FQDN hostname */ public boolean getUseShortHostName() { - return getBoolean(USE_SHORT_HOST_NAME, false); + return USE_SHORT_HOST_NAME_KEY.getBoolean(this); } /** @@ -2492,7 +3862,7 @@ public boolean getUseShortHostName() { * @return server configuration */ public ServerConfiguration setUseShortHostName(boolean useShortHostName) { - setProperty(USE_SHORT_HOST_NAME, useShortHostName); + USE_SHORT_HOST_NAME_KEY.set(this, useShortHostName); return this; } @@ -2502,7 +3872,7 @@ public ServerConfiguration setUseShortHostName(boolean useShortHostName) { * @return true, then bookie will be listen for local JVM clients */ public boolean isEnableLocalTransport() { - return getBoolean(ENABLE_LOCAL_TRANSPORT, false); + return ENABLE_LOCAL_TRANSPORT_KEY.getBoolean(this); } /** @@ -2514,7 +3884,7 @@ public boolean isEnableLocalTransport() { * @return server configuration */ public ServerConfiguration setEnableLocalTransport(boolean enableLocalTransport) { - setProperty(ENABLE_LOCAL_TRANSPORT, enableLocalTransport); + ENABLE_LOCAL_TRANSPORT_KEY.set(this, enableLocalTransport); return this; } @@ -2524,7 +3894,7 @@ public ServerConfiguration setEnableLocalTransport(boolean enableLocalTransport) * @return true, then bookie will not listen for network connections */ public boolean isDisableServerSocketBind() { - return getBoolean(DISABLE_SERVER_SOCKET_BIND, false); + return DISABLE_SERVER_SOCKET_BIND_KEY.getBoolean(this); } /** @@ -2537,7 +3907,7 @@ public boolean isDisableServerSocketBind() { * @return server configuration */ public ServerConfiguration setDisableServerSocketBind(boolean disableServerSocketBind) { - setProperty(DISABLE_SERVER_SOCKET_BIND, disableServerSocketBind); + DISABLE_SERVER_SOCKET_BIND_KEY.set(this, disableServerSocketBind); return this; } @@ -2547,11 +3917,8 @@ public ServerConfiguration setDisableServerSocketBind(boolean disableServerSocke * @return stats provider class * @throws ConfigurationException */ - public Class getStatsProviderClass() - throws ConfigurationException { - return ReflectionUtils.getClass(this, STATS_PROVIDER_CLASS, - NullStatsProvider.class, StatsProvider.class, - DEFAULT_LOADER); + public Class getStatsProviderClass() { + return STATS_PROVIDER_CLASS_KEY.getClass(this, StatsProvider.class); } /** @@ -2562,7 +3929,7 @@ public Class getStatsProviderClass() * @return server configuration */ public ServerConfiguration setStatsProviderClass(Class providerClass) { - setProperty(STATS_PROVIDER_CLASS, providerClass.getName()); + STATS_PROVIDER_CLASS_KEY.set(this, providerClass); return this; } @@ -2607,7 +3974,7 @@ public void validate() throws ConfigurationException { * @return initial byteBuf size */ public int getRecvByteBufAllocatorSizeInitial() { - return getInt(BYTEBUF_ALLOCATOR_SIZE_INITIAL, 64 * 1024); + return BYTEBUF_ALLOCATOR_SIZE_INITIAL_KEY.getInt(this); } /** @@ -2617,7 +3984,7 @@ public int getRecvByteBufAllocatorSizeInitial() { * buffer size */ public void setRecvByteBufAllocatorSizeInitial(int size) { - setProperty(BYTEBUF_ALLOCATOR_SIZE_INITIAL, size); + BYTEBUF_ALLOCATOR_SIZE_INITIAL_KEY.set(this, size); } /** @@ -2626,7 +3993,7 @@ public void setRecvByteBufAllocatorSizeInitial(int size) { * @return min byteBuf size */ public int getRecvByteBufAllocatorSizeMin() { - return getInt(BYTEBUF_ALLOCATOR_SIZE_MIN, 64 * 1024); + return BYTEBUF_ALLOCATOR_SIZE_MIN_KEY.getInt(this); } /** @@ -2636,7 +4003,7 @@ public int getRecvByteBufAllocatorSizeMin() { * buffer size */ public void setRecvByteBufAllocatorSizeMin(int size) { - setProperty(BYTEBUF_ALLOCATOR_SIZE_MIN, size); + BYTEBUF_ALLOCATOR_SIZE_MIN_KEY.set(this, size); } /** @@ -2645,7 +4012,7 @@ public void setRecvByteBufAllocatorSizeMin(int size) { * @return max byteBuf size */ public int getRecvByteBufAllocatorSizeMax() { - return getInt(BYTEBUF_ALLOCATOR_SIZE_MAX, 1 * 1024 * 1024); + return BYTEBUF_ALLOCATOR_SIZE_MAX_KEY.getInt(this); } /** @@ -2655,7 +4022,7 @@ public int getRecvByteBufAllocatorSizeMax() { * buffer size */ public void setRecvByteBufAllocatorSizeMax(int size) { - setProperty(BYTEBUF_ALLOCATOR_SIZE_MAX, size); + BYTEBUF_ALLOCATOR_SIZE_MAX_KEY.set(this, size); } /** @@ -2666,7 +4033,7 @@ public void setRecvByteBufAllocatorSizeMax(int size) { * the bookie authentication provider factory class name */ public void setBookieAuthProviderFactoryClass(String factoryClass) { - setProperty(BOOKIE_AUTH_PROVIDER_FACTORY_CLASS, factoryClass); + BOOKIE_AUTH_PROVIDER_FACTORY_CLASS_KEY.set(this, factoryClass); } /** @@ -2676,7 +4043,7 @@ public void setBookieAuthProviderFactoryClass(String factoryClass) { * @return the bookie authentication provider factory class name or null. */ public String getBookieAuthProviderFactoryClass() { - return getString(BOOKIE_AUTH_PROVIDER_FACTORY_CLASS, null); + return BOOKIE_AUTH_PROVIDER_FACTORY_CLASS_KEY.getString(this); } /** @@ -2694,7 +4061,7 @@ public ServerConfiguration setNettyMaxFrameSizeBytes(int maxSize) { * @return */ public String getTLSTrustStoreType() { - return getString(TLS_TRUSTSTORE_TYPE, "JKS"); + return TLS_TRUSTSTORE_TYPE_KEY.getString(this); } /** @@ -2703,7 +4070,7 @@ public String getTLSTrustStoreType() { * @return */ public ServerConfiguration setTLSKeyStoreType(String arg) { - setProperty(TLS_KEYSTORE_TYPE, arg); + TLS_TRUSTSTORE_TYPE_KEY.set(this, arg); return this; } @@ -2713,7 +4080,7 @@ public ServerConfiguration setTLSKeyStoreType(String arg) { * @return */ public String getTLSKeyStore() { - return getString(TLS_KEYSTORE, null); + return TLS_KEYSTORE_KEY.getString(this); } /** @@ -2722,7 +4089,7 @@ public String getTLSKeyStore() { * @return */ public ServerConfiguration setTLSKeyStore(String arg) { - setProperty(TLS_KEYSTORE, arg); + TLS_KEYSTORE_KEY.set(this, arg); return this; } @@ -2732,7 +4099,7 @@ public ServerConfiguration setTLSKeyStore(String arg) { * @return */ public String getTLSKeyStorePasswordPath() { - return getString(TLS_KEYSTORE_PASSWORD_PATH, null); + return TLS_KEYSTORE_PASSWORD_PATH_KEY.getString(this); } /** @@ -2741,7 +4108,7 @@ public String getTLSKeyStorePasswordPath() { * @return */ public ServerConfiguration setTLSKeyStorePasswordPath(String arg) { - setProperty(TLS_KEYSTORE_PASSWORD_PATH, arg); + TLS_KEYSTORE_PASSWORD_PATH_KEY.set(this, arg); return this; } @@ -2751,7 +4118,7 @@ public ServerConfiguration setTLSKeyStorePasswordPath(String arg) { * @return */ public String getTLSKeyStoreType() { - return getString(TLS_KEYSTORE_TYPE, "JKS"); + return TLS_KEYSTORE_TYPE_KEY.getString(this); } /** @@ -2770,7 +4137,7 @@ public ServerConfiguration setTLSTrustStoreType(String arg) { * @return */ public String getTLSTrustStore() { - return getString(TLS_TRUSTSTORE, null); + return TLS_TRUSTSTORE_KEY.getString(this); } /** @@ -2779,7 +4146,7 @@ public String getTLSTrustStore() { * @return */ public ServerConfiguration setTLSTrustStore(String arg) { - setProperty(TLS_TRUSTSTORE, arg); + TLS_TRUSTSTORE_KEY.set(this, arg); return this; } @@ -2790,7 +4157,7 @@ public ServerConfiguration setTLSTrustStore(String arg) { * @return */ public String getTLSTrustStorePasswordPath() { - return getString(TLS_TRUSTSTORE_PASSWORD_PATH, null); + return TLS_TRUSTSTORE_PASSWORD_PATH_KEY.getString(this); } /** @@ -2799,37 +4166,17 @@ public String getTLSTrustStorePasswordPath() { * @return */ public ServerConfiguration setTLSTrustStorePasswordPath(String arg) { - setProperty(TLS_TRUSTSTORE_PASSWORD_PATH, arg); - return this; - } - - /** - * Get the path to file containing TLS Certificate. - * - * @return - */ - public String getTLSCertificatePath() { - return getString(TLS_CERTIFICATE_PATH, null); - } - - /** - * Set the path to file containing TLS Certificate. - * - * @return - */ - public ServerConfiguration setTLSCertificatePath(String arg) { - setProperty(TLS_CERTIFICATE_PATH, arg); + TLS_TRUSTSTORE_PASSWORD_PATH_KEY.set(this, arg); return this; } - /** * Whether to enable recording task execution stats. * * @return flag to enable/disable recording task execution stats. */ public boolean getEnableTaskExecutionStats() { - return getBoolean(ENABLE_TASK_EXECUTION_STATS, false); + return ENABLE_TASK_EXECUTION_STATS_KEY.getBoolean(this); } /** @@ -2840,7 +4187,7 @@ public boolean getEnableTaskExecutionStats() { * @return client configuration. */ public ServerConfiguration setEnableTaskExecutionStats(boolean enabled) { - setProperty(ENABLE_TASK_EXECUTION_STATS, enabled); + ENABLE_TASK_EXECUTION_STATS_KEY.set(this, enabled); return this; } @@ -2852,7 +4199,7 @@ public ServerConfiguration setEnableTaskExecutionStats(boolean enabled) { * @see #setMinUsableSizeForIndexFileCreation(long) */ public long getMinUsableSizeForIndexFileCreation() { - return this.getLong(MIN_USABLESIZE_FOR_INDEXFILE_CREATION, 100 * 1024 * 1024L); + return MIN_USABLESIZE_FOR_INDEXFILE_CREATION_KEY.getLong(this); } /** @@ -2867,7 +4214,7 @@ public long getMinUsableSizeForIndexFileCreation() { * @return server configuration */ public ServerConfiguration setMinUsableSizeForIndexFileCreation(long minUsableSizeForIndexFileCreation) { - this.setProperty(MIN_USABLESIZE_FOR_INDEXFILE_CREATION, minUsableSizeForIndexFileCreation); + MIN_USABLESIZE_FOR_INDEXFILE_CREATION_KEY.set(this, minUsableSizeForIndexFileCreation); return this; } @@ -2878,7 +4225,7 @@ public ServerConfiguration setMinUsableSizeForIndexFileCreation(long minUsableSi * @see #setMinUsableSizeForEntryLogCreation(long) */ public long getMinUsableSizeForEntryLogCreation() { - return this.getLong(MIN_USABLESIZE_FOR_ENTRYLOG_CREATION, (long) 1.2 * getEntryLogSizeLimit()); + return MIN_USABLESIZE_FOR_ENTRYLOG_CREATION_KEY.getLong(this); } /** @@ -2892,7 +4239,7 @@ public long getMinUsableSizeForEntryLogCreation() { * @return server configuration */ public ServerConfiguration setMinUsableSizeForEntryLogCreation(long minUsableSizeForEntryLogCreation) { - this.setProperty(MIN_USABLESIZE_FOR_ENTRYLOG_CREATION, minUsableSizeForEntryLogCreation); + MIN_USABLESIZE_FOR_ENTRYLOG_CREATION_KEY.set(this, minUsableSizeForEntryLogCreation); return this; } @@ -2904,7 +4251,7 @@ public ServerConfiguration setMinUsableSizeForEntryLogCreation(long minUsableSiz * @return the minimum safe usable size per ledger directory for bookie to accept high priority writes. */ public long getMinUsableSizeForHighPriorityWrites() { - return this.getLong(MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES, getMinUsableSizeForEntryLogCreation()); + return MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES_KEY.getLong(this); } /** @@ -2915,7 +4262,7 @@ public long getMinUsableSizeForHighPriorityWrites() { * @return server configuration. */ public ServerConfiguration setMinUsableSizeForHighPriorityWrites(long minUsableSizeForHighPriorityWrites) { - this.setProperty(MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES, minUsableSizeForHighPriorityWrites); + MIN_USABLESIZE_FOR_HIGH_PRIORITY_WRITES_KEY.set(this, minUsableSizeForHighPriorityWrites); return this; } @@ -2926,7 +4273,7 @@ public ServerConfiguration setMinUsableSizeForHighPriorityWrites(long minUsableS * @return */ public boolean isAllowMultipleDirsUnderSameDiskPartition() { - return this.getBoolean(ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION, true); + return ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION_KEY.getBoolean(this); } /** @@ -2938,7 +4285,7 @@ public boolean isAllowMultipleDirsUnderSameDiskPartition() { * @return server configuration object. */ public ServerConfiguration setAllowMultipleDirsUnderSameDiskPartition(boolean allow) { - this.setProperty(ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION, allow); + ALLOW_MULTIPLEDIRS_UNDER_SAME_DISKPARTITION_KEY.set(this, allow); return this; } @@ -2948,7 +4295,7 @@ public ServerConfiguration setAllowMultipleDirsUnderSameDiskPartition(boolean al * @return true - if http server should start */ public boolean isHttpServerEnabled() { - return getBoolean(HTTP_SERVER_ENABLED, false); + return HTTP_SERVER_ENABLED_KEY.getBoolean(this); } /** @@ -2959,7 +4306,7 @@ public boolean isHttpServerEnabled() { * @return ServerConfiguration */ public ServerConfiguration setHttpServerEnabled(boolean enabled) { - setProperty(HTTP_SERVER_ENABLED, enabled); + HTTP_SERVER_ENABLED_KEY.set(this, enabled); return this; } @@ -2969,7 +4316,7 @@ public ServerConfiguration setHttpServerEnabled(boolean enabled) { * @return http server port */ public int getHttpServerPort() { - return getInt(HTTP_SERVER_PORT, 8080); + return HTTP_SERVER_PORT_KEY.getInt(this); } /** @@ -2980,7 +4327,7 @@ public int getHttpServerPort() { * @return server configuration */ public ServerConfiguration setHttpServerPort(int port) { - setProperty(HTTP_SERVER_PORT, port); + HTTP_SERVER_PORT_KEY.set(this, port); return this; } @@ -2990,11 +4337,7 @@ public ServerConfiguration setHttpServerPort(int port) { * @return the extra list of server lifecycle components to enable on a bookie server. */ public String[] getExtraServerComponents() { - String extraServerComponentsStr = getString(EXTRA_SERVER_COMPONENTS); - if (Strings.isNullOrEmpty(extraServerComponentsStr)) { - return null; - } - return this.getStringArray(EXTRA_SERVER_COMPONENTS); + return EXTRA_SERVER_COMPONENTS_KEY.getArrayWithoutDefault(this); } /** @@ -3005,7 +4348,7 @@ public String[] getExtraServerComponents() { * @return server configuration. */ public ServerConfiguration setExtraServerComponents(String[] componentClasses) { - this.setProperty(EXTRA_SERVER_COMPONENTS, componentClasses); + EXTRA_SERVER_COMPONENTS_KEY.set(this, componentClasses); return this; } @@ -3017,7 +4360,7 @@ public ServerConfiguration setExtraServerComponents(String[] componentClasses) { * {@link #getExtraServerComponents()}. The default value is false. */ public boolean getIgnoreExtraServerComponentsStartupFailures() { - return getBoolean(IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES, false); + return IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES_KEY.getBoolean(this); } /** @@ -3028,7 +4371,7 @@ public boolean getIgnoreExtraServerComponentsStartupFailures() { * @return server configuration. */ public ServerConfiguration setIgnoreExtraServerComponentsStartupFailures(boolean enabled) { - setProperty(IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES, enabled); + IGNORE_EXTRA_SERVER_COMPONENTS_STARTUP_FAILURES_KEY.set(this, enabled); return this; } @@ -3038,7 +4381,7 @@ public ServerConfiguration setIgnoreExtraServerComponentsStartupFailures(boolean * @return netty channel write buffer low water mark. */ public int getServerWriteBufferLowWaterMark() { - return getInt(SERVER_WRITEBUFFER_LOW_WATER_MARK, 384 * 1024); + return SERVER_WRITEBUFFER_LOW_WATER_MARK_KEY.getInt(this); } /** @@ -3049,7 +4392,7 @@ public int getServerWriteBufferLowWaterMark() { * @return client configuration. */ public ServerConfiguration setServerWriteBufferLowWaterMark(int waterMark) { - setProperty(SERVER_WRITEBUFFER_LOW_WATER_MARK, waterMark); + SERVER_WRITEBUFFER_LOW_WATER_MARK_KEY.set(this, waterMark); return this; } @@ -3059,7 +4402,7 @@ public ServerConfiguration setServerWriteBufferLowWaterMark(int waterMark) { * @return netty channel write buffer high water mark. */ public int getServerWriteBufferHighWaterMark() { - return getInt(SERVER_WRITEBUFFER_HIGH_WATER_MARK, 512 * 1024); + return SERVER_WRITEBUFFER_HIGH_WATER_MARK_KEY.getInt(this); } /** @@ -3070,9 +4413,10 @@ public int getServerWriteBufferHighWaterMark() { * @return client configuration. */ public ServerConfiguration setServerWriteBufferHighWaterMark(int waterMark) { - setProperty(SERVER_WRITEBUFFER_HIGH_WATER_MARK, waterMark); + SERVER_WRITEBUFFER_HIGH_WATER_MARK_KEY.set(this, waterMark); return this; } + /** * Set registration manager class. * @@ -3083,7 +4427,7 @@ public ServerConfiguration setServerWriteBufferHighWaterMark(int waterMark) { @Deprecated public void setRegistrationManagerClass( Class regManagerClass) { - setProperty(REGISTRATION_MANAGER_CLASS, regManagerClass); + REGISTRATION_MANAGER_CLASS_KEY.set(this, regManagerClass); } /** @@ -3095,9 +4439,7 @@ public void setRegistrationManagerClass( @Deprecated public Class getRegistrationManagerClass() throws ConfigurationException { - return ReflectionUtils.getClass(this, REGISTRATION_MANAGER_CLASS, - ZKRegistrationManager.class, RegistrationManager.class, - DEFAULT_LOADER); + return REGISTRATION_MANAGER_CLASS_KEY.getClass(this, RegistrationManager.class); } @Override @@ -3110,7 +4452,7 @@ protected ServerConfiguration getThis() { * would be a active entrylog for each ledger */ public boolean isEntryLogPerLedgerEnabled() { - return this.getBoolean(ENTRY_LOG_PER_LEDGER_ENABLED, false); + return ENTRY_LOG_PER_LEDGER_ENABLED_KEY.getBoolean(this); } /* @@ -3118,7 +4460,7 @@ public boolean isEntryLogPerLedgerEnabled() { * */ public ServerConfiguration setEntryLogPerLedgerEnabled(boolean entryLogPerLedgerEnabled) { - this.setProperty(ENTRY_LOG_PER_LEDGER_ENABLED, Boolean.toString(entryLogPerLedgerEnabled)); + ENTRY_LOG_PER_LEDGER_ENABLED_KEY.set(this, entryLogPerLedgerEnabled); return this; } @@ -3128,7 +4470,7 @@ public ServerConfiguration setEntryLogPerLedgerEnabled(boolean entryLogPerLedger * Gets the number of threads used to flush entrymemtable */ public int getNumOfMemtableFlushThreads() { - return this.getInt(NUMBER_OF_MEMTABLE_FLUSH_THREADS, 8); + return NUMBER_OF_MEMTABLE_FLUSH_THREADS_KEY.getInt(this); } /* @@ -3136,7 +4478,7 @@ public int getNumOfMemtableFlushThreads() { * */ public ServerConfiguration setNumOfMemtableFlushThreads(int numOfMemtableFlushThreads) { - this.setProperty(NUMBER_OF_MEMTABLE_FLUSH_THREADS, Integer.toString(numOfMemtableFlushThreads)); + NUMBER_OF_MEMTABLE_FLUSH_THREADS_KEY.set(this, numOfMemtableFlushThreads); return this; } @@ -3146,7 +4488,7 @@ public ServerConfiguration setNumOfMemtableFlushThreads(int numOfMemtableFlushTh * automatically removed from the cache */ public int getEntrylogMapAccessExpiryTimeInSeconds() { - return this.getInt(ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS, 5 * 60); + return ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS_KEY.getInt(this); } /* @@ -3154,8 +4496,7 @@ public int getEntrylogMapAccessExpiryTimeInSeconds() { * policy, in entrylogperledger feature. */ public ServerConfiguration setEntrylogMapAccessExpiryTimeInSeconds(int entrylogMapAccessExpiryTimeInSeconds) { - this.setProperty(ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS, - Integer.toString(entrylogMapAccessExpiryTimeInSeconds)); + ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS_KEY.set(this, entrylogMapAccessExpiryTimeInSeconds); return this; } @@ -3164,7 +4505,7 @@ public ServerConfiguration setEntrylogMapAccessExpiryTimeInSeconds(int entrylogM * in time. */ public int getMaximumNumberOfActiveEntryLogs() { - return this.getInt(MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS, 500); + return MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS_KEY.getInt(this); } /* @@ -3172,8 +4513,7 @@ public int getMaximumNumberOfActiveEntryLogs() { * in time. */ public ServerConfiguration setMaximumNumberOfActiveEntryLogs(int maximumNumberOfActiveEntryLogs) { - this.setProperty(MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS, - Integer.toString(maximumNumberOfActiveEntryLogs)); + MAXIMUM_NUMBER_OF_ACTIVE_ENTRYLOGS_KEY.set(this, maximumNumberOfActiveEntryLogs); return this; } @@ -3182,7 +4522,7 @@ public ServerConfiguration setMaximumNumberOfActiveEntryLogs(int maximumNumberOf * metrics cache size limits in multiples of entrylogMap cache size limits. */ public int getEntryLogPerLedgerCounterLimitsMultFactor() { - return this.getInt(ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR, 10); + return ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR_KEY.getInt(this); } /* @@ -3191,8 +4531,7 @@ public int getEntryLogPerLedgerCounterLimitsMultFactor() { */ public ServerConfiguration setEntryLogPerLedgerCounterLimitsMultFactor( int entryLogPerLedgerCounterLimitsMultFactor) { - this.setProperty(ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR, - Integer.toString(entryLogPerLedgerCounterLimitsMultFactor)); + ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS_KEY.set(this, entryLogPerLedgerCounterLimitsMultFactor); return this; } @@ -3200,6 +4539,20 @@ public ServerConfiguration setEntryLogPerLedgerCounterLimitsMultFactor( * True if a local consistency check should be performed on startup. */ public boolean isLocalConsistencyCheckOnStartup() { - return this.getBoolean(LOCAL_CONSISTENCY_CHECK_ON_STARTUP, false); + return LOCAL_CONSISTENCY_CHECK_ON_STARTUP_KEY.getBoolean(this); + } + + /** + * Limit who can start the application to prevent future permission errors. + */ + public void setPermittedStartupUsers(String s) { + PERMITTED_STARTUP_USERS_KEY.set(this, s); + } + + /** + * Get array of users specified in this property. + */ + public String[] getPermittedStartupUsers() { + return PERMITTED_STARTUP_USERS_KEY.getArray(this); } } diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java index 27e8ab2eef5..634198b36cf 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java @@ -22,7 +22,7 @@ import static org.apache.bookkeeper.bookie.BookKeeperServerStats.BOOKIE_SCOPE; import static org.apache.bookkeeper.bookie.BookKeeperServerStats.SERVER_SCOPE; -import static org.apache.bookkeeper.conf.AbstractConfiguration.PERMITTED_STARTUP_USERS; +import static org.apache.bookkeeper.conf.ServerConfiguration.PERMITTED_STARTUP_USERS; import com.google.common.annotations.VisibleForTesting; import java.io.IOException; diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java index 9df734646f0..c69581b3636 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java @@ -474,7 +474,7 @@ public void testBookiesNotAvailableScenarioForReplicationWorker() throws Excepti } // create couple of replicationworkers - baseConf.setLockReleaseOfFailedLedgerGracePeriod("500"); + baseConf.setLockReleaseOfFailedLedgerGracePeriod(500L); ReplicationWorker rw1 = new ReplicationWorker(baseConf); ReplicationWorker rw2 = new ReplicationWorker(baseConf); diff --git a/bookkeeper-stats-providers/codahale-metrics-provider/pom.xml b/bookkeeper-stats-providers/codahale-metrics-provider/pom.xml index cab53fefad0..ef91b8e1910 100644 --- a/bookkeeper-stats-providers/codahale-metrics-provider/pom.xml +++ b/bookkeeper-stats-providers/codahale-metrics-provider/pom.xml @@ -31,7 +31,12 @@ org.apache.bookkeeper.stats bookkeeper-stats-api - ${project.parent.version} + ${project.version} + + + org.apache.bookkeeper + bookkeeper-common + ${project.version} io.dropwizard.metrics diff --git a/bookkeeper-stats-providers/codahale-metrics-provider/src/main/java/org/apache/bookkeeper/stats/codahale/CodahaleMetricsProvider.java b/bookkeeper-stats-providers/codahale-metrics-provider/src/main/java/org/apache/bookkeeper/stats/codahale/CodahaleMetricsProvider.java index 1bd5b185efa..b5184cd9b34 100644 --- a/bookkeeper-stats-providers/codahale-metrics-provider/src/main/java/org/apache/bookkeeper/stats/codahale/CodahaleMetricsProvider.java +++ b/bookkeeper-stats-providers/codahale-metrics-provider/src/main/java/org/apache/bookkeeper/stats/codahale/CodahaleMetricsProvider.java @@ -33,6 +33,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import org.apache.bookkeeper.common.conf.ConfigKey; +import org.apache.bookkeeper.common.conf.Type; import org.apache.bookkeeper.stats.StatsLogger; import org.apache.bookkeeper.stats.StatsProvider; import org.apache.commons.configuration.Configuration; @@ -47,6 +49,54 @@ public class CodahaleMetricsProvider implements StatsProvider { static final Logger LOG = LoggerFactory.getLogger(CodahaleMetricsProvider.class); + private static final ConfigKey STATS_PREFIX_KEY = + ConfigKey.builder("codahaleStatsPrefix") + .type(Type.STRING) + .description("metric name prefix, default is \"\"") + .defaultValue("") + .orderInGroup(0) + .build(); + + private static final ConfigKey STATS_OUTPUT_FREQUENCY_SECONDS_KEY = + ConfigKey.builder("codahaleStatsOutputFrequencySeconds") + .type(Type.INT) + .description("the frequency that stats reporters report stats, in seconds") + .defaultValue(60) + .orderInGroup(1) + .build(); + + private static final ConfigKey STATS_GRAPHITE_ENDPOINT_KEY = + ConfigKey.builder("codahaleStatsGraphiteEndpoint") + .type(Type.STRING) + .description("the graphite endpoint for reporting stats") + .documentation("See {@link http://metrics.dropwizard.io/3.1.0/manual/graphite/} for more details") + .orderInGroup(2) + .build(); + + private static final ConfigKey STATS_CSV_ENDPOINT_KEY = + ConfigKey.builder("codahaleStatsCSVEndpoint") + .type(Type.STRING) + .description("the directory for reporting stats in csv format") + .documentation("See {@link http://metrics.dropwizard.io/3.1.0/manual/core/#csv} for more details") + .orderInGroup(3) + .build(); + + private static final ConfigKey STATS_SLF4J_ENDPOINT_KEY = + ConfigKey.builder("codahaleStatsSlf4jEndpoint") + .type(Type.STRING) + .description("the slf4j endpoint for reporting stats") + .documentation("See {@link http://metrics.dropwizard.io/3.1.0/manual/core/#slf4j} for more details") + .orderInGroup(4) + .build(); + + private static final ConfigKey STATS_JMX_ENDPOINT_KEY = + ConfigKey.builder("codahaleStatsJmxEndpoint") + .type(Type.STRING) + .description("the jmx endpoint for reporting stats") + .documentation("See {@link http://metrics.dropwizard.io/3.1.0/manual/core/#jmx} for more details") + .orderInGroup(5) + .build(); + MetricRegistry metrics = null; List reporters = new ArrayList(); JmxReporter jmx = null; @@ -67,12 +117,12 @@ public synchronized MetricRegistry getMetrics() { public void start(Configuration conf) { initIfNecessary(); - int metricsOutputFrequency = conf.getInt("codahaleStatsOutputFrequencySeconds", 60); - String prefix = conf.getString("codahaleStatsPrefix", ""); - String graphiteHost = conf.getString("codahaleStatsGraphiteEndpoint"); - String csvDir = conf.getString("codahaleStatsCSVEndpoint"); - String slf4jCat = conf.getString("codahaleStatsSlf4jEndpoint"); - String jmxDomain = conf.getString("codahaleStatsJmxEndpoint"); + int metricsOutputFrequency = STATS_OUTPUT_FREQUENCY_SECONDS_KEY.getInt(conf); + String prefix = STATS_PREFIX_KEY.getString(conf); + String graphiteHost = STATS_GRAPHITE_ENDPOINT_KEY.getString(conf); + String csvDir = STATS_CSV_ENDPOINT_KEY.getString(conf); + String slf4jCat = STATS_SLF4J_ENDPOINT_KEY.getString(conf); + String jmxDomain = STATS_JMX_ENDPOINT_KEY.getString(conf); if (!Strings.isNullOrEmpty(graphiteHost)) { LOG.info("Configuring stats with graphite"); diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml b/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml index 9f212e52408..42521d15529 100644 --- a/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml +++ b/bookkeeper-stats-providers/prometheus-metrics-provider/pom.xml @@ -30,7 +30,13 @@ org.apache.bookkeeper.stats bookkeeper-stats-api - ${project.parent.version} + ${project.version} + + + + org.apache.bookkeeper + bookkeeper-common + ${project.version} diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java b/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java index 0b4c0c2111e..626023ca402 100644 --- a/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java +++ b/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java @@ -42,6 +42,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import org.apache.bookkeeper.common.conf.ConfigKey; +import org.apache.bookkeeper.common.conf.Type; import org.apache.bookkeeper.stats.CachingStatsProvider; import org.apache.bookkeeper.stats.StatsLogger; import org.apache.bookkeeper.stats.StatsProvider; @@ -62,12 +64,30 @@ public class PrometheusMetricsProvider implements StatsProvider { public static final String PROMETHEUS_STATS_HTTP_ENABLE = "prometheusStatsHttpEnable"; public static final boolean DEFAULT_PROMETHEUS_STATS_HTTP_ENABLE = true; + private static final ConfigKey PROMETHEUS_STATS_HTTP_ENABLE_KEY = ConfigKey.builder(PROMETHEUS_STATS_HTTP_ENABLE) + .type(Type.BOOLEAN) + .description("Flag to enable or disable prometheus http server for exposing stats") + .defaultValue(DEFAULT_PROMETHEUS_STATS_HTTP_ENABLE) + .orderInGroup(0) + .build(); public static final String PROMETHEUS_STATS_HTTP_PORT = "prometheusStatsHttpPort"; public static final int DEFAULT_PROMETHEUS_STATS_HTTP_PORT = 8000; + private static final ConfigKey PROMETHEUS_STATS_HTTP_PORT_KEY = ConfigKey.builder(PROMETHEUS_STATS_HTTP_PORT) + .type(Type.INT) + .description("Default port for Prometheus metrics exporter") + .defaultValue(DEFAULT_PROMETHEUS_STATS_HTTP_PORT) + .orderInGroup(1) + .build(); public static final String PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS = "prometheusStatsLatencyRolloverSeconds"; public static final int DEFAULT_PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS = 60; + private static final ConfigKey PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS_KEY = + ConfigKey.builder(PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS) + .description("latency stats rollover interval, in seconds") + .defaultValue(DEFAULT_PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS) + .orderInGroup(2) + .build(); final CollectorRegistry registry; @@ -120,11 +140,11 @@ public String getStatsName(String... statsComponents) { @Override public void start(Configuration conf) { - boolean httpEnabled = conf.getBoolean(PROMETHEUS_STATS_HTTP_ENABLE, DEFAULT_PROMETHEUS_STATS_HTTP_ENABLE); + boolean httpEnabled = PROMETHEUS_STATS_HTTP_ENABLE_KEY.getBoolean(conf); boolean bkHttpServerEnabled = conf.getBoolean("httpServerEnabled", false); // only start its own http server when prometheus http is enabled and bk http server is not enabled. if (httpEnabled && !bkHttpServerEnabled) { - int httpPort = conf.getInt(PROMETHEUS_STATS_HTTP_PORT, DEFAULT_PROMETHEUS_STATS_HTTP_PORT); + int httpPort = PROMETHEUS_STATS_HTTP_PORT_KEY.getInt(conf); InetSocketAddress httpEndpoint = InetSocketAddress.createUnresolved("0.0.0.0", httpPort); this.server = new Server(httpEndpoint); ServletContextHandler context = new ServletContextHandler(); @@ -164,8 +184,7 @@ public double get() { executor = Executors.newSingleThreadScheduledExecutor(new DefaultThreadFactory("metrics")); - int latencyRolloverSeconds = conf.getInt(PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS, - DEFAULT_PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS); + int latencyRolloverSeconds = PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS_KEY.getInt(conf); executor.scheduleAtFixedRate(() -> { rotateLatencyCollection(); diff --git a/bookkeeper-stats-providers/twitter-ostrich-provider/pom.xml b/bookkeeper-stats-providers/twitter-ostrich-provider/pom.xml index f1662e28223..50a8dc78a0e 100644 --- a/bookkeeper-stats-providers/twitter-ostrich-provider/pom.xml +++ b/bookkeeper-stats-providers/twitter-ostrich-provider/pom.xml @@ -31,7 +31,12 @@ org.apache.bookkeeper.stats bookkeeper-stats-api - ${project.parent.version} + ${project.version} + + + org.apache.bookkeeper + bookkeeper-common + ${project.version} com.twitter diff --git a/bookkeeper-stats-providers/twitter-ostrich-provider/src/main/java/org/apache/bookkeeper/stats/twitter/ostrich/OstrichProvider.java b/bookkeeper-stats-providers/twitter-ostrich-provider/src/main/java/org/apache/bookkeeper/stats/twitter/ostrich/OstrichProvider.java index 173b20022c1..35ab21f9880 100644 --- a/bookkeeper-stats-providers/twitter-ostrich-provider/src/main/java/org/apache/bookkeeper/stats/twitter/ostrich/OstrichProvider.java +++ b/bookkeeper-stats-providers/twitter-ostrich-provider/src/main/java/org/apache/bookkeeper/stats/twitter/ostrich/OstrichProvider.java @@ -22,6 +22,8 @@ import com.twitter.ostrich.admin.StatsFactory; import com.twitter.util.Duration; import java.util.concurrent.TimeUnit; +import org.apache.bookkeeper.common.conf.ConfigKey; +import org.apache.bookkeeper.common.conf.Type; import org.apache.bookkeeper.stats.CachingStatsProvider; import org.apache.bookkeeper.stats.StatsLogger; import org.apache.bookkeeper.stats.StatsProvider; @@ -43,6 +45,30 @@ public class OstrichProvider implements StatsProvider { protected static final String STATS_HTTP_PORT = "statsHttpPort"; protected static final String SHOULD_SHUTDOWN_SERVICE_TRACKER = "shouldShutdownServiceTracker"; + private static final ConfigKey STATS_EXPORT_KEY = ConfigKey.builder(STATS_EXPORT) + .type(Type.BOOLEAN) + .description("Flag to control whether to expose ostrich metrics via a http endpoint configured by `" + + STATS_HTTP_PORT + "`") + .defaultValue(false) + .orderInGroup(0) + .build(); + + private static final ConfigKey STATS_HTTP_PORT_KEY = ConfigKey.builder(STATS_HTTP_PORT) + .type(Type.INT) + .description("The http port of exposing ostrich stats if `" + STATS_EXPORT + "` is set to true") + .defaultValue(9002) + .orderInGroup(1) + .build(); + + private static final ConfigKey SHOULD_SHUTDOWN_SERVICE_TRACKER_KEY = + ConfigKey.builder(SHOULD_SHUTDOWN_SERVICE_TRACKER) + .type(Type.BOOLEAN) + .description("Flag to control whether to shutdown ostrich service tracker when shutting" + + " down ostrich provider") + .defaultValue(false) + .orderInGroup(2) + .build(); + private com.twitter.ostrich.admin.AdminHttpService statsExporter = null; private final CachingStatsProvider cachingStatsProvider; private boolean shutdownServiceTracker = false; @@ -90,13 +116,13 @@ public StatsLogger getStatsLogger(String scope) { @Override public void start(Configuration conf) { - if (conf.getBoolean(STATS_EXPORT, false)) { + if (STATS_EXPORT_KEY.getBoolean(conf)) { statsExporter = new com.twitter.ostrich.admin.AdminServiceFactory( - conf.getInt(STATS_HTTP_PORT, 9002), 20, OstrichProvider.emptyList(), + STATS_HTTP_PORT_KEY.getInt(conf), 20, OstrichProvider.emptyList(), Some.apply(""), OstrichProvider.emptyList(), OstrichProvider.emptyMap(), list(Duration.apply(1, TimeUnit.MINUTES)) ).apply(RuntimeEnvironment.apply(this, new String[0])); - this.shutdownServiceTracker = conf.getBoolean(SHOULD_SHUTDOWN_SERVICE_TRACKER, false); + this.shutdownServiceTracker = SHOULD_SHUTDOWN_SERVICE_TRACKER_KEY.getBoolean(conf); } } diff --git a/bookkeeper-stats-providers/twitter-science-provider/pom.xml b/bookkeeper-stats-providers/twitter-science-provider/pom.xml index 278a5b5262c..6b2a6474566 100644 --- a/bookkeeper-stats-providers/twitter-science-provider/pom.xml +++ b/bookkeeper-stats-providers/twitter-science-provider/pom.xml @@ -33,7 +33,12 @@ org.apache.bookkeeper.stats bookkeeper-stats-api - ${project.parent.version} + ${project.version} + + + org.apache.bookkeeper + bookkeeper-common + ${project.version} com.twitter.common diff --git a/bookkeeper-stats-providers/twitter-science-provider/src/main/java/org/apache/bookkeeper/stats/twitter/science/TwitterStatsProvider.java b/bookkeeper-stats-providers/twitter-science-provider/src/main/java/org/apache/bookkeeper/stats/twitter/science/TwitterStatsProvider.java index 2a410c03b03..510116716ca 100644 --- a/bookkeeper-stats-providers/twitter-science-provider/src/main/java/org/apache/bookkeeper/stats/twitter/science/TwitterStatsProvider.java +++ b/bookkeeper-stats-providers/twitter-science-provider/src/main/java/org/apache/bookkeeper/stats/twitter/science/TwitterStatsProvider.java @@ -16,6 +16,8 @@ */ package org.apache.bookkeeper.stats.twitter.science; +import org.apache.bookkeeper.common.conf.ConfigKey; +import org.apache.bookkeeper.common.conf.Type; import org.apache.bookkeeper.stats.CachingStatsProvider; import org.apache.bookkeeper.stats.StatsLogger; import org.apache.bookkeeper.stats.StatsProvider; @@ -34,6 +36,21 @@ public class TwitterStatsProvider implements StatsProvider { protected static final String STATS_EXPORT = "statsExport"; protected static final String STATS_HTTP_PORT = "statsHttpPort"; + private static final ConfigKey STATS_EXPORT_KEY = ConfigKey.builder(STATS_EXPORT) + .type(Type.BOOLEAN) + .description("Flag to control whether to expose metrics via a http endpoint configured by `" + + STATS_HTTP_PORT + "`") + .defaultValue(false) + .orderInGroup(0) + .build(); + + private static final ConfigKey STATS_HTTP_PORT_KEY = ConfigKey.builder(STATS_HTTP_PORT) + .type(Type.INT) + .description("The http port of exposing stats if `" + STATS_EXPORT + "` is set to true") + .defaultValue(9002) + .orderInGroup(1) + .build(); + private HTTPStatsExporter statsExporter = null; private final CachingStatsProvider cachingStatsProvider; @@ -64,8 +81,8 @@ public String getStatsName(String... statsComponents) { @Override public void start(Configuration conf) { - if (conf.getBoolean(STATS_EXPORT, false)) { - statsExporter = new HTTPStatsExporter(conf.getInt(STATS_HTTP_PORT, 9002)); + if (STATS_EXPORT_KEY.getBoolean(conf)) { + statsExporter = new HTTPStatsExporter(STATS_HTTP_PORT_KEY.getInt(conf)); } if (null != statsExporter) { try { From be12a98428112cb0f3058da7d5223c4d64c27e20 Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Sun, 13 Jan 2019 12:08:18 +0900 Subject: [PATCH 2/6] Fix bugs --- .../bookkeeper/common/conf/ConfigKey.java | 40 ++++++++++++------- .../conf/AbstractConfiguration.java | 6 +-- .../bookkeeper/conf/ServerConfiguration.java | 2 +- .../prometheus/PrometheusMetricsProvider.java | 1 + 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java index 15df0529a04..6754025db80 100644 --- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java +++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java @@ -116,6 +116,15 @@ private Object defaultValue(Configuration conf) { } } + private Number defaultValueAsNumber(Configuration conf) { + Object value = defaultValue(conf); + if (value instanceof Number) { + return (Number) value; + } else { + throw new IllegalArgumentException("The default value of key '" + name() + "' is not a NUMBER"); + } + } + private String defaultValueAsString(Configuration conf) { Object defaultValue = defaultValue(conf); if (null == defaultValue) { @@ -228,17 +237,20 @@ public void validate(Configuration conf) throws ConfigException { * @param value value of the setting */ public void set(Configuration conf, Object value) { - if (!type().validator().validate(name(), value)) { - throw new IllegalArgumentException( - "Invalid value '" + value + "' to set on setting '" + name() + "': expected type = " + type); - } + if (null == value) { + conf.setProperty(name(), null); + } else { + if (!type().validator().validate(name(), value)) { + throw new IllegalArgumentException( + "Invalid value '" + value + "' to set on setting '" + name() + "': expected type = " + type); + } - if (null != validator() && !validator().validate(name(), value)) { - throw new IllegalArgumentException( - "Invalid value '" + value + "' to set on setting '" + name() + "': required '" + validator() + "'"); - } + if (null != validator() && !validator().validate(name(), value)) { + throw new IllegalArgumentException( + "Invalid value '" + value + "' to set on setting '" + name() + + "': required '" + validator() + "'"); + } - if (null != value) { if (value instanceof Class) { conf.setProperty(name(), ((Class) value).getName()); } else { @@ -255,7 +267,7 @@ public void set(Configuration conf, Object value) { */ public long getLong(Configuration conf) { checkArgument(type() == Type.LONG, "'" + name() + "' is NOT a LONG numeric setting"); - return conf.getLong(name(), (Long) defaultValue(conf)); + return conf.getLong(name(), defaultValueAsNumber(conf).longValue()); } /** @@ -266,7 +278,7 @@ public long getLong(Configuration conf) { */ public int getInt(Configuration conf) { checkArgument(type() == Type.INT, "'" + name() + "' is NOT a INT numeric setting"); - return conf.getInt(name(), (Integer) defaultValue(conf)); + return conf.getInt(name(), defaultValueAsNumber(conf).intValue()); } /** @@ -277,7 +289,7 @@ public int getInt(Configuration conf) { */ public short getShort(Configuration conf) { checkArgument(type() == Type.SHORT, "'" + name() + "' is NOT a SHORT numeric setting"); - return conf.getShort(name(), (Short) defaultValue(conf)); + return conf.getShort(name(), defaultValueAsNumber(conf).shortValue()); } /** @@ -299,7 +311,7 @@ public boolean getBoolean(Configuration conf) { */ public double getDouble(Configuration conf) { checkArgument(type() == Type.DOUBLE, "'" + name() + "' is NOT a DOUBLE numeric setting"); - return conf.getDouble(name(), (Double) defaultValue(conf)); + return conf.getDouble(name(), defaultValueAsNumber(conf).doubleValue()); } /** @@ -310,7 +322,7 @@ public double getDouble(Configuration conf) { */ public float getFloat(Configuration conf) { checkArgument(type() == Type.FLOAT, "'" + name() + "' is NOT a FLOAT numeric setting"); - return conf.getFloat(name(), (Float) defaultValue(conf)); + return conf.getFloat(name(), defaultValueAsNumber(conf).floatValue()); } /** diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java index 9d75cb4ebf4..4a411625422 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java @@ -81,7 +81,7 @@ public abstract class AbstractConfiguration protected static final String METADATA_SERVICE_URI = "metadataServiceUri"; protected static final ConfigKey METADATA_SERVICE_URI_KEY = ConfigKey.builder(METADATA_SERVICE_URI) .type(Type.STRING) - .description("metadata service uri that bookkeeper is used for loading corresponding metadata driver" + .description("metadata service uri that bookkeeper uses for loading corresponding metadata driver" + " and resolving its metadata service location") .required(true) .group(GROUP_METADATA_SERVICE) @@ -218,7 +218,7 @@ public abstract class AbstractConfiguration .type(Type.DOUBLE) .description("The Zookeeper request limit") .documentation("It is only enabled when setting a positive value. Default value is 0.") - .defaultValue(0) + .defaultValue(0.0f) .group(GROUP_ZK) .orderInGroup(3) .build(); @@ -625,7 +625,7 @@ public String getMetadataServiceUriUnchecked() throws UncheckedConfigurationExce * @throws ConfigurationException if the metadata service uri is invalid. */ public String getMetadataServiceUri() throws ConfigurationException { - String serviceUri = METADATA_SERVICE_URI_KEY.getString(this); + String serviceUri = METADATA_SERVICE_URI_KEY.getStringWithoutDefault(this); if (null == serviceUri) { // no service uri is defined, fallback to old settings String ledgerManagerType; diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index a6091ce5320..a286ebdf680 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -1340,7 +1340,7 @@ public String toString() { protected static final ConfigKey LOCAL_SCRUB_RATE_LIMIT_KEY = ConfigKey.builder(LOCAL_SCRUB_RATE_LIMIT) .type(Type.DOUBLE) .description("local scrub rate limit (entries/second)") - .defaultValue(60) + .defaultValue(60.0f) .group(GROUP_SCRUB) .orderInGroup(1) .build(); diff --git a/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java b/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java index 626023ca402..7bbd7bc8769 100644 --- a/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java +++ b/bookkeeper-stats-providers/prometheus-metrics-provider/src/main/java/org/apache/bookkeeper/stats/prometheus/PrometheusMetricsProvider.java @@ -84,6 +84,7 @@ public class PrometheusMetricsProvider implements StatsProvider { public static final int DEFAULT_PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS = 60; private static final ConfigKey PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS_KEY = ConfigKey.builder(PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS) + .type(Type.INT) .description("latency stats rollover interval, in seconds") .defaultValue(DEFAULT_PROMETHEUS_STATS_LATENCY_ROLLOVER_SECONDS) .orderInGroup(2) From 636b52baa010e35416d916c87447163bd77462f7 Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Mon, 14 Jan 2019 09:43:04 +0900 Subject: [PATCH 3/6] Fix bugs --- .../bookkeeper/common/conf/ConfigKey.java | 7 +++++- .../apache/bookkeeper/bookie/BookieShell.java | 4 ++-- .../conf/AbstractConfiguration.java | 3 +-- .../bookkeeper/conf/ServerConfiguration.java | 23 +++++++++---------- .../client/BookKeeperAdminTest.java | 2 +- .../client/BookieDecommissionTest.java | 2 +- .../replication/AuditorPeriodicCheckTest.java | 2 +- .../replication/BookieAutoRecoveryTest.java | 2 +- .../replication/TestReplicationWorker.java | 2 +- .../test/BookieJournalRollingTest.java | 2 +- 10 files changed, 26 insertions(+), 23 deletions(-) diff --git a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java index 6754025db80..0392f1ce037 100644 --- a/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java +++ b/bookkeeper-common/src/main/java/org/apache/bookkeeper/common/conf/ConfigKey.java @@ -406,7 +406,12 @@ public List getList(Configuration conf) { public String[] getArray(Configuration conf) { String[] retArray = getArrayWithoutDefault(conf); if (null == retArray || retArray.length == 0) { - return (String[]) defaultValue(conf); + Object dv = defaultValue(conf); + if (dv instanceof String[]) { + return (String[]) dv; + } else { + return new String[] { defaultValueAsString(conf) }; + } } else { return retArray; } diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java index dc9137e6a1a..8414b69c020 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java @@ -2211,12 +2211,12 @@ private int updateBookieIdInCookie(final String bookieId, final boolean useHostn for (File dir : ledgerDirectories) { newCookie.writeToDirectory(dir); } - LOG.info("Updated cookie file present in ledgerDirectories {}", ledgerDirectories); + LOG.info("Updated cookie file present in ledgerDirectories {}", (Object[]) ledgerDirectories); if (ledgerDirectories != indexDirectories) { for (File dir : indexDirectories) { newCookie.writeToDirectory(dir); } - LOG.info("Updated cookie file present in indexDirectories {}", indexDirectories); + LOG.info("Updated cookie file present in indexDirectories {}", (Object[]) indexDirectories); } } // writes newcookie to zookeeper diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java index 1eeed036de3..49c0b642944 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/AbstractConfiguration.java @@ -108,7 +108,6 @@ public abstract class AbstractConfiguration .description("Ledger Manager Class") .documentation("What kind of ledger manager is used to manage how ledgers are stored, managed and" + " garbage collected. Try to read 'BookKeeper Internals' for detail info.") - .defaultValue(HierarchicalLedgerManagerFactory.class) .group(GROUP_METADATA_SERVICE) .orderInGroup(2) .deprecated(true) @@ -1169,7 +1168,7 @@ public String getTLSCertificatePath() { * @return */ public T setTLSCertificatePath(String arg) { - TLS_CLIENT_AUTHENTICATION_KEY.set(this, arg); + TLS_CERTIFICATE_PATH_KEY.set(this, arg); return getThis(); } diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index fafc9b5d209..7b6bac48745 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -1032,7 +1032,6 @@ public String toString() { + " `diskUsageThreshold`. Because compaction, journal replays can still write data to disks" + " when a bookie is readonly.\n\n" + "Default value is 1.2 * `" + ENTRY_LOG_SIZE_LIMIT + "`.") - .validator(RangeValidator.atLeast(0L)) .defaultValueSupplier(conf -> 1.2 * ENTRY_LOG_SIZE_LIMIT_KEY.getLong(conf)) .group(GROUP_LEDGER_STORAGE) .orderInGroup(5) @@ -1575,11 +1574,11 @@ public String toString() { protected static final String OPEN_LEDGER_REREPLICATION_GRACE_PERIOD = "openLedgerRereplicationGracePeriod"; protected static final ConfigKey OPEN_LEDGER_REREPLICATION_GRACE_PERIOD_KEY = ConfigKey.builder(OPEN_LEDGER_REREPLICATION_GRACE_PERIOD) - .type(Type.INT) + .type(Type.LONG) .description("The grace period, in seconds, that the replication worker waits" + " before fencing and replicating a ledger fragment that's still being" + " written to upon bookie failure.") - .defaultValue(30) + .defaultValue(30L) .group(GROUP_REPLICATION_WORKER) .orderInGroup(100) .build(); @@ -1598,12 +1597,12 @@ public String toString() { protected static final String LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD = "lockReleaseOfFailedLedgerGracePeriod"; protected static final ConfigKey LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD_KEY = ConfigKey.builder(LOCK_RELEASE_OF_FAILED_LEDGER_GRACE_PERIOD) - .type(Type.INT) + .type(Type.LONG) .description("The grace period, in milliseconds, if the replication worker fails to replicate" + " a underreplicatedledger for more than `10` times, then instead of releasing the lock" + " immediately after failed attempt, it will hold under replicated ledger lock for this" + " grace period and then it will release the lock.") - .defaultValue(60000) + .defaultValue(60000L) .group(GROUP_REPLICATION_WORKER) .orderInGroup(102) .build(); @@ -1615,14 +1614,14 @@ public String toString() { protected static final String AUDITOR_PERIODIC_CHECK_INTERVAL = "auditorPeriodicCheckInterval"; protected static final ConfigKey AUDITOR_PERIODIC_CHECK_INTERVAL_KEY = ConfigKey.builder(AUDITOR_PERIODIC_CHECK_INTERVAL) - .type(Type.INT) + .type(Type.LONG) .description("The interval between auditor bookie checks, in seconds") .documentation("The auditor bookie check, checks ledger metadata to see which bookies should" + " contain entries for each ledger. If a bookie which should contain entries is " + " unavailable, then the ledger containing that entry is marked for recovery." + " Setting this to 0 disabled the periodic check. Bookie checks will still run when" + " a bookie fails") - .defaultValue(604800) + .defaultValue(604800L) .group(GROUP_AUDITOR) .orderInGroup(100) .build(); @@ -1630,11 +1629,11 @@ public String toString() { protected static final String AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL = "auditorPeriodicBookieCheckInterval"; protected static final ConfigKey AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL_KEY = ConfigKey.builder(AUDITOR_PERIODIC_BOOKIE_CHECK_INTERVAL) - .type(Type.INT) + .type(Type.LONG) .description("Interval at which the auditor will do a check of all ledgers in the cluster, in seconds") .documentation("To disable the periodic check completely, set this to 0. Note that periodic checking" + " will put extra load on the cluster, so it should not be run more frequently than once a day.") - .defaultValue(86400) + .defaultValue(86400L) .group(GROUP_AUDITOR) .orderInGroup(101) .build(); @@ -2118,7 +2117,7 @@ public int getMaxBackupJournals() { * @return server configuration */ public ServerConfiguration setMaxBackupJournals(int maxBackupJournals) { - MAX_JOURNAL_SIZE_KEY.set(this, maxBackupJournals); + MAX_BACKUP_JOURNALS_KEY.set(this, maxBackupJournals); return this; } @@ -2904,7 +2903,7 @@ public ServerConfiguration setIsForceGCAllowWhenNoSpace(boolean force) { * * @param waitTime time to wait before replicating ledger fragment */ - public void setOpenLedgerRereplicationGracePeriod(String waitTime) { + public void setOpenLedgerRereplicationGracePeriod(long waitTime) { OPEN_LEDGER_REREPLICATION_GRACE_PERIOD_KEY.set(this, waitTime); } @@ -3217,7 +3216,7 @@ public long getSkipListSizeLimit() { * @return server configuration object. */ public ServerConfiguration setSkipListSizeLimit(int size) { - SKIP_LIST_SIZE_LIMIT_KEY.set(this, size); + SKIP_LIST_SIZE_LIMIT_KEY.set(this, (long) size); return this; } diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java index 6e8cf324de8..16a9d89acf9 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookKeeperAdminTest.java @@ -66,7 +66,7 @@ public class BookKeeperAdminTest extends BookKeeperClusterTestCase { public BookKeeperAdminTest() { super(numOfBookies, 480); baseConf.setLostBookieRecoveryDelay(lostBookieRecoveryDelayInitValue); - baseConf.setOpenLedgerRereplicationGracePeriod(String.valueOf(30000)); + baseConf.setOpenLedgerRereplicationGracePeriod(30000L); setAutoRecoveryEnabled(true); } diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieDecommissionTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieDecommissionTest.java index 906db8f5cc8..2943e3036bf 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieDecommissionTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieDecommissionTest.java @@ -46,7 +46,7 @@ public class BookieDecommissionTest extends BookKeeperClusterTestCase { public BookieDecommissionTest() { super(NUM_OF_BOOKIES, 480); - baseConf.setOpenLedgerRereplicationGracePeriod(String.valueOf(30000)); + baseConf.setOpenLedgerRereplicationGracePeriod(30000L); setAutoRecoveryEnabled(true); } diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorPeriodicCheckTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorPeriodicCheckTest.java index fd97da31fe1..967c3b09abc 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorPeriodicCheckTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorPeriodicCheckTest.java @@ -87,7 +87,7 @@ public class AuditorPeriodicCheckTest extends BookKeeperClusterTestCase { private MetadataBookieDriver driver; private HashMap auditorElectors = new HashMap(); - private static final int CHECK_INTERVAL = 1; // run every second + private static final long CHECK_INTERVAL = 1L; // run every second public AuditorPeriodicCheckTest() { super(3); diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/BookieAutoRecoveryTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/BookieAutoRecoveryTest.java index 45cd2eb7e18..637bfdad792 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/BookieAutoRecoveryTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/BookieAutoRecoveryTest.java @@ -69,7 +69,7 @@ public class BookieAutoRecoveryTest extends BookKeeperClusterTestCase { .getLogger(BookieAutoRecoveryTest.class); private static final byte[] PASSWD = "admin".getBytes(); private static final byte[] data = "TESTDATA".getBytes(); - private static final String openLedgerRereplicationGracePeriod = "3000"; // milliseconds + private static final long openLedgerRereplicationGracePeriod = 3000L; // milliseconds private DigestType digestType; private MetadataClientDriver metadataClientDriver; diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java index c69581b3636..1543dc0535a 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/TestReplicationWorker.java @@ -404,7 +404,7 @@ public void testRWShouldReplicateTheLedgersAfterTimeoutIfLastFragmentIsUR() LOG.info("New Bookie addr : {}", newBkAddr); // set to 3s instead of default 30s - baseConf.setOpenLedgerRereplicationGracePeriod("3000"); + baseConf.setOpenLedgerRereplicationGracePeriod(3000L); ReplicationWorker rw = new ReplicationWorker(baseConf); @Cleanup MetadataClientDriver clientDriver = MetadataDrivers.getClientDriver( diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieJournalRollingTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieJournalRollingTest.java index 83d7ba174f0..1eb062bcbf7 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieJournalRollingTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieJournalRollingTest.java @@ -60,7 +60,7 @@ public BookieJournalRollingTest() { @Override public void setUp() throws Exception { // Set up the configuration properties needed. - baseConf.setMaxJournalSizeMB(1); + baseConf.setMaxJournalSizeMB(1L); baseConf.setMaxBackupJournals(1); super.setUp(); } From 3a64e4e5e162ff48acee73bffae0e85aea600573 Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Mon, 14 Jan 2019 09:53:07 +0900 Subject: [PATCH 4/6] Fix tlsKeyStoreType setting --- .../bookkeeper/conf/ServerConfiguration.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index 7b6bac48745..aed4e2a0927 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -4085,12 +4085,12 @@ public ServerConfiguration setNettyMaxFrameSizeBytes(int maxSize) { } /** - * Get the truststore type for client. Default is JKS. + * Get the keystore type for client. Default is JKS. * * @return */ - public String getTLSTrustStoreType() { - return TLS_TRUSTSTORE_TYPE_KEY.getString(this); + public String getTLSKeyStoreType() { + return TLS_KEYSTORE_TYPE_KEY.getString(this); } /** @@ -4099,7 +4099,7 @@ public String getTLSTrustStoreType() { * @return */ public ServerConfiguration setTLSKeyStoreType(String arg) { - TLS_TRUSTSTORE_TYPE_KEY.set(this, arg); + TLS_KEYSTORE_TYPE_KEY.set(this, arg); return this; } @@ -4142,12 +4142,12 @@ public ServerConfiguration setTLSKeyStorePasswordPath(String arg) { } /** - * Get the keystore type for client. Default is JKS. + * Get the truststore type for client. Default is JKS. * * @return */ - public String getTLSKeyStoreType() { - return TLS_KEYSTORE_TYPE_KEY.getString(this); + public String getTLSTrustStoreType() { + return TLS_TRUSTSTORE_TYPE_KEY.getString(this); } /** From 2da716425099e62cdf272e672fa1c1646b7d76b9 Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Mon, 14 Jan 2019 15:33:57 +0900 Subject: [PATCH 5/6] Fix wrong setting type --- .../java/org/apache/bookkeeper/conf/ServerConfiguration.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index aed4e2a0927..5560f6032e0 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -1641,11 +1641,11 @@ public String toString() { protected static final String AUDITOR_LEDGER_VERIFICATION_PERCENTAGE = "auditorLedgerVerificationPercentage"; protected static final ConfigKey AUDITOR_LEDGER_VERIFICATION_PERCENTAGE_KEY = ConfigKey.builder(AUDITOR_LEDGER_VERIFICATION_PERCENTAGE) - .type(Type.INT) + .type(Type.LONG) .description("The percentage of a ledger (fragment)'s entries will be verified before claiming this" + " fragment as missing fragment") .documentation("Default is 0, which only verify the first and last entries of a given fragment") - .defaultValue(0) + .defaultValue(0L) .group(GROUP_AUDITOR) .orderInGroup(102) .build(); From a10cc7e483cf71c94734deb83e84b962a067c9de Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Mon, 14 Jan 2019 15:47:05 +0900 Subject: [PATCH 6/6] Fix setting `entryLogPerLedgerCounterLimitsMultFactor` --- .../java/org/apache/bookkeeper/conf/ServerConfiguration.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java index 5560f6032e0..1e973e86444 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/conf/ServerConfiguration.java @@ -921,7 +921,6 @@ public String toString() { + " the entrylog file after the last addEntry call for that ledger, if explicit writeclose" + " for that ledger is not received") .defaultValue(300) - .validator(RangeValidator.atLeast(0)) .group(GROUP_LEDGER_STORAGE_ENTRY_LOGGER) .orderInGroup(7) .build(); @@ -4560,7 +4559,7 @@ public int getEntryLogPerLedgerCounterLimitsMultFactor() { */ public ServerConfiguration setEntryLogPerLedgerCounterLimitsMultFactor( int entryLogPerLedgerCounterLimitsMultFactor) { - ENTRYLOGMAP_ACCESS_EXPIRYTIME_INSECONDS_KEY.set(this, entryLogPerLedgerCounterLimitsMultFactor); + ENTRY_LOG_PER_LEDGER_COUNTER_LIMITS_MULT_FACTOR_KEY.set(this, entryLogPerLedgerCounterLimitsMultFactor); return this; }