From caa38c1354824a2da50a8fbc8fc85ba1b0dfc7fe Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 06 Oct 2015 14:43:56 +0000
Subject: [PATCH] OPENDJ-1719 Consider migrating JE backend to new PluggableBackend framework
---
opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/ConfigurableEnvironment.java | 340 ++++++++++++++++++++++++++++++--------------------------
1 files changed, 182 insertions(+), 158 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/ConfigurableEnvironment.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/ConfigurableEnvironment.java
index 49774fa..9437445 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/ConfigurableEnvironment.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/ConfigurableEnvironment.java
@@ -35,27 +35,31 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.admin.BooleanPropertyDefinition;
import org.opends.server.admin.DurationPropertyDefinition;
import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.std.meta.JEBackendCfgDefn;
import org.opends.server.admin.std.meta.LocalDBBackendCfgDefn;
+import org.opends.server.admin.std.server.BackendCfg;
+import org.opends.server.admin.std.server.JEBackendCfg;
import org.opends.server.admin.std.server.LocalDBBackendCfg;
import org.opends.server.config.ConfigConstants;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.MemoryQuota;
-import org.forgerock.opendj.config.server.ConfigException;
+import org.opends.server.types.DN;
+
import com.sleepycat.je.Durability;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.dbi.MemoryBudget;
import static com.sleepycat.je.EnvironmentConfig.*;
-import static org.opends.messages.ConfigMessages.*;
import static org.opends.messages.BackendMessages.*;
+import static org.opends.messages.ConfigMessages.*;
-/**
- * This class maps JE properties to configuration attributes.
- */
+/** This class maps JE properties to configuration attributes. */
public class ConfigurableEnvironment
{
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
@@ -109,10 +113,7 @@
public static final String ATTR_DATABASE_LOG_FILE_MAX =
ConfigConstants.NAME_PREFIX_CFG + "db-log-file-max";
- /**
- * The name of the attribute which configures the database cache eviction
- * algorithm.
- */
+ /** The name of the attribute which configures the database cache eviction algorithm. */
public static final String ATTR_EVICTOR_LRU_ONLY =
ConfigConstants.NAME_PREFIX_CFG + "db-evictor-lru-only";
@@ -150,14 +151,10 @@
public static final String ATTR_LOGGING_FILE_HANDLER_ON =
ConfigConstants.NAME_PREFIX_CFG + "db-logging-file-handler-on";
-
- /**
- * The name of the attribute which configures the trace logging message level.
- */
+ /** The name of the attribute which configures the trace logging message level. */
public static final String ATTR_LOGGING_LEVEL =
ConfigConstants.NAME_PREFIX_CFG + "db-logging-level";
-
/**
* The name of the attribute which configures how many bytes are written to
* the log before the checkpointer runs.
@@ -165,7 +162,6 @@
public static final String ATTR_CHECKPOINTER_BYTES_INTERVAL =
ConfigConstants.NAME_PREFIX_CFG + "db-checkpointer-bytes-interval";
-
/**
* The name of the attribute which configures the amount of time between
* runs of the checkpointer.
@@ -174,14 +170,10 @@
ConfigConstants.NAME_PREFIX_CFG +
"db-checkpointer-wakeup-interval";
-
- /**
- * The name of the attribute which configures the number of lock tables.
- */
+ /** The name of the attribute which configures the number of lock tables. */
public static final String ATTR_NUM_LOCK_TABLES =
ConfigConstants.NAME_PREFIX_CFG + "db-num-lock-tables";
-
/**
* The name of the attribute which configures the number threads
* allocated by the cleaner for log file processing.
@@ -189,36 +181,33 @@
public static final String ATTR_NUM_CLEANER_THREADS =
ConfigConstants.NAME_PREFIX_CFG + "db-num-cleaner-threads";
- /**
- * The name of the attribute which configures the size of the file
- * handle cache.
- */
+ /** The name of the attribute which configures the size of the file handle cache. */
public static final String ATTR_LOG_FILECACHE_SIZE =
ConfigConstants.NAME_PREFIX_CFG + "db-log-filecache-size";
-
- /**
- * The name of the attribute which may specify any native JE properties.
- */
+ /** The name of the attribute which may specify any native JE properties. */
public static final String ATTR_JE_PROPERTY =
ConfigConstants.NAME_PREFIX_CFG + "je-property";
-
/** A map of JE property names to the corresponding configuration attribute. */
private static HashMap<String, String> attrMap = new HashMap<>();
/**
- * A map of configuration attribute names to the corresponding configuration
- * object getter method.
+ * A map of configuration attribute names to the corresponding configuration object getter method.
*/
- private static HashMap<String, Method> methodMap = new HashMap<>();
+ @RemoveOnceLocalDBBackendIsPluggable
+ private static Map<String, Method> localDbMethodMap = new HashMap<>();
+ /** A map of configuration attribute names to the corresponding configuration PropertyDefinition. */
+ @RemoveOnceLocalDBBackendIsPluggable
+ private static Map<String, PropertyDefinition<?>> localDbDefnMap = new HashMap<>();
+
/**
- * A map of configuration attribute names to the corresponding configuration
- * PropertyDefinition.
+ * A map of configuration attribute names to the corresponding configuration object getter method.
*/
- private static HashMap<String, PropertyDefinition> defnMap = new HashMap<>();
+ private static Map<String, Method> jebMethodMap = new HashMap<>();
+ /** A map of configuration attribute names to the corresponding configuration PropertyDefinition. */
+ private static Map<String, PropertyDefinition<?>> jebDefnMap = new HashMap<>();
-
- /** Pulled from resource/admin/ABBREVIATIONS.xsl. db is mose common. */
+ /** Pulled from resource/admin/ABBREVIATIONS.xsl. db is mose common. */
private static final List<String> ABBREVIATIONS = Arrays.asList(new String[]
{"aci", "ip", "ssl", "dn", "rdn", "jmx", "smtp", "http",
"https", "ldap", "ldaps", "ldif", "jdbc", "tcp", "tls",
@@ -241,7 +230,6 @@
return buffer.toString();
}
-
/**
* Register a JE property and its corresponding configuration attribute.
*
@@ -255,32 +243,45 @@
{
// Strip off NAME_PREFIX_CFG.
String baseName = attrName.substring(7);
-
String methodBaseName = propNametoCamlCase(baseName);
+ registerLocalDbProp(attrName, methodBaseName);
+ registerJebProp(attrName, methodBaseName);
+ attrMap.put(propertyName, attrName);
+ }
+
+ @RemoveOnceLocalDBBackendIsPluggable
+ private static void registerLocalDbProp(String attrName, String methodBaseName) throws Exception
+ {
Class<LocalDBBackendCfg> configClass = LocalDBBackendCfg.class;
LocalDBBackendCfgDefn defn = LocalDBBackendCfgDefn.getInstance();
Class<? extends LocalDBBackendCfgDefn> defClass = defn.getClass();
- PropertyDefinition propDefn =
- (PropertyDefinition)defClass.getMethod("get" + methodBaseName +
- "PropertyDefinition").invoke(defn);
+ String propName = "get" + methodBaseName + "PropertyDefinition";
+ PropertyDefinition<?> propDefn = (PropertyDefinition<?>) defClass.getMethod(propName).invoke(defn);
- String methodName;
- if (propDefn instanceof BooleanPropertyDefinition)
- {
- methodName = "is" + methodBaseName;
- }
- else
- {
- methodName = "get" + methodBaseName;
- }
+ String methodPrefix = propDefn instanceof BooleanPropertyDefinition ? "is" : "get";
+ String methodName = methodPrefix + methodBaseName;
- defnMap.put(attrName, propDefn);
- methodMap.put(attrName, configClass.getMethod(methodName));
- attrMap.put(propertyName, attrName);
+ localDbDefnMap.put(attrName, propDefn);
+ localDbMethodMap.put(attrName, configClass.getMethod(methodName));
}
+ private static void registerJebProp(String attrName, String methodBaseName) throws Exception
+ {
+ Class<JEBackendCfg> configClass = JEBackendCfg.class;
+ JEBackendCfgDefn defn = JEBackendCfgDefn.getInstance();
+ Class<? extends JEBackendCfgDefn> defClass = defn.getClass();
+
+ String propName = "get" + methodBaseName + "PropertyDefinition";
+ PropertyDefinition<?> propDefn = (PropertyDefinition<?>) defClass.getMethod(propName).invoke(defn);
+
+ String methodPrefix = propDefn instanceof BooleanPropertyDefinition ? "is" : "get";
+ String methodName = methodPrefix + methodBaseName;
+
+ jebDefnMap.put(attrName, propDefn);
+ jebMethodMap.put(attrName, configClass.getMethod(methodName));
+ }
/**
* Get the name of the configuration attribute associated with a JE property.
@@ -295,15 +296,16 @@
/**
* Get the value of a JE property that is mapped to a configuration attribute.
* @param cfg The configuration containing the property values.
- * @param attrName The conriguration attribute type name.
+ * @param attrName The configuration attribute type name.
* @return The string value of the JE property.
*/
- private static String getPropertyValue(LocalDBBackendCfg cfg, String attrName)
+ private static String getPropertyValue(BackendCfg cfg, String attrName, ByteString backendId)
{
try
{
- PropertyDefinition propDefn = defnMap.get(attrName);
- Method method = methodMap.get(attrName);
+ final boolean isLocalDb = cfg instanceof LocalDBBackendCfg;
+ PropertyDefinition<?> propDefn = (isLocalDb ? localDbDefnMap : jebDefnMap).get(attrName);
+ Method method = (isLocalDb ? localDbMethodMap : jebMethodMap).get(attrName);
if (propDefn instanceof DurationPropertyDefinition)
{
@@ -329,7 +331,7 @@
value = Integer.valueOf(Math.max(24, cpus * 2));
logger.debug(INFO_ERGONOMIC_SIZING_OF_JE_CLEANER_THREADS,
- cfg.dn().rdn().getAttributeValue(0), (Number) value);
+ backendId, (Number) value);
}
else if (attrName.equals(ATTR_NUM_LOCK_TABLES)
&& value == null)
@@ -343,7 +345,7 @@
BigInteger tmp = BigInteger.valueOf((cleaners + workers) * 2);
value = tmp.nextProbablePrime();
- logger.debug(INFO_ERGONOMIC_SIZING_OF_JE_LOCK_TABLES, cfg.dn().rdn().getAttributeValue(0), (Number) value);
+ logger.debug(INFO_ERGONOMIC_SIZING_OF_JE_LOCK_TABLES, backendId, (Number) value);
}
return String.valueOf(value);
@@ -356,8 +358,6 @@
}
}
-
-
static
{
// Register the parameters that have JE property names.
@@ -387,8 +387,6 @@
}
}
-
-
/**
* Create a JE environment configuration with default values.
*
@@ -435,7 +433,28 @@
return envConfig;
}
+ /**
+ * Parse a configuration associated with a JE environment and create an
+ * environment config from it.
+ *
+ * @param cfg The configuration to be parsed.
+ * @return An environment config instance corresponding to the config entry.
+ * @throws ConfigException If there is an error in the provided configuration
+ * entry.
+ */
+ public static EnvironmentConfig parseConfigEntry(JEBackendCfg cfg) throws ConfigException
+ {
+ validateDbCacheSize(cfg.getDBCacheSize());
+ EnvironmentConfig envConfig = defaultConfig();
+ setDurability(envConfig, cfg.isDBTxnNoSync(), cfg.isDBTxnWriteNoSync());
+ setJEProperties(cfg, envConfig, cfg.dn().rdn().getAttributeValue(0));
+ setDBLoggingLevel(envConfig, cfg.getDBLoggingLevel(), cfg.dn(), cfg.isDBLoggingFileHandlerOn());
+
+ // See if there are any native JE properties specified in the config
+ // and if so try to parse, evaluate and set them.
+ return setJEProperties(envConfig, cfg.getJEProperty(), attrMap);
+ }
/**
* Parse a configuration associated with a JE environment and create an
@@ -446,77 +465,89 @@
* @throws ConfigException If there is an error in the provided configuration
* entry.
*/
- public static EnvironmentConfig parseConfigEntry(LocalDBBackendCfg cfg)
- throws ConfigException
+ @RemoveOnceLocalDBBackendIsPluggable
+ public static EnvironmentConfig parseConfigEntry(LocalDBBackendCfg cfg) throws ConfigException
{
- // See if the db cache size setting is valid.
- if(cfg.getDBCacheSize() != 0)
- {
- if (MemoryBudget.getRuntimeMaxMemory() < cfg.getDBCacheSize()) {
- throw new ConfigException(
- ERR_BACKEND_CONFIG_CACHE_SIZE_GREATER_THAN_JVM_HEAP.get(
- cfg.getDBCacheSize(), MemoryBudget.getRuntimeMaxMemory()));
- }
- if (cfg.getDBCacheSize() < MemoryBudget.MIN_MAX_MEMORY_SIZE) {
- throw new ConfigException(
- ERR_CONFIG_JEB_CACHE_SIZE_TOO_SMALL.get(
- cfg.getDBCacheSize(), MemoryBudget.MIN_MAX_MEMORY_SIZE));
- }
- MemoryQuota memoryQuota = DirectoryServer.getInstance().getServerContext().getMemoryQuota();
- if (!memoryQuota.acquireMemory(cfg.getDBCacheSize()))
- {
- logger.warn(ERR_BACKEND_CONFIG_CACHE_SIZE_GREATER_THAN_JVM_HEAP.get(
- cfg.getDBCacheSize(), memoryQuota.getMaxMemory()));
- }
- }
+ validateDbCacheSize(cfg.getDBCacheSize());
EnvironmentConfig envConfig = defaultConfig();
-
- // Durability settings.
- if (cfg.isDBTxnNoSync() && cfg.isDBTxnWriteNoSync())
- {
- throw new ConfigException(
- ERR_CONFIG_JEB_DURABILITY_CONFLICT.get());
- }
- if (cfg.isDBTxnNoSync())
- {
- envConfig.setDurability(Durability.COMMIT_NO_SYNC);
- }
- if (cfg.isDBTxnWriteNoSync())
- {
- envConfig.setDurability(Durability.COMMIT_WRITE_NO_SYNC);
- }
-
- // Iterate through the config attributes associated with a JE property.
- for (Map.Entry<String, String> mapEntry : attrMap.entrySet())
- {
- String jeProperty = mapEntry.getKey();
- String attrName = mapEntry.getValue();
-
- String value = getPropertyValue(cfg, attrName);
- envConfig.setConfigParam(jeProperty, value);
- }
-
- // Set logging and file handler levels.
- Logger parent = Logger.getLogger("com.sleepycat.je");
- try
- {
- parent.setLevel(Level.parse(cfg.getDBLoggingLevel()));
- }
- catch (Exception e)
- {
- throw new ConfigException(ERR_JEB_INVALID_LOGGING_LEVEL.get(cfg.getDBLoggingLevel(), cfg.dn()));
- }
-
- final Level level = cfg.isDBLoggingFileHandlerOn() ? Level.ALL : Level.OFF;
- envConfig.setConfigParam(FILE_LOGGING_LEVEL, level.getName());
+ setDurability(envConfig, cfg.isDBTxnNoSync(), cfg.isDBTxnWriteNoSync());
+ setJEProperties(cfg, envConfig, cfg.dn().rdn().getAttributeValue(0));
+ setDBLoggingLevel(envConfig, cfg.getDBLoggingLevel(), cfg.dn(), cfg.isDBLoggingFileHandlerOn());
// See if there are any native JE properties specified in the config
// and if so try to parse, evaluate and set them.
return setJEProperties(envConfig, cfg.getJEProperty(), attrMap);
}
+ private static void validateDbCacheSize(long dbCacheSize) throws ConfigException
+ {
+ if (dbCacheSize != 0)
+ {
+ if (MemoryBudget.getRuntimeMaxMemory() < dbCacheSize)
+ {
+ throw new ConfigException(ERR_BACKEND_CONFIG_CACHE_SIZE_GREATER_THAN_JVM_HEAP.get(
+ dbCacheSize, MemoryBudget.getRuntimeMaxMemory()));
+ }
+ if (dbCacheSize < MemoryBudget.MIN_MAX_MEMORY_SIZE)
+ {
+ throw new ConfigException(ERR_CONFIG_JEB_CACHE_SIZE_TOO_SMALL.get(
+ dbCacheSize, MemoryBudget.MIN_MAX_MEMORY_SIZE));
+ }
+ MemoryQuota memoryQuota = DirectoryServer.getInstance().getServerContext().getMemoryQuota();
+ if (!memoryQuota.acquireMemory(dbCacheSize))
+ {
+ logger.warn(ERR_BACKEND_CONFIG_CACHE_SIZE_GREATER_THAN_JVM_HEAP.get(
+ dbCacheSize, memoryQuota.getMaxMemory()));
+ }
+ }
+ }
+ private static void setDurability(EnvironmentConfig envConfig, boolean dbTxnNoSync, boolean dbTxnWriteNoSync)
+ throws ConfigException
+ {
+ if (dbTxnNoSync && dbTxnWriteNoSync)
+ {
+ throw new ConfigException(ERR_CONFIG_JEB_DURABILITY_CONFLICT.get());
+ }
+ if (dbTxnNoSync)
+ {
+ envConfig.setDurability(Durability.COMMIT_NO_SYNC);
+ }
+ else if (dbTxnWriteNoSync)
+ {
+ envConfig.setDurability(Durability.COMMIT_WRITE_NO_SYNC);
+ }
+ }
+
+ private static void setJEProperties(BackendCfg cfg, EnvironmentConfig envConfig, ByteString backendId)
+ {
+ for (Map.Entry<String, String> mapEntry : attrMap.entrySet())
+ {
+ String jeProperty = mapEntry.getKey();
+ String attrName = mapEntry.getValue();
+
+ String value = getPropertyValue(cfg, attrName, backendId);
+ envConfig.setConfigParam(jeProperty, value);
+ }
+ }
+
+ private static void setDBLoggingLevel(EnvironmentConfig envConfig, String loggingLevel, DN dn,
+ boolean loggingFileHandlerOn) throws ConfigException
+ {
+ Logger parent = Logger.getLogger("com.sleepycat.je");
+ try
+ {
+ parent.setLevel(Level.parse(loggingLevel));
+ }
+ catch (Exception e)
+ {
+ throw new ConfigException(ERR_JEB_INVALID_LOGGING_LEVEL.get(loggingLevel, dn));
+ }
+
+ final Level level = loggingFileHandlerOn ? Level.ALL : Level.OFF;
+ envConfig.setConfigParam(FILE_LOGGING_LEVEL, level.getName());
+ }
/**
* Parse, validate and set native JE environment properties for
@@ -549,43 +580,36 @@
for (String jeEntry : jeProperties)
{
StringTokenizer st = new StringTokenizer(jeEntry, "=");
- if (st.countTokens() == 2) {
- String jePropertyName = st.nextToken();
- String jePropertyValue = st.nextToken();
- // Check if it is a duplicate.
- if (uniqueJEProperties.contains(jePropertyName)) {
- LocalizableMessage message = ERR_CONFIG_JE_DUPLICATE_PROPERTY.get(
- jePropertyName);
- throw new ConfigException(message);
+ if (st.countTokens() != 2)
+ {
+ throw new ConfigException(ERR_CONFIG_JE_PROPERTY_INVALID_FORM.get(jeEntry));
+ }
+
+ String jePropertyName = st.nextToken();
+ String jePropertyValue = st.nextToken();
+ // Check if it is a duplicate.
+ if (uniqueJEProperties.contains(jePropertyName)) {
+ throw new ConfigException(ERR_CONFIG_JE_DUPLICATE_PROPERTY.get(jePropertyName));
+ }
+
+ // Set JE property.
+ try {
+ envConfig.setConfigParam(jePropertyName, jePropertyValue);
+ // If this property shadows an existing config attribute.
+ if (configAttrMap.containsKey(jePropertyName)) {
+ LocalizableMessage message = ERR_CONFIG_JE_PROPERTY_SHADOWS_CONFIG.get(
+ jePropertyName, attrMap.get(jePropertyName));
+ throw new ConfigException(message);
}
- // Set JE property.
- try {
- envConfig.setConfigParam(jePropertyName, jePropertyValue);
- // If this property shadows an existing config attribute.
- if (configAttrMap.containsKey(jePropertyName)) {
- LocalizableMessage message = ERR_CONFIG_JE_PROPERTY_SHADOWS_CONFIG.get(
- jePropertyName, attrMap.get(jePropertyName));
- throw new ConfigException(message);
- }
- // Add this property to unique set.
- uniqueJEProperties.add(jePropertyName);
- } catch(IllegalArgumentException e) {
- logger.traceException(e);
- LocalizableMessage message =
- ERR_CONFIG_JE_PROPERTY_INVALID.get(
- jeEntry, e.getMessage());
- throw new ConfigException(message, e.getCause());
- }
- } else {
- LocalizableMessage message =
- ERR_CONFIG_JE_PROPERTY_INVALID_FORM.get(jeEntry);
- throw new ConfigException(message);
+ // Add this property to unique set.
+ uniqueJEProperties.add(jePropertyName);
+ } catch(IllegalArgumentException e) {
+ logger.traceException(e);
+ LocalizableMessage message = ERR_CONFIG_JE_PROPERTY_INVALID.get(jeEntry, e.getMessage());
+ throw new ConfigException(message, e.getCause());
}
}
return envConfig;
}
-
-
-
}
--
Gitblit v1.10.0