Author: mreutegg
Date: Mon Nov 27 09:12:21 2017
New Revision: 1816417
URL: http://svn.apache.org/viewvc?rev=1816417&view=rev
Log:
OAK-6917: Configuration presets for DocumentNodeStoreService
Added:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfiguration.java
(with props)
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobGCRegistrationTest.java
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobTrackerRegistrationTest.java
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentCachingDataStoreStatsTest.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobGCRegistrationTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobGCRegistrationTest.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobGCRegistrationTest.java
(original)
+++
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobGCRegistrationTest.java
Mon Nov 27 09:12:21 2017
@@ -55,7 +55,10 @@ public class DocumentBlobGCRegistrationT
properties.put("repository.home", repoHome);
properties.put("mongouri", MongoUtils.URL);
properties.put("db", MongoUtils.DB);
- service = context.registerInjectActivateService(new
DocumentNodeStoreService(), properties);
+ MockOsgi.setConfigForPid(context.bundleContext(),
+ DocumentNodeStoreService.class.getName(), properties);
+ context.registerInjectActivateService(new
DocumentNodeStoreService.Preset());
+ service = context.registerInjectActivateService(new
DocumentNodeStoreService());
}
@Override
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobTrackerRegistrationTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobTrackerRegistrationTest.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobTrackerRegistrationTest.java
(original)
+++
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/blob/DocumentBlobTrackerRegistrationTest.java
Mon Nov 27 09:12:21 2017
@@ -23,7 +23,9 @@ import java.util.Map;
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService;
import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.junit.After;
+import org.junit.Before;
import org.junit.BeforeClass;
import static com.google.common.collect.Maps.newHashMap;
@@ -42,6 +44,11 @@ public class DocumentBlobTrackerRegistra
assumeTrue(MongoUtils.isAvailable());
}
+ @Before
+ public void registerPreset() {
+ context.registerInjectActivateService(new
DocumentNodeStoreService.Preset());
+ }
+
@After
@Override
public void tearDown() throws Exception {
@@ -57,7 +64,9 @@ public class DocumentBlobTrackerRegistra
properties.put("repository.home", repoHome);
properties.put("mongouri", MongoUtils.URL);
properties.put("db", MongoUtils.DB);
- service = context.registerInjectActivateService(new
DocumentNodeStoreService(), properties);
+ MockOsgi.setConfigForPid(context.bundleContext(),
+ DocumentNodeStoreService.class.getName(), properties);
+ service = context.registerInjectActivateService(new
DocumentNodeStoreService());
}
@Override
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentCachingDataStoreStatsTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentCachingDataStoreStatsTest.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentCachingDataStoreStatsTest.java
(original)
+++
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentCachingDataStoreStatsTest.java
Mon Nov 27 09:12:21 2017
@@ -28,6 +28,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.apache.sling.testing.mock.osgi.ReferenceViolationException;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.After;
@@ -128,6 +129,9 @@ public class DocumentCachingDataStoreSta
properties.put("db", MongoUtils.DB);
properties.put("repository.home", repoHome);
properties.put(DocumentNodeStoreService.CUSTOM_BLOB_STORE,
customBlobStore);
+ MockOsgi.setConfigForPid(context.bundleContext(),
+ DocumentNodeStoreService.class.getName(), properties);
+ context.registerInjectActivateService(new
DocumentNodeStoreService.Preset());
documentNodeStoreService =
context.registerInjectActivateService(new
DocumentNodeStoreService(), properties);
}
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
Mon Nov 27 09:12:21 2017
@@ -23,14 +23,17 @@ import org.osgi.service.metatype.annotat
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
+import static org.apache.jackrabbit.oak.plugins.document.Configuration.PID;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CACHE_SEGMENT_COUNT;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CACHE_STACK_MOVE_DISTANCE;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CHILDREN_CACHE_PERCENTAGE;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_DIFF_CACHE_PERCENTAGE;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_NODE_CACHE_PERCENTAGE;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_UPDATE_LIMIT;
@ObjectClassDefinition(
+ pid = {PID},
name = "Apache Jackrabbit Oak Document NodeStore Service",
description = "NodeStore implementation based on Document model. For
configuration option refer " +
"to
http://jackrabbit.apache.org/oak/docs/osgi_config.html#DocumentNodeStore. Note
that for system " +
@@ -38,6 +41,11 @@ import static org.apache.jackrabbit.oak.
"should be done via file system based config file and this
view should ONLY be used to determine which " +
"options are supported")
@interface Configuration {
+
+ String PID =
"org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService";
+
+ String PRESET_PID = PID + "Preset";
+
@AttributeDefinition(
name = "Mongo URI",
description = "Mongo connection URI used to connect to Mongo.
Refer to " +
@@ -121,7 +129,7 @@ import static org.apache.jackrabbit.oak.
name = "Custom BlobStore",
description = "Boolean value indicating that a custom BlobStore is
to be used. " +
"By default, for MongoDB, MongoBlobStore is used; for RDB,
RDBBlobStore is used.")
- boolean customBlobStore() default false;
+ boolean customBlobStore() default
DocumentNodeStoreService.DEFAULT_CUSTOM_BLOB_STORE;
@AttributeDefinition(
@@ -141,7 +149,7 @@ import static org.apache.jackrabbit.oak.
name = "Pre-fetch external changes",
description = "Boolean value indicating if external changes should
" +
"be pre-fetched in a background thread.")
- boolean prefetchExternalChanges() default false;
+ boolean prefetchExternalChanges() default
DocumentNodeStoreService.DEFAULT_PREFETCH_EXTERNAL_CHANGES;
@AttributeDefinition(
name = "NodeStoreProvider role",
@@ -168,7 +176,7 @@ import static org.apache.jackrabbit.oak.
"expression triggers a GC run every night at 2 AM: '" +
DocumentNodeStoreService.CLASSIC_RGC_EXPR + "'."
)
- String versionGCExpression() default "";
+ String versionGCExpression() default
DocumentNodeStoreService.DEFAULT_VER_GC_EXPRESSION;
@AttributeDefinition(
name = "Time limit for a Version GC run (in sec)",
@@ -225,7 +233,7 @@ import static org.apache.jackrabbit.oak.
name = "DocumentNodeStore update.limit",
description = "Number of content updates that need to happen
before " +
"the updates are automatically purged to the private
branch.")
- int updateLimit();
+ int updateLimit() default DEFAULT_UPDATE_LIMIT;
@AttributeDefinition(
name = "Persistent Cache Includes",
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
Mon Nov 27 09:12:21 2017
@@ -22,6 +22,7 @@ import static com.google.common.base.Sup
import static com.google.common.base.Suppliers.ofInstance;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
+import static
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreServiceConfiguration.PROP_UPDATE_LIMIT;
import static
org.apache.jackrabbit.oak.plugins.document.util.MongoConnection.readConcernLevel;
import java.io.InputStream;
@@ -145,7 +146,7 @@ public class DocumentMK {
* Number of content updates that need to happen before the updates
* are automatically purged to the private branch.
*/
- static final int UPDATE_LIMIT = Integer.getInteger("update.limit", 100000);
+ static final int UPDATE_LIMIT = Integer.getInteger("update.limit",
Builder.DEFAULT_UPDATE_LIMIT);
/**
* The node store.
@@ -561,6 +562,7 @@ public class DocumentMK {
public static final int DEFAULT_DIFF_CACHE_PERCENTAGE = 30;
public static final int DEFAULT_CACHE_SEGMENT_COUNT = 16;
public static final int DEFAULT_CACHE_STACK_MOVE_DISTANCE = 16;
+ public static final int DEFAULT_UPDATE_LIMIT = 100000;
private DocumentNodeStore nodeStore;
private Supplier<DocumentStore> documentStoreSupplier = ofInstance(new
MemoryDocumentStore());
private String mongoUri;
Modified:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
Mon Nov 27 09:12:21 2017
@@ -22,16 +22,8 @@ import static com.google.common.base.Pre
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.emptyList;
import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
-import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toBoolean;
-import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toInteger;
import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toLong;
-import static
org.apache.jackrabbit.oak.osgi.OsgiUtil.lookupFrameworkThenConfiguration;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CACHE_SEGMENT_COUNT;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CACHE_STACK_MOVE_DISTANCE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_CHILDREN_CACHE_PERCENTAGE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_DIFF_CACHE_PERCENTAGE;
import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_MEMORY_CACHE_SIZE;
-import static
org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_NODE_CACHE_PERCENTAGE;
import static
org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS_RESOLUTION;
import static
org.apache.jackrabbit.oak.spi.blob.osgi.SplitBlobStoreService.ONLY_STANDALONE_TARGET;
import static
org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean;
@@ -70,7 +62,6 @@ import org.apache.jackrabbit.oak.api.jmx
import org.apache.jackrabbit.oak.api.jmx.CheckpointMBean;
import org.apache.jackrabbit.oak.api.jmx.PersistentCacheStatsMBean;
import org.apache.jackrabbit.oak.cache.CacheStats;
-import org.apache.jackrabbit.oak.commons.PropertiesUtil;
import
org.apache.jackrabbit.oak.plugins.document.VersionGarbageCollector.VersionGCStats;
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.apache.jackrabbit.oak.spi.commit.ObserverTracker;
@@ -112,6 +103,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@@ -120,7 +112,6 @@ import org.osgi.service.component.annota
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
-import org.osgi.service.metatype.annotations.Designate;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -130,8 +121,7 @@ import org.slf4j.LoggerFactory;
*/
@Component(
configurationPolicy = ConfigurationPolicy.REQUIRE,
- service = {})
-@Designate(ocd = Configuration.class)
+ configurationPid = {Configuration.PID})
public class DocumentNodeStoreService {
private static final long MB = 1024 * 1024;
@@ -142,16 +132,18 @@ public class DocumentNodeStoreService {
static final boolean DEFAULT_SO_KEEP_ALIVE = false;
static final String DEFAULT_PERSISTENT_CACHE = "cache,binary=0";
static final String DEFAULT_JOURNAL_CACHE = "diff-cache";
+ static final boolean DEFAULT_CUSTOM_BLOB_STORE = false;
public static final String CONTINUOUS_RGC_EXPR = "*/5 * * * * ?";
public static final String CLASSIC_RGC_EXPR = "0 0 2 * * ?";
public static final long DEFAULT_RGC_TIME_LIMIT_SECS = 3*60*60; // default
is 3 hours
- private static final String PREFIX = "oak.documentstore.";
private static final String DESCRIPTION = "oak.nodestore.description";
static final long DEFAULT_JOURNAL_GC_INTERVAL_MILLIS = 5*60*1000; //
default is 5min
static final long DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS = 24*60*60*1000; //
default is 24hours
+ static final boolean DEFAULT_PREFETCH_EXTERNAL_CHANGES = false;
private static final String DEFAULT_PROP_HOME = "./repository";
static final long DEFAULT_MAX_REPLICATION_LAG = 6 * 60 * 60;
static final boolean DEFAULT_BUNDLING_DISABLED = false;
+ static final String DEFAULT_VER_GC_EXPRESSION = "";
/**
* Revisions older than this time would be garbage collected
@@ -169,55 +161,12 @@ public class DocumentNodeStoreService {
*/
static final long DEFAULT_BLOB_SNAPSHOT_INTERVAL = 12 * 60 * 60;
- /**
- * Name of framework property to configure Mongo Connection URI
- */
- private static final String FWK_PROP_URI = "oak.mongo.uri";
-
- /**
- * Name of framework property to configure Mongo Database name
- * to use
- */
- private static final String FWK_PROP_DB = "oak.mongo.db";
-
- /**
- * Name of framework property to configure socket keep-alive for MongoDB
- */
- private static final String FWK_PROP_SO_KEEP_ALIVE =
"oak.mongo.socketKeepAlive";
-
-
// property name constants - values can come from framework properties or
OSGi config
- private static final String PROP_URI = "mongouri";
- private static final String PROP_DB = "db";
- static final String PROP_SO_KEEP_ALIVE = "socketKeepAlive";
- private static final String PROP_CACHE = "cache";
- private static final String PROP_NODE_CACHE_PERCENTAGE =
"nodeCachePercentage";
- private static final String PROP_PREV_DOC_CACHE_PERCENTAGE =
"prevDocCachePercentage";
- private static final String PROP_CHILDREN_CACHE_PERCENTAGE =
"childrenCachePercentage";
- private static final String PROP_DIFF_CACHE_PERCENTAGE =
"diffCachePercentage";
- private static final String PROP_CACHE_SEGMENT_COUNT = "cacheSegmentCount";
- private static final String PROP_CACHE_STACK_MOVE_DISTANCE =
"cacheStackMoveDistance";
- private static final String PROP_BLOB_CACHE_SIZE = "blobCacheSize";
- private static final String PROP_PERSISTENT_CACHE = "persistentCache";
- private static final String PROP_JOURNAL_CACHE = "journalCache";
- public static final String PROP_PREFETCH_EXTERNAL_CHANGES =
"prefetchExternalChanges";
- private static final String PROP_JOURNAL_GC_MAX_AGE_MILLIS =
"journalGCMaxAge";
public static final String CUSTOM_BLOB_STORE = "customBlobStore";
- public static final String PROP_VER_GC_MAX_AGE = "versionGcMaxAgeInSecs";
- public static final String PROP_VER_GC_EXPRESSION = "versionGCExpression";
- public static final String PROP_VER_GC_TIME_LIMIT =
"versionGCTimeLimitInSecs";
public static final String PROP_REV_RECOVERY_INTERVAL =
"lastRevRecoveryJobIntervalInSecs";
- public static final String PROP_BLOB_GC_MAX_AGE = "blobGcMaxAgeInSecs";
- public static final String PROP_BLOB_SNAPSHOT_INTERVAL =
"blobTrackSnapshotIntervalInSecs";
- private static final String PROP_HOME = "repository.home";
- public static final String PROP_REPLICATION_LAG =
"maxReplicationLagInSecs";
public static final String PROP_DS_TYPE = "documentStoreType";
- private static final String PROP_BUNDLING_DISABLED = "bundlingDisabled";
- public static final String PROP_UPDATE_LIMIT = "updateLimit";
- public static final String PROP_ROLE = "role";
- private static final String PROP_JOURNAL_GC_INTERVAL_MILLIS =
"journalGCInterval";
- private static enum DocumentStoreType {
+ private enum DocumentStoreType {
MONGO, RDB;
static DocumentStoreType fromString(String type) {
@@ -248,30 +197,35 @@ public class DocumentNodeStoreService {
private ComponentContext context;
private Whiteboard whiteboard;
private long deactivationTimestamp = 0;
- private long maxReplicationLagInSecs;
@Reference
private StatisticsProvider statisticsProvider;
+ @Reference
+ private ConfigurationAdmin configurationAdmin;
+
+ @Reference(service = Preset.class)
+ private Preset preset;
+
private boolean customBlobStore;
private ServiceRegistration blobStoreReg;
private BlobStore defaultBlobStore;
- private volatile Configuration config;
+ private Configuration config;
@Activate
protected void activate(ComponentContext context, Configuration config)
throws Exception {
closer = Closer.create();
- this.config = config;
+ this.config = DocumentNodeStoreServiceConfiguration.create(context,
+ configurationAdmin, preset.configuration, config);
this.context = context;
whiteboard = new OsgiWhiteboard(context.getBundleContext());
executor = new WhiteboardExecutor();
executor.start(whiteboard);
- maxReplicationLagInSecs = config.maxReplicationLagInSecs();
- customBlobStore = toBoolean(prop(CUSTOM_BLOB_STORE), false);
- documentStoreType =
DocumentStoreType.fromString(config.documentStoreType());
+ customBlobStore = this.config.customBlobStore();
+ documentStoreType =
DocumentStoreType.fromString(this.config.documentStoreType());
registerNodeStoreIfPossible();
}
@@ -294,37 +248,21 @@ public class DocumentNodeStoreService {
}
private void registerNodeStore() throws IOException {
- String uri = PropertiesUtil.toString(prop(PROP_URI, FWK_PROP_URI),
DEFAULT_URI);
- String db = PropertiesUtil.toString(prop(PROP_DB, FWK_PROP_DB),
DEFAULT_DB);
- boolean soKeepAlive =
PropertiesUtil.toBoolean(prop(PROP_SO_KEEP_ALIVE, FWK_PROP_SO_KEEP_ALIVE),
DEFAULT_SO_KEEP_ALIVE);
-
- int cacheSize = toInteger(prop(PROP_CACHE), DEFAULT_CACHE);
- int nodeCachePercentage = toInteger(prop(PROP_NODE_CACHE_PERCENTAGE),
DEFAULT_NODE_CACHE_PERCENTAGE);
- int prevDocCachePercentage =
toInteger(prop(PROP_PREV_DOC_CACHE_PERCENTAGE), DEFAULT_NODE_CACHE_PERCENTAGE);
- int childrenCachePercentage =
toInteger(prop(PROP_CHILDREN_CACHE_PERCENTAGE),
DEFAULT_CHILDREN_CACHE_PERCENTAGE);
- int diffCachePercentage = toInteger(prop(PROP_DIFF_CACHE_PERCENTAGE),
DEFAULT_DIFF_CACHE_PERCENTAGE);
- int blobCacheSize = toInteger(prop(PROP_BLOB_CACHE_SIZE),
DEFAULT_BLOB_CACHE_SIZE);
- String persistentCache = getPath(PROP_PERSISTENT_CACHE,
DEFAULT_PERSISTENT_CACHE);
- String journalCache = getPath(PROP_JOURNAL_CACHE,
DEFAULT_JOURNAL_CACHE);
- int cacheSegmentCount = toInteger(prop(PROP_CACHE_SEGMENT_COUNT),
DEFAULT_CACHE_SEGMENT_COUNT);
- int cacheStackMoveDistance =
toInteger(prop(PROP_CACHE_STACK_MOVE_DISTANCE),
DEFAULT_CACHE_STACK_MOVE_DISTANCE);
- boolean bundlingDisabled = toBoolean(prop(PROP_BUNDLING_DISABLED),
DEFAULT_BUNDLING_DISABLED);
- boolean prefetchExternalChanges =
toBoolean(prop(PROP_PREFETCH_EXTERNAL_CHANGES), false);
- int updateLimit = toInteger(prop(PROP_UPDATE_LIMIT),
DocumentMK.UPDATE_LIMIT);
- long journalGCMaxAge =
toLong(context.getProperties().get(PROP_JOURNAL_GC_MAX_AGE_MILLIS),
DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS);
+ String persistentCache = resolvePath(config.persistentCache(),
DEFAULT_PERSISTENT_CACHE);
+ String journalCache = resolvePath(config.journalCache(),
DEFAULT_JOURNAL_CACHE);
DocumentMK.Builder mkBuilder =
new DocumentMK.Builder().
setStatisticsProvider(statisticsProvider).
- memoryCacheSize(cacheSize * MB).
+ memoryCacheSize(config.cache() * MB).
memoryCacheDistribution(
- nodeCachePercentage,
- prevDocCachePercentage,
- childrenCachePercentage,
- diffCachePercentage).
- setCacheSegmentCount(cacheSegmentCount).
- setCacheStackMoveDistance(cacheStackMoveDistance).
- setBundlingDisabled(bundlingDisabled).
-
setJournalPropertyHandlerFactory(journalPropertyHandlerFactory).
+ config.nodeCachePercentage(),
+ config.prevDocCachePercentage(),
+ config.childrenCachePercentage(),
+ config.diffCachePercentage()).
+ setCacheSegmentCount(config.cacheSegmentCount()).
+ setCacheStackMoveDistance(config.cacheStackMoveDistance()).
+ setBundlingDisabled(config.bundlingDisabled()).
+
setJournalPropertyHandlerFactory(journalPropertyHandlerFactory).
setLeaseCheck(!ClusterNodeInfo.DEFAULT_LEASE_CHECK_DISABLED /*
OAK-2739: enabled by default */).
setLeaseFailureHandler(new LeaseFailureHandler() {
@@ -347,9 +285,9 @@ public class DocumentNodeStoreService {
}
}
}).
- setPrefetchExternalChanges(prefetchExternalChanges).
- setUpdateLimit(updateLimit).
- setJournalGCMaxAge(journalGCMaxAge).
+ setPrefetchExternalChanges(config.prefetchExternalChanges()).
+ setUpdateLimit(config.updateLimit()).
+ setJournalGCMaxAge(config.journalGCMaxAge()).
setNodeCachePredicate(createCachePredicate());
if (!Strings.isNullOrEmpty(persistentCache)) {
@@ -382,6 +320,10 @@ public class DocumentNodeStoreService {
log.info("Connected to datasource {}", dataSource);
}
} else {
+ String uri = config.mongouri();
+ String db = config.db();
+ boolean soKeepAlive = config.socketKeepAlive();
+
MongoClientURI mongoURI = new MongoClientURI(uri);
if (log.isInfoEnabled()) {
@@ -389,14 +331,14 @@ public class DocumentNodeStoreService {
// might contain passwords
log.info("Starting DocumentNodeStore with host={}, db={},
cache size (MB)={}, persistentCache={}, " +
"journalCache={}, blobCacheSize (MB)={},
maxReplicationLagInSecs={}",
- mongoURI.getHosts(), db, cacheSize, persistentCache,
- journalCache, blobCacheSize, maxReplicationLagInSecs);
+ mongoURI.getHosts(), db, config.cache(),
persistentCache,
+ journalCache, config.blobCacheSize(),
config.maxReplicationLagInSecs());
log.info("Mongo Connection details {}",
MongoConnection.toString(mongoURI.getOptions()));
}
- mkBuilder.setMaxReplicationLag(maxReplicationLagInSecs,
TimeUnit.SECONDS);
+ mkBuilder.setMaxReplicationLag(config.maxReplicationLagInSecs(),
TimeUnit.SECONDS);
mkBuilder.setSocketKeepAlive(soKeepAlive);
- mkBuilder.setMongoDB(uri, db, blobCacheSize);
+ mkBuilder.setMongoDB(uri, db, config.blobCacheSize());
log.info("Connected to database '{}'", db);
}
@@ -453,17 +395,14 @@ public class DocumentNodeStoreService {
}
if (blobStore instanceof BlobTrackingStore) {
- final long trackSnapshotInterval =
toLong(prop(PROP_BLOB_SNAPSHOT_INTERVAL),
- DEFAULT_BLOB_SNAPSHOT_INTERVAL);
- String root = getRepositoryHome();
-
BlobTrackingStore trackingStore = (BlobTrackingStore)
blobStore;
if (trackingStore.getTracker() != null) {
trackingStore.getTracker().close();
}
((BlobTrackingStore) blobStore).addTracker(
- new BlobIdTracker(root, repoId, trackSnapshotInterval,
(SharedDataStore)
- blobStore));
+ new BlobIdTracker(getRepositoryHome(), repoId,
+ config.blobTrackSnapshotIntervalInSecs(),
+ (SharedDataStore) blobStore));
}
}
@@ -545,7 +484,7 @@ public class DocumentNodeStoreService {
}
private boolean isNodeStoreProvider() {
- return prop(PROP_ROLE) != null;
+ return !Strings.isNullOrEmpty(config.role());
}
private boolean isContinuousRevisionGC() {
@@ -562,8 +501,8 @@ public class DocumentNodeStoreService {
} else {
defaultExpr = "";
}
- String expr = PropertiesUtil.toString(prop(PROP_VER_GC_EXPRESSION),
"");
- if (expr.isEmpty()) {
+ String expr = config.versionGCExpression();
+ if (Strings.isNullOrEmpty(expr)) {
expr = defaultExpr;
}
// validate expression
@@ -579,14 +518,11 @@ public class DocumentNodeStoreService {
}
private void registerNodeStoreProvider(final NodeStore ns) {
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(NodeStoreProvider.ROLE, prop(PROP_ROLE));
- nodeStoreReg =
context.getBundleContext().registerService(NodeStoreProvider.class.getName(),
new NodeStoreProvider() {
- @Override
- public NodeStore getNodeStore() {
- return ns;
- }
- },
+ Dictionary<String, Object> props = new Hashtable<>();
+ props.put(NodeStoreProvider.ROLE, config.role());
+ nodeStoreReg = context.getBundleContext().registerService(
+ NodeStoreProvider.class.getName(),
+ (NodeStoreProvider) () -> ns,
props);
log.info("Registered NodeStoreProvider backed by DocumentNodeStore");
}
@@ -737,35 +673,15 @@ public class DocumentNodeStoreService {
private void registerJMXBeans(final DocumentNodeStore store,
DocumentMK.Builder mkBuilder) throws
IOException {
- addRegistration(
- registerMBean(whiteboard,
- CacheStatsMBean.class,
- store.getNodeCacheStats(),
- CacheStatsMBean.TYPE,
- store.getNodeCacheStats().getName()));
- addRegistration(
- registerMBean(whiteboard,
- CacheStatsMBean.class,
- store.getNodeChildrenCacheStats(),
- CacheStatsMBean.TYPE,
- store.getNodeChildrenCacheStats().getName())
- );
+ registerCacheStatsMBean(store.getNodeCacheStats());
+ registerCacheStatsMBean(store.getNodeChildrenCacheStats());
for (CacheStats cs : store.getDiffCacheStats()) {
- addRegistration(
- registerMBean(whiteboard,
- CacheStatsMBean.class, cs,
- CacheStatsMBean.TYPE, cs.getName()));
+ registerCacheStatsMBean(cs);
}
DocumentStore ds = store.getDocumentStore();
if (ds.getCacheStats() != null) {
for (CacheStats cacheStats : ds.getCacheStats()) {
- addRegistration(
- registerMBean(whiteboard,
- CacheStatsMBean.class,
- cacheStats,
- CacheStatsMBean.TYPE,
- cacheStats.getName())
- );
+ registerCacheStatsMBean(cacheStats);
}
}
@@ -786,13 +702,7 @@ public class DocumentNodeStoreService {
);
if (mkBuilder.getBlobStoreCacheStats() != null) {
- addRegistration(
- registerMBean(whiteboard,
- CacheStatsMBean.class,
- mkBuilder.getBlobStoreCacheStats(),
- CacheStatsMBean.TYPE,
- mkBuilder.getBlobStoreCacheStats().getName())
- );
+ registerCacheStatsMBean(mkBuilder.getBlobStoreCacheStats());
}
if (mkBuilder.getDocumentStoreStatsCollector() instanceof
DocumentStoreStatsMBean) {
@@ -817,9 +727,8 @@ public class DocumentNodeStoreService {
);
}
-
- final long versionGcMaxAgeInSecs = toLong(prop(PROP_VER_GC_MAX_AGE),
DEFAULT_VER_GC_MAX_AGE);
- final long blobGcMaxAgeInSecs = toLong(prop(PROP_BLOB_GC_MAX_AGE),
DEFAULT_BLOB_GC_MAX_AGE);
+ final long versionGcMaxAgeInSecs = config.versionGcMaxAgeInSecs();
+ final long blobGcMaxAgeInSecs = config.blobGcMaxAgeInSecs();
if (store.getBlobStore() instanceof GarbageCollectableBlobStore) {
BlobGarbageCollector gc =
store.createBlobGarbageCollector(blobGcMaxAgeInSecs,
@@ -859,6 +768,11 @@ public class DocumentNodeStoreService {
}
}
+ private void registerCacheStatsMBean(CacheStats cacheStats) {
+ addRegistration(registerMBean(whiteboard, CacheStatsMBean.class,
+ cacheStats, CacheStatsMBean.TYPE, cacheStats.getName()));
+ }
+
private void registerLastRevRecoveryJob(final DocumentNodeStore nodeStore)
{
long leaseTime =
toLong(context.getProperties().get(PROP_REV_RECOVERY_INTERVAL),
ClusterNodeInfo.DEFAULT_LEASE_UPDATE_INTERVAL_MILLIS);
@@ -868,12 +782,10 @@ public class DocumentNodeStoreService {
}
private void registerJournalGC(final DocumentNodeStore nodeStore) {
- long journalGCInterval =
toLong(context.getProperties().get(PROP_JOURNAL_GC_INTERVAL_MILLIS),
- DEFAULT_JOURNAL_GC_INTERVAL_MILLIS);
addRegistration(scheduleWithFixedDelay(whiteboard,
new JournalGCJob(nodeStore),
jobPropertiesFor(JournalGCJob.class),
- TimeUnit.MILLISECONDS.toSeconds(journalGCInterval),
+ TimeUnit.MILLISECONDS.toSeconds(config.journalGCInterval()),
true/*runOnSingleClusterNode*/, true /*use dedicated pool*/));
}
@@ -884,26 +796,18 @@ public class DocumentNodeStoreService {
}
Map<String, Object> props = jobPropertiesFor(RevisionGCJob.class);
props.put("scheduler.expression", expr);
- long versionGcMaxAgeInSecs = toLong(prop(PROP_VER_GC_MAX_AGE),
DEFAULT_VER_GC_MAX_AGE);
- long versionGCTimeLimitInSecs = toLong(prop(PROP_VER_GC_TIME_LIMIT),
DEFAULT_RGC_TIME_LIMIT_SECS);
+ long versionGcMaxAgeInSecs = config.versionGcMaxAgeInSecs();
+ long versionGCTimeLimitInSecs = config.versionGCTimeLimitInSecs();
addRegistration(scheduleWithFixedDelay(whiteboard,
new RevisionGCJob(nodeStore, versionGcMaxAgeInSecs,
versionGCTimeLimitInSecs),
props, MODIFIED_IN_SECS_RESOLUTION, true, true));
}
- private String prop(String propName) {
- return prop(propName, PREFIX + propName);
- }
-
- private String prop(String propName, String fwkPropName) {
- return lookupFrameworkThenConfiguration(context, propName,
fwkPropName);
- }
-
- private String getPath(String propName, String defaultValue) {
- String path = PropertiesUtil.toString(prop(propName), defaultValue);
- if (Strings.isNullOrEmpty(path)) {
- return path;
+ private String resolvePath(String value, String defaultValue) {
+ String path = value;
+ if (Strings.isNullOrEmpty(value)) {
+ path = defaultValue;
}
if ("-".equals(path)) {
// disable this path configuration
@@ -914,7 +818,7 @@ public class DocumentNodeStoreService {
}
private String getRepositoryHome() {
- String repoHome = prop(PROP_HOME, PROP_HOME);
+ String repoHome = config.repository_home();
if (Strings.isNullOrEmpty(repoHome)) {
repoHome = DEFAULT_PROP_HOME;
}
@@ -1058,4 +962,17 @@ public class DocumentNodeStoreService {
props.put("scheduler.name", clazz.getName());
return props;
}
+
+ @Component(
+ service = Preset.class,
+ configurationPid = Configuration.PRESET_PID)
+ public static class Preset {
+
+ Configuration configuration;
+
+ @Activate
+ void activate(Configuration configuration) {
+ this.configuration = configuration;
+ }
+ }
}
Added:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfiguration.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfiguration.java?rev=1816417&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfiguration.java
(added)
+++
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfiguration.java
Mon Nov 27 09:12:21 2017
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.apache.jackrabbit.oak.osgi.OsgiUtil;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentContext;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Configuration for the {@link DocumentNodeStoreService}. Access is provided
+ * via {@link Configuration}, while internally the implementation considers
+ * entries in the following sequence:
+ * <ul>
+ * <li>Framework/system properties, potentially with mapped names. See
+ * {@link #frameworkPropertyNameFor(String)}.</li>
+ * <li>OSGi configuration for {@link DocumentNodeStoreService} with
+ * {@link Configuration#PID} if the property is set via the
+ * OSGi Configuration Admin.</li>
+ * <li>OSGi configuration with {@link Configuration#PRESET_PID}. The
+ * default value for a configuration entry will be provided if the
+ * OSGi Configuration Admin does not have an entry as a preset.</li>
+ * </ul>
+ */
+final class DocumentNodeStoreServiceConfiguration {
+
+ /**
+ * Default framework property name prefix.
+ */
+ private static final String DEFAULT_FWK_PREFIX = "oak.documentstore.";
+
+ /**
+ * Name of framework property to configure Mongo Connection URI
+ */
+ private static final String FWK_PROP_URI = "oak.mongo.uri";
+
+ /**
+ * Name of framework property to configure Mongo Database name
+ * to use
+ */
+ private static final String FWK_PROP_DB = "oak.mongo.db";
+
+ /**
+ * Name of framework property to configure socket keep-alive for MongoDB
+ */
+ private static final String FWK_PROP_SO_KEEP_ALIVE =
"oak.mongo.socketKeepAlive";
+
+ /**
+ * Name of the framework property to configure the update limit.
+ */
+ private static final String FWK_PROP_UPDATE_LIMIT = "update.limit";
+
+ private static final String PROP_DB = "db";
+ private static final String PROP_URI = "mongouri";
+ private static final String PROP_HOME = "repository.home";
+ static final String PROP_SO_KEEP_ALIVE = "socketKeepAlive";
+ static final String PROP_UPDATE_LIMIT = "updateLimit";
+
+ /**
+ * Special mapping of property names to framework properties. All other
+ * property names are mapped to framework properties by prefixing them with
+ * {@link #DEFAULT_FWK_PREFIX}.
+ */
+ private static final Map<String, String> FWK_PROP_MAPPING =
ImmutableMap.of(
+ PROP_DB, FWK_PROP_DB,
+ PROP_URI, FWK_PROP_URI,
+ PROP_HOME, PROP_HOME,
+ PROP_SO_KEEP_ALIVE, FWK_PROP_SO_KEEP_ALIVE,
+ PROP_UPDATE_LIMIT, FWK_PROP_UPDATE_LIMIT
+ );
+
+ private DocumentNodeStoreServiceConfiguration() {
+ }
+
+ static Configuration create(ComponentContext context,
+ ConfigurationAdmin configurationAdmin,
+ Configuration preset,
+ Configuration configuration)
+ throws IOException {
+ return (Configuration) Proxy.newProxyInstance(
+ DocumentNodeStoreServiceConfiguration.class.getClassLoader(),
+ new Class[]{Configuration.class},
+ new ConfigurationHandler(context, configurationAdmin, preset,
configuration)
+ );
+ }
+
+ private static String frameworkPropertyNameFor(String propertyName) {
+ String fwkPropName = FWK_PROP_MAPPING.get(propertyName);
+ if (fwkPropName == null) {
+ fwkPropName = DEFAULT_FWK_PREFIX + propertyName;
+ }
+ return fwkPropName;
+ }
+
+ private static final class ConfigurationHandler implements
InvocationHandler {
+
+ private final ComponentContext context;
+
+ /**
+ * The preset configuration.
+ */
+ private final Configuration preset;
+
+ /**
+ * The configuration taking precedence over the preset.
+ */
+ private final Configuration configuration;
+
+ private final Set<String> configurationKeys;
+
+ ConfigurationHandler(ComponentContext context,
+ ConfigurationAdmin configurationAdmin,
+ Configuration preset,
+ Configuration configuration) throws IOException {
+ this.context = checkNotNull(context);
+ this.preset = checkNotNull(preset);
+ this.configuration = checkNotNull(configuration);
+ this.configurationKeys =
getConfigurationKeys(checkNotNull(configurationAdmin));
+ }
+
+ private static Set<String> getConfigurationKeys(ConfigurationAdmin
configurationAdmin)
+ throws IOException {
+ Set<String> keys = new HashSet<>();
+ org.osgi.service.cm.Configuration c =
configurationAdmin.getConfiguration(Configuration.PID);
+ for (Object k : Collections.list(c.getProperties().keys())) {
+ keys.add(k.toString());
+ }
+ return keys;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ String name = method.getName().replaceAll("_", ".");
+ Configuration c;
+ if (configurationKeys.contains(name)) {
+ c = configuration;
+ } else {
+ c = preset;
+ }
+ Object value = method.invoke(c);
+ // check if this is overridden by a framework property
+ String frameworkProp = OsgiUtil.lookup(
+ context.getBundleContext(),
frameworkPropertyNameFor(name));
+ if (frameworkProp != null) {
+ value = tryCoerce(frameworkProp, method.getReturnType(),
value);
+ }
+ return value;
+ }
+
+ private Object tryCoerce(String value, Class<?> type, Object
defaultValue) {
+ Object obj;
+ if (type == Boolean.class || type == boolean.class) {
+ obj = Boolean.parseBoolean(value);
+ } else if (type == Integer.class || type == int.class) {
+ try {
+ obj = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ obj = defaultValue;
+ }
+ } else if (type == Long.class || type == long.class) {
+ try {
+ obj = Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ obj = defaultValue;
+ }
+ } else if (type == String.class) {
+ obj = value;
+ } else {
+ obj = defaultValue;
+ }
+ return obj;
+ }
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java?rev=1816417&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
(added)
+++
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
Mon Nov 27 09:12:21 2017
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class DocumentNodeStoreServiceConfigurationTest {
+
+ @Rule
+ public final OsgiContext context = new OsgiContext();
+
+ private ConfigurationAdmin configAdmin =
context.getService(ConfigurationAdmin.class);
+
+ private TestConfig configuration = new TestConfig(Configuration.PID);
+
+ private TestConfig preset = new TestConfig(Configuration.PRESET_PID);
+
+ @Test
+ public void defaultValues() throws Exception {
+ Configuration config = createConfiguration();
+ assertEquals(DocumentNodeStoreService.DEFAULT_URI, config.mongouri());
+ assertEquals(DocumentNodeStoreService.DEFAULT_DB, config.db());
+ assertEquals(DocumentNodeStoreService.DEFAULT_SO_KEEP_ALIVE,
config.socketKeepAlive());
+ assertEquals(DocumentNodeStoreService.DEFAULT_CACHE, config.cache());
+ assertEquals(DocumentMK.Builder.DEFAULT_NODE_CACHE_PERCENTAGE,
config.nodeCachePercentage());
+ assertEquals(DocumentMK.Builder.DEFAULT_PREV_DOC_CACHE_PERCENTAGE,
config.prevDocCachePercentage());
+ assertEquals(DocumentMK.Builder.DEFAULT_CHILDREN_CACHE_PERCENTAGE,
config.childrenCachePercentage());
+ assertEquals(DocumentMK.Builder.DEFAULT_DIFF_CACHE_PERCENTAGE,
config.diffCachePercentage());
+ assertEquals(DocumentMK.Builder.DEFAULT_CACHE_SEGMENT_COUNT,
config.cacheSegmentCount());
+ assertEquals(DocumentMK.Builder.DEFAULT_CACHE_STACK_MOVE_DISTANCE,
config.cacheStackMoveDistance());
+ assertEquals(DocumentNodeStoreService.DEFAULT_BLOB_CACHE_SIZE,
config.blobCacheSize());
+ assertEquals(DocumentNodeStoreService.DEFAULT_PERSISTENT_CACHE,
config.persistentCache());
+ assertEquals(DocumentNodeStoreService.DEFAULT_JOURNAL_CACHE,
config.journalCache());
+ assertEquals(DocumentNodeStoreService.DEFAULT_CUSTOM_BLOB_STORE,
config.customBlobStore());
+
assertEquals(DocumentNodeStoreService.DEFAULT_JOURNAL_GC_INTERVAL_MILLIS,
config.journalGCInterval());
+
assertEquals(DocumentNodeStoreService.DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS,
config.journalGCMaxAge());
+
assertEquals(DocumentNodeStoreService.DEFAULT_PREFETCH_EXTERNAL_CHANGES,
config.prefetchExternalChanges());
+ assertEquals(null, config.role());
+ assertEquals(DocumentNodeStoreService.DEFAULT_VER_GC_MAX_AGE,
config.versionGcMaxAgeInSecs());
+ assertEquals(DocumentNodeStoreService.DEFAULT_VER_GC_EXPRESSION,
config.versionGCExpression());
+ assertEquals(DocumentNodeStoreService.DEFAULT_RGC_TIME_LIMIT_SECS,
config.versionGCTimeLimitInSecs());
+ assertEquals(DocumentNodeStoreService.DEFAULT_BLOB_GC_MAX_AGE,
config.blobGcMaxAgeInSecs());
+ assertEquals(DocumentNodeStoreService.DEFAULT_BLOB_SNAPSHOT_INTERVAL,
config.blobTrackSnapshotIntervalInSecs());
+ assertEquals(null, config.repository_home());
+ assertEquals(DocumentNodeStoreService.DEFAULT_MAX_REPLICATION_LAG,
config.maxReplicationLagInSecs());
+ assertEquals("MONGO", config.documentStoreType());
+ assertEquals(DocumentNodeStoreService.DEFAULT_BUNDLING_DISABLED,
config.bundlingDisabled());
+ assertEquals(DocumentMK.Builder.DEFAULT_UPDATE_LIMIT,
config.updateLimit());
+ assertEquals(Arrays.asList("/"),
Arrays.asList(config.persistentCacheIncludes()));
+ }
+
+ @Test
+ public void presetMongoURI() throws Exception {
+ String uri = "mongodb://localhost:27017/test";
+ addConfigurationEntry(preset, "mongouri", uri);
+ Configuration config = createConfiguration();
+ assertEquals(uri, config.mongouri());
+ }
+
+ @Test
+ public void presetSocketKeepAlive() throws Exception {
+ boolean keepAlive = !DocumentNodeStoreService.DEFAULT_SO_KEEP_ALIVE;
+ addConfigurationEntry(preset, "socketKeepAlive", keepAlive);
+ Configuration config = createConfiguration();
+ assertEquals(keepAlive, config.socketKeepAlive());
+ }
+
+ @Test
+ public void presetUpdateLimit() throws Exception {
+ int updateLimit = DocumentMK.Builder.DEFAULT_UPDATE_LIMIT / 2;
+ addConfigurationEntry(preset, "updateLimit", updateLimit);
+ Configuration config = createConfiguration();
+ assertEquals(updateLimit, config.updateLimit());
+ }
+
+ @Test
+ public void presetPersistentCacheIncludes() throws Exception {
+ String[] includes = new String[]{"/foo", "/bar"};
+ addConfigurationEntry(preset, "persistentCacheIncludes", includes);
+ Configuration config = createConfiguration();
+ assertTrue(Arrays.equals(includes, config.persistentCacheIncludes()));
+ }
+
+ @Test
+ public void presetOverridden() throws Exception {
+ String db = "test";
+ addConfigurationEntry(preset, "db", "foo");
+ addConfigurationEntry(configuration, "db", db);
+ Configuration config = createConfiguration();
+ assertEquals(db, config.db());
+ }
+
+ @Test
+ public void presetResetToDefault() throws Exception {
+ String db = "test";
+ addConfigurationEntry(preset, "db", db);
+ addConfigurationEntry(configuration, "db",
DocumentNodeStoreService.DEFAULT_DB);
+ Configuration config = createConfiguration();
+ assertEquals(DocumentNodeStoreService.DEFAULT_DB, config.db());
+ }
+
+ private Configuration createConfiguration() throws IOException {
+ return DocumentNodeStoreServiceConfiguration.create(
+ context.componentContext(), configAdmin,
+ preset.asConfiguration(),
+ configuration.asConfiguration());
+ }
+
+ private void addConfigurationEntry(TestConfig config, String key, Object
value)
+ throws IOException {
+ config.put(key, value);
+ org.osgi.service.cm.Configuration c =
configAdmin.getConfiguration(config.servicePid);
+ c.update(new Hashtable(config));
+ }
+
+ private static class TestConfig extends HashMap<String, Object> {
+
+ final String servicePid;
+
+ TestConfig(String servicePid) {
+ this.servicePid = servicePid;
+ }
+
+ Configuration asConfiguration() {
+ return (Configuration) Proxy.newProxyInstance(
+
DocumentNodeStoreServiceConfigurationTest.class.getClassLoader(),
+ new Class[]{Configuration.class},
+ this::getProperty);
+ }
+
+ private Object getProperty(Object proxy, Method method, Object[] args)
{
+ Object value = get(method.getName().replaceAll("_", "."));
+ if (value == null) {
+ value = method.getDefaultValue();
+ }
+ return value;
+ }
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java?rev=1816417&r1=1816416&r2=1816417&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
(original)
+++
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
Mon Nov 27 09:12:21 2017
@@ -34,10 +34,12 @@ import org.apache.sling.testing.mock.osg
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import static org.apache.jackrabbit.oak.plugins.document.Configuration.PID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -56,12 +58,15 @@ public class DocumentNodeStoreServiceTes
private final DocumentNodeStoreService service = new
DocumentNodeStoreService();
+ private final DocumentNodeStoreService.Preset preset = new
DocumentNodeStoreService.Preset();
+
private String repoHome;
@Before
public void setUp() throws Exception {
assumeTrue(MongoUtils.isAvailable());
context.registerService(StatisticsProvider.class,
StatisticsProvider.NOOP);
+ context.registerInjectActivateService(preset);
MockOsgi.injectServices(service, context.bundleContext());
repoHome = target.newFolder().getAbsolutePath();
}
@@ -123,7 +128,8 @@ public class DocumentNodeStoreServiceTes
@Test
public void journalPropertyTracker() throws Exception {
- MockOsgi.activate(service, context.bundleContext(),
newConfig(repoHome));
+ MockOsgi.setConfigForPid(context.bundleContext(), PID,
newConfig(repoHome));
+ MockOsgi.activate(service, context.bundleContext());
DocumentNodeStore store = context.getService(DocumentNodeStore.class);
assertEquals(0,
store.getJournalPropertyHandlerFactory().getServiceCount());
@@ -134,8 +140,9 @@ public class DocumentNodeStoreServiceTes
@Test
public void setUpdateLimit() throws Exception {
Map<String, Object> config = newConfig(repoHome);
- config.put(DocumentNodeStoreService.PROP_UPDATE_LIMIT, 17);
- MockOsgi.activate(service, context.bundleContext(), config);
+ config.put(DocumentNodeStoreServiceConfiguration.PROP_UPDATE_LIMIT,
17);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
DocumentNodeStore store = context.getService(DocumentNodeStore.class);
assertEquals(17, store.getUpdateLimit());
}
@@ -143,8 +150,9 @@ public class DocumentNodeStoreServiceTes
@Test
public void keepAlive() throws Exception {
Map<String, Object> config = newConfig(repoHome);
- config.put(DocumentNodeStoreService.PROP_SO_KEEP_ALIVE, true);
- MockOsgi.activate(service, context.bundleContext(), config);
+ config.put(DocumentNodeStoreServiceConfiguration.PROP_SO_KEEP_ALIVE,
true);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
DocumentNodeStore store = context.getService(DocumentNodeStore.class);
MongoDocumentStore mds = getMongoDocumentStore(store);
DB db = MongoDocumentStoreTestHelper.getDB(mds);
@@ -154,7 +162,8 @@ public class DocumentNodeStoreServiceTes
@Test
public void continuousRGCDefault() throws Exception {
Map<String, Object> config = newConfig(repoHome);
- MockOsgi.activate(service, context.bundleContext(), config);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
boolean jobScheduled = false;
for (Runnable r : context.getServices(Runnable.class,
"(scheduler.expression=\\*/5 \\* \\* \\* \\* ?)")) {
jobScheduled |=
r.getClass().equals(DocumentNodeStoreService.RevisionGCJob.class);
@@ -165,7 +174,8 @@ public class DocumentNodeStoreServiceTes
@Test
public void continuousRGCJobAsSupplier() throws Exception {
Map<String, Object> config = newConfig(repoHome);
- MockOsgi.activate(service, context.bundleContext(), config);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
Runnable rgcJob = null;
for (Runnable r : context.getServices(Runnable.class, null)) {
if
(r.getClass().equals(DocumentNodeStoreService.RevisionGCJob.class)) {
@@ -181,7 +191,8 @@ public class DocumentNodeStoreServiceTes
public void persistentCacheExclude() throws Exception{
Map<String, Object> config = newConfig(repoHome);
config.put("persistentCacheIncludes", new String[] {"/a/b", "/c/d ",
null});
- MockOsgi.activate(service, context.bundleContext(), config);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
DocumentNodeStore dns = context.getService(DocumentNodeStore.class);
assertTrue(dns.getNodeCachePredicate().apply("/a/b/c"));
@@ -190,6 +201,42 @@ public class DocumentNodeStoreServiceTes
assertFalse(dns.getNodeCachePredicate().apply("/x"));
}
+ @Ignore("SLING-7233")
+ @Test
+ public void preset() throws Exception {
+ MockOsgi.setConfigForPid(context.bundleContext(),
+ Configuration.PRESET_PID,
+ DocumentNodeStoreServiceConfiguration.PROP_SO_KEEP_ALIVE,
true);
+ MockOsgi.activate(preset, context.bundleContext());
+
+ MockOsgi.setConfigForPid(context.bundleContext(), PID,
newConfig(repoHome));
+ MockOsgi.activate(service, context.bundleContext());
+
+ DocumentNodeStore store = context.getService(DocumentNodeStore.class);
+ MongoDocumentStore mds = getMongoDocumentStore(store);
+ DB db = MongoDocumentStoreTestHelper.getDB(mds);
+ assertTrue(db.getMongo().getMongoOptions().isSocketKeepAlive());
+ }
+
+ @Test
+ public void presetOverride() throws Exception {
+ MockOsgi.setConfigForPid(context.bundleContext(),
+ Configuration.PRESET_PID,
+ DocumentNodeStoreServiceConfiguration.PROP_SO_KEEP_ALIVE,
true);
+ MockOsgi.activate(preset, context.bundleContext());
+
+ Map<String, Object> config = newConfig(repoHome);
+ config.put(DocumentNodeStoreServiceConfiguration.PROP_SO_KEEP_ALIVE,
false);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+
+ MockOsgi.activate(service, context.bundleContext());
+
+ DocumentNodeStore store = context.getService(DocumentNodeStore.class);
+ MongoDocumentStore mds = getMongoDocumentStore(store);
+ DB db = MongoDocumentStoreTestHelper.getDB(mds);
+ assertFalse(db.getMongo().getMongoOptions().isSocketKeepAlive());
+ }
+
private static MongoDocumentStore getMongoDocumentStore(DocumentNodeStore
s) {
try {
Field f = s.getClass().getDeclaredField("nonLeaseCheckingStore");
@@ -223,7 +270,8 @@ public class DocumentNodeStoreServiceTes
Map<String, Object> config) {
assertFalse(new File(expectedPath).exists());
- MockOsgi.activate(service, context.bundleContext(), config);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
assertNotNull(context.getService(NodeStore.class));
// must exist after service was activated
@@ -249,8 +297,8 @@ public class DocumentNodeStoreServiceTes
private void assertNoCachePath(String unexpectedPath,
Map<String, Object> config) {
assertFalse(new File(unexpectedPath).exists());
-
- MockOsgi.activate(service, context.bundleContext(), config);
+ MockOsgi.setConfigForPid(context.bundleContext(), PID, config);
+ MockOsgi.activate(service, context.bundleContext());
assertNotNull(context.getService(NodeStore.class));
// must not exist after service was activated