Modified: jackrabbit/oak/trunk/oak-store-document/pom.xml URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/pom.xml?rev=1810002&r1=1810001&r2=1810002&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/pom.xml (original) +++ jackrabbit/oak/trunk/oak-store-document/pom.xml Thu Sep 28 14:09:26 2017 @@ -101,8 +101,8 @@ <scope>provided</scope> </dependency> <dependency> - <groupId>org.apache.felix</groupId> - <artifactId>org.apache.felix.scr.annotations</artifactId> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.service.metatype.annotations</artifactId> <scope>provided</scope> </dependency>
Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java?rev=1810002&r1=1810001&r2=1810002&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentDiscoveryLiteService.java Thu Sep 28 14:09:26 2017 @@ -30,13 +30,6 @@ import java.util.Set; import javax.annotation.Nonnull; import javax.jcr.Value; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.ReferencePolicy; -import org.apache.felix.scr.annotations.Service; import org.apache.jackrabbit.commons.SimpleValueFactory; import org.apache.jackrabbit.oak.api.Descriptors; import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard; @@ -46,6 +39,12 @@ import org.apache.jackrabbit.oak.spi.com import org.apache.jackrabbit.oak.spi.state.NodeState; import org.osgi.framework.Version; import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -136,8 +135,10 @@ import org.slf4j.LoggerFactory; * * @see #OAK_DISCOVERYLITE_CLUSTERVIEW */ -@Component(immediate = true, name = DocumentDiscoveryLiteService.COMPONENT_NAME) -@Service(value = { DocumentDiscoveryLiteService.class, Observer.class }) +@Component( + name = DocumentDiscoveryLiteService.COMPONENT_NAME, + immediate = true, + service = { DocumentDiscoveryLiteService.class, Observer.class }) public class DocumentDiscoveryLiteService implements ClusterStateChangeListener, Observer { static final String COMPONENT_NAME = "org.apache.jackrabbit.oak.plugins.document.DocumentDiscoveryLiteService"; @@ -287,8 +288,8 @@ public class DocumentDiscoveryLiteServic * Require a static reference to the NodeStore. Note that this implies the * service is only active for documentNS **/ - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC) - private volatile DocumentNodeStore nodeStore; + @Reference + private DocumentNodeStore nodeStore; /** * inactive nodes that have been so for a while, ie they have no backlog 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=1810002&r1=1810001&r2=1810002&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 Thu Sep 28 14:09:26 2017 @@ -58,15 +58,6 @@ import com.google.common.util.concurrent import com.mongodb.MongoClientURI; import org.apache.commons.io.FilenameUtils; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.ConfigurationPolicy; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.PropertyOption; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.ReferencePolicy; import org.apache.jackrabbit.commons.SimpleValueFactory; import org.apache.jackrabbit.oak.api.Descriptors; import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean; @@ -116,21 +107,27 @@ import org.osgi.framework.BundleExceptio import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +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.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; +import org.osgi.service.metatype.annotations.Option; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The OSGi service to start/stop a DocumentNodeStore instance. */ -@Component(policy = ConfigurationPolicy.REQUIRE, - metatype = true, - label = "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 " + - "stability purpose it is advisable to not change these settings at runtime. Instead the config change " + - "should be done via file system based config file and this view should ONLY be used to determine which " + - "options are supported" -) +@Component( + configurationPolicy = ConfigurationPolicy.REQUIRE, + service = {}) +@Designate(ocd = DocumentNodeStoreService.Configuration.class) public class DocumentNodeStoreService { private static final long MB = 1024 * 1024; @@ -144,6 +141,27 @@ public class DocumentNodeStoreService { private static final boolean DEFAULT_CONTINUOUS_RGC = false; private static final String PREFIX = "oak.documentstore."; private static final String DESCRIPTION = "oak.nodestore.description"; + private 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 + private static final String DEFAULT_PROP_HOME = "./repository"; + private static final long DEFAULT_MAX_REPLICATION_LAG = 6 * 60 * 60; + private static final boolean DEFAULT_BUNDLING_DISABLED = false; + + /** + * Revisions older than this time would be garbage collected + */ + private static final long DEFAULT_VER_GC_MAX_AGE = 24 * 60 * 60; //TimeUnit.DAYS.toSeconds(1); + + + /** + * Blob modified before this time duration would be considered for Blob GC + */ + private static final long DEFAULT_BLOB_GC_MAX_AGE = 24 * 60 * 60; + + /** + * Default interval for taking snapshots of locally tracked blob ids. + */ + private static final long DEFAULT_BLOB_SNAPSHOT_INTERVAL = 12 * 60 * 60; /** * Name of framework property to configure Mongo Connection URI @@ -161,133 +179,219 @@ public class DocumentNodeStoreService { */ private static final String FWK_PROP_SO_KEEP_ALIVE = "oak.mongo.socketKeepAlive"; - @Property(value = DEFAULT_URI, - label = "Mongo URI", - description = "Mongo connection URI used to connect to Mongo. Refer to " + - "http://docs.mongodb.org/manual/reference/connection-string/ for details. Note that this value " + - "can be overridden via framework property 'oak.mongo.uri'" - ) - private static final String PROP_URI = "mongouri"; - @Property(value = DEFAULT_DB, - label = "Mongo DB name", - description = "Name of the database in Mongo. Note that this value " + - "can be overridden via framework property 'oak.mongo.db'" - ) + @ObjectClassDefinition( + 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 " + + "stability purpose it is advisable to not change these settings at runtime. Instead the config change " + + "should be done via file system based config file and this view should ONLY be used to determine which " + + "options are supported") + @interface Configuration { + @AttributeDefinition( + name = "Mongo URI", + description = "Mongo connection URI used to connect to Mongo. Refer to " + + "http://docs.mongodb.org/manual/reference/connection-string/ for details. Note that this value " + + "can be overridden via framework property 'oak.mongo.uri'") + String mongouri() default DEFAULT_URI; + + @AttributeDefinition( + name = "Mongo DB name", + description = "Name of the database in Mongo. Note that this value " + + "can be overridden via framework property 'oak.mongo.db'") + String db() default DEFAULT_DB; + + + @AttributeDefinition( + name = "MongoDB socket keep-alive option", + description = "Whether socket keep-alive should be enabled for " + + "connections to MongoDB. Note that this value can be " + + "overridden via framework property 'oak.mongo.socketKeepAlive'") + boolean socketKeepAlive() default DEFAULT_SO_KEEP_ALIVE; + + @AttributeDefinition( + name = "Cache Size (in MB)", + description = "Cache size in MB. This is distributed among various caches used in DocumentNodeStore") + int cache() default DEFAULT_CACHE; + + @AttributeDefinition( + name = "NodeState Cache", + description = "Percentage of cache to be allocated towards Node cache") + int nodeCachePercentage() default DEFAULT_NODE_CACHE_PERCENTAGE; + + @AttributeDefinition( + name = "PreviousDocument Cache", + description = "Percentage of cache to be allocated towards Previous Document cache") + int prevDocCachePercentage() default DEFAULT_PREV_DOC_CACHE_PERCENTAGE; + + @AttributeDefinition( + name = "NodeState Children Cache", + description = "Percentage of cache to be allocated towards Children cache") + int childrenCachePercentage() default DEFAULT_CHILDREN_CACHE_PERCENTAGE; + + @AttributeDefinition( + name = "Diff Cache", + description = "Percentage of cache to be allocated towards Diff cache") + int diffCachePercentage() default DEFAULT_DIFF_CACHE_PERCENTAGE; + + @AttributeDefinition( + name = "LIRS Cache Segment Count", + description = "The number of segments in the LIRS cache " + + "(default 16, a higher count means higher concurrency " + + "but slightly lower cache hit rate)") + int cacheSegmentCount() default DEFAULT_CACHE_SEGMENT_COUNT; + + @AttributeDefinition( + name = "LIRS Cache Stack Move Distance", + description = "The delay to move entries to the head of the queue " + + "in the LIRS cache " + + "(default 16, a higher value means higher concurrency " + + "but slightly lower cache hit rate)") + int cacheStackMoveDistance() default DEFAULT_CACHE_STACK_MOVE_DISTANCE; + + @AttributeDefinition( + name = "Blob Cache Size (in MB)", + description = "Cache size to store blobs in memory. Used only with default BlobStore " + + "(as per DocumentStore type)") + int blobCacheSize() default DEFAULT_BLOB_CACHE_SIZE; + + @AttributeDefinition( + name = "Persistent Cache Config", + description = "Configuration for persistent cache. Refer to " + + "http://jackrabbit.apache.org/oak/docs/nodestore/persistent-cache.html for various options") + String persistentCache() default DEFAULT_PERSISTENT_CACHE; + + @AttributeDefinition( + name = "Journal Cache Config", + description = "Configuration for journal cache. Refer to " + + "http://jackrabbit.apache.org/oak/docs/nodestore/persistent-cache.html for various options") + String journalCache() default DEFAULT_JOURNAL_CACHE; + + @AttributeDefinition( + 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; + + + @AttributeDefinition( + name = "Journal Garbage Collection Interval (millis)", + description = "Long value indicating interval (in milliseconds) with which the " + + "journal (for external changes) is cleaned up. Default is " + DEFAULT_JOURNAL_GC_INTERVAL_MILLIS) + long journalGCInterval() default DEFAULT_JOURNAL_GC_INTERVAL_MILLIS; + + @AttributeDefinition( + name = "Maximum Age of Journal Entries (millis)", + description = "Long value indicating max age (in milliseconds) that " + + "journal (for external changes) entries are kept (older ones are candidates for gc). " + + "Default is " + DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS) + long journalGCMaxAge() default DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS; + + @AttributeDefinition( + name = "Pre-fetch external changes", + description = "Boolean value indicating if external changes should " + + "be pre-fetched in a background thread.") + boolean prefetchExternalChanges() default false; + + @AttributeDefinition( + name = "NodeStoreProvider role", + description = "Property indicating that this component will not register as a NodeStore but as a " + + "NodeStoreProvider with given role") + String role(); + + @AttributeDefinition( + name = "Version GC Max Age (in secs)", + description = "Version Garbage Collector (GC) logic will only consider those deleted for GC which " + + "are not accessed recently (currentTime - lastModifiedTime > versionGcMaxAgeInSecs). For " + + "example as per default only those document which have been *marked* deleted 24 hrs ago will be " + + "considered for GC. This also applies how older revision of live document are GC.") + long versionGcMaxAgeInSecs() default DEFAULT_VER_GC_MAX_AGE; + + @AttributeDefinition( + name = "Continuous Version GC Mode", + description = "Run Version GC continuously as a background task.") + boolean versionGCContinuous() default DEFAULT_CONTINUOUS_RGC; + + @AttributeDefinition( + name = "Blob GC Max Age (in secs)", + description = "Blob Garbage Collector (GC) logic will only consider those blobs for GC which " + + "are not accessed recently (currentTime - lastModifiedTime > blobGcMaxAgeInSecs). For " + + "example as per default only those blobs which have been created 24 hrs ago will be " + + "considered for GC") + long blobGcMaxAgeInSecs() default DEFAULT_BLOB_GC_MAX_AGE; + + @AttributeDefinition( + name = "Blob tracking snapshot interval (in secs)", + description = "This is the default interval in which the snapshots of locally tracked blob ids will" + + "be taken and synchronized with the blob store. This should be configured to be less than the " + + "frequency of blob GC so that deletions during blob GC can be accounted for " + + "in the next GC execution.") + long blobTrackSnapshotIntervalInSecs() default DEFAULT_BLOB_SNAPSHOT_INTERVAL; + + @AttributeDefinition( + name = "Root directory", + description = "Root directory for local tracking of blob ids. This service " + + "will first lookup the 'repository.home' framework property and " + + "then a component context property with the same name. If none " + + "of them is defined, a sub directory 'repository' relative to " + + "the current working directory is used.") + String repository_home(); + + @AttributeDefinition( + name = "Max Replication Lag (in secs)", + description = "Value in seconds. Determines the duration beyond which it can be safely assumed " + + "that the state on the secondaries is consistent with the primary, and it is safe to read from them") + long maxReplicationLagInSecs() default DEFAULT_MAX_REPLICATION_LAG; + + @AttributeDefinition( + name = "DocumentStore Type", + description = "Type of DocumentStore to use for persistence. Defaults to MONGO", + options = { + @Option(label = "MONGO", value = "MONGO"), + @Option(label = "RDB", value = "RDB")}) + String documentStoreType() default "MONGO"; + + @AttributeDefinition( + name = "Bundling Disabled", + description = "Boolean value indicating that Node bundling is disabled") + boolean bundlingDisabled() default DEFAULT_BUNDLING_DISABLED; + + @AttributeDefinition( + 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(); + } + + // 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"; - - @Property(boolValue = DEFAULT_SO_KEEP_ALIVE, - label = "MongoDB socket keep-alive option", - description = "Whether socket keep-alive should be enabled for " + - "connections to MongoDB. Note that this value can be " + - "overridden via framework property 'oak.mongo.socketKeepAlive'" - ) static final String PROP_SO_KEEP_ALIVE = "socketKeepAlive"; - - @Property(intValue = DEFAULT_CACHE, - label = "Cache Size (in MB)", - description = "Cache size in MB. This is distributed among various caches used in DocumentNodeStore" - ) private static final String PROP_CACHE = "cache"; - - @Property(intValue = DEFAULT_NODE_CACHE_PERCENTAGE, - label = "NodeState Cache", - description = "Percentage of cache to be allocated towards Node cache" - ) private static final String PROP_NODE_CACHE_PERCENTAGE = "nodeCachePercentage"; - - @Property(intValue = DEFAULT_PREV_DOC_CACHE_PERCENTAGE, - label = "PreviousDocument Cache", - description = "Percentage of cache to be allocated towards Previous Document cache" - ) private static final String PROP_PREV_DOC_CACHE_PERCENTAGE = "prevDocCachePercentage"; - - @Property(intValue = DocumentMK.Builder.DEFAULT_CHILDREN_CACHE_PERCENTAGE, - label = "NodeState Children Cache", - description = "Percentage of cache to be allocated towards Children cache" - ) private static final String PROP_CHILDREN_CACHE_PERCENTAGE = "childrenCachePercentage"; - - @Property(intValue = DocumentMK.Builder.DEFAULT_DIFF_CACHE_PERCENTAGE, - label = "Diff Cache", - description = "Percentage of cache to be allocated towards Diff cache" - ) private static final String PROP_DIFF_CACHE_PERCENTAGE = "diffCachePercentage"; - - @Property(intValue = DEFAULT_CACHE_SEGMENT_COUNT, - label = "LIRS Cache Segment Count", - description = "The number of segments in the LIRS cache " + - "(default 16, a higher count means higher concurrency " + - "but slightly lower cache hit rate)" - ) private static final String PROP_CACHE_SEGMENT_COUNT = "cacheSegmentCount"; - - @Property(intValue = DEFAULT_CACHE_STACK_MOVE_DISTANCE, - label = "LIRS Cache Stack Move Distance", - description = "The delay to move entries to the head of the queue " + - "in the LIRS cache " + - "(default 16, a higher value means higher concurrency " + - "but slightly lower cache hit rate)" - ) private static final String PROP_CACHE_STACK_MOVE_DISTANCE = "cacheStackMoveDistance"; - - @Property(intValue = DEFAULT_BLOB_CACHE_SIZE, - label = "Blob Cache Size (in MB)", - description = "Cache size to store blobs in memory. Used only with default BlobStore " + - "(as per DocumentStore type)" - ) private static final String PROP_BLOB_CACHE_SIZE = "blobCacheSize"; - - @Property(value = DEFAULT_PERSISTENT_CACHE, - label = "Persistent Cache Config", - description = "Configuration for persistent cache. Refer to " + - "http://jackrabbit.apache.org/oak/docs/nodestore/persistent-cache.html for various options" - ) private static final String PROP_PERSISTENT_CACHE = "persistentCache"; - - @Property(value = DEFAULT_JOURNAL_CACHE, - label = "Journal Cache Config", - description = "Configuration for journal cache. Refer to " + - "http://jackrabbit.apache.org/oak/docs/nodestore/persistent-cache.html for various options" - ) private static final String PROP_JOURNAL_CACHE = "journalCache"; - - @Property(boolValue = false, - label = "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." - ) - public static final String CUSTOM_BLOB_STORE = "customBlobStore"; - - private static final long DEFAULT_JOURNAL_GC_INTERVAL_MILLIS = 5*60*1000; // default is 5min - @Property(longValue = DEFAULT_JOURNAL_GC_INTERVAL_MILLIS, - label = "Journal Garbage Collection Interval (millis)", - description = "Long value indicating interval (in milliseconds) with which the " - + "journal (for external changes) is cleaned up. Default is " + DEFAULT_JOURNAL_GC_INTERVAL_MILLIS - ) - private static final String PROP_JOURNAL_GC_INTERVAL_MILLIS = "journalGCInterval"; - - static final long DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS = 24*60*60*1000; // default is 24hours - @Property(longValue = DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS, - label = "Maximum Age of Journal Entries (millis)", - description = "Long value indicating max age (in milliseconds) that " - + "journal (for external changes) entries are kept (older ones are candidates for gc). " - + "Default is " + DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS - ) - private static final String PROP_JOURNAL_GC_MAX_AGE_MILLIS = "journalGCMaxAge"; - - @Property (boolValue = false, - label = "Pre-fetch external changes", - description = "Boolean value indicating if external changes should " + - "be pre-fetched in a background thread." - ) public static final String PROP_PREFETCH_EXTERNAL_CHANGES = "prefetchExternalChanges"; - - @Property( - label = "NodeStoreProvider role", - description = "Property indicating that this component will not register as a NodeStore but as a NodeStoreProvider with given role" - ) + 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_CONTINUOUS = "versionGCContinuous"; + 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 { MONGO, RDB; @@ -306,24 +410,12 @@ public class DocumentNodeStoreService { private Closer closer; private WhiteboardExecutor executor; - @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, - policy = ReferencePolicy.DYNAMIC, target = ONLY_STANDALONE_TARGET) private volatile BlobStore blobStore; - @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, - policy = ReferencePolicy.DYNAMIC, - target = "(datasource.name=oak)" - ) private volatile DataSource dataSource; - @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, - policy = ReferencePolicy.DYNAMIC, - target = "(datasource.name=oak)" - ) private volatile DataSource blobDataSource; - @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, - policy = ReferencePolicy.DYNAMIC) private volatile DocumentNodeStateCache nodeStateCache; private DocumentNodeStore nodeStore; @@ -332,99 +424,7 @@ public class DocumentNodeStoreService { private ComponentContext context; private Whiteboard whiteboard; private long deactivationTimestamp = 0; - - - /** - * Revisions older than this time would be garbage collected - */ - private static final long DEFAULT_VER_GC_MAX_AGE = 24 * 60 * 60; //TimeUnit.DAYS.toSeconds(1); - @Property (longValue = DEFAULT_VER_GC_MAX_AGE, - label = "Version GC Max Age (in secs)", - description = "Version Garbage Collector (GC) logic will only consider those deleted for GC which " + - "are not accessed recently (currentTime - lastModifiedTime > versionGcMaxAgeInSecs). For " + - "example as per default only those document which have been *marked* deleted 24 hrs ago will be " + - "considered for GC. This also applies how older revision of live document are GC." - ) - public static final String PROP_VER_GC_MAX_AGE = "versionGcMaxAgeInSecs"; - - @Property (boolValue = DEFAULT_CONTINUOUS_RGC, - label = "Continuous Version GC Mode", - description = "Run Version GC continuously as a background task.") - public static final String PROP_VER_GC_CONTINUOUS = "versionGCContinuous"; - - public static final String PROP_REV_RECOVERY_INTERVAL = "lastRevRecoveryJobIntervalInSecs"; - - /** - * Blob modified before this time duration would be considered for Blob GC - */ - private static final long DEFAULT_BLOB_GC_MAX_AGE = 24 * 60 * 60; - @Property (longValue = DEFAULT_BLOB_GC_MAX_AGE, - label = "Blob GC Max Age (in secs)", - description = "Blob Garbage Collector (GC) logic will only consider those blobs for GC which " + - "are not accessed recently (currentTime - lastModifiedTime > blobGcMaxAgeInSecs). For " + - "example as per default only those blobs which have been created 24 hrs ago will be " + - "considered for GC" - ) - public static final String PROP_BLOB_GC_MAX_AGE = "blobGcMaxAgeInSecs"; - - /** - * Default interval for taking snapshots of locally tracked blob ids. - */ - private static final long DEFAULT_BLOB_SNAPSHOT_INTERVAL = 12 * 60 * 60; - @Property (longValue = DEFAULT_BLOB_SNAPSHOT_INTERVAL, - label = "Blob tracking snapshot interval (in secs)", - description = "This is the default interval in which the snapshots of locally tracked blob ids will" - + "be taken and synchronized with the blob store. This should be configured to be less than the " - + "frequency of blob GC so that deletions during blob GC can be accounted for " - + "in the next GC execution." - ) - public static final String PROP_BLOB_SNAPSHOT_INTERVAL = "blobTrackSnapshotIntervalInSecs"; - - private static final String DEFAULT_PROP_HOME = "./repository"; - @Property( - label = "Root directory", - description = "Root directory for local tracking of blob ids. This service " + - "will first lookup the 'repository.home' framework property and " + - "then a component context property with the same name. If none " + - "of them is defined, a sub directory 'repository' relative to " + - "the current working directory is used." - ) - private static final String PROP_HOME = "repository.home"; - - private static final long DEFAULT_MAX_REPLICATION_LAG = 6 * 60 * 60; - @Property(longValue = DEFAULT_MAX_REPLICATION_LAG, - label = "Max Replication Lag (in secs)", - description = "Value in seconds. Determines the duration beyond which it can be safely assumed " + - "that the state on the secondaries is consistent with the primary, and it is safe to read from them" - ) - public static final String PROP_REPLICATION_LAG = "maxReplicationLagInSecs"; - private long maxReplicationLagInSecs = DEFAULT_MAX_REPLICATION_LAG; - - @Property(options = { - @PropertyOption(name = "MONGO", value = "MONGO"), - @PropertyOption(name = "RDB", value = "RDB") - }, - value = "MONGO", - label = "DocumentStore Type", - description = "Type of DocumentStore to use for persistence. Defaults to MONGO" - ) - public static final String PROP_DS_TYPE = "documentStoreType"; - - private static final boolean DEFAULT_BUNDLING_DISABLED = false; - @Property(boolValue = DEFAULT_BUNDLING_DISABLED, - label = "Bundling Disabled", - description = "Boolean value indicating that Node bundling is disabled" - ) - private static final String PROP_BUNDLING_DISABLED = "bundlingDisabled"; - - @Property( - label = "DocumentNodeStore update.limit", - description = "Number of content updates that need to happen before " + - "the updates are automatically purged to the private branch." - ) - public static final String PROP_UPDATE_LIMIT = "updateLimit"; - - private DocumentStoreType documentStoreType; + private long maxReplicationLagInSecs; @Reference private StatisticsProvider statisticsProvider; @@ -436,15 +436,15 @@ public class DocumentNodeStoreService { private BlobStore defaultBlobStore; @Activate - protected void activate(ComponentContext context, Map<String, ?> config) throws Exception { + protected void activate(ComponentContext context, Configuration config) throws Exception { closer = Closer.create(); this.context = context; whiteboard = new OsgiWhiteboard(context.getBundleContext()); executor = new WhiteboardExecutor(); executor.start(whiteboard); - maxReplicationLagInSecs = toLong(config.get(PROP_REPLICATION_LAG), DEFAULT_MAX_REPLICATION_LAG); + maxReplicationLagInSecs = config.maxReplicationLagInSecs(); customBlobStore = toBoolean(prop(CUSTOM_BLOB_STORE), false); - documentStoreType = DocumentStoreType.fromString(PropertiesUtil.toString(config.get(PROP_DS_TYPE), "MONGO")); + documentStoreType = DocumentStoreType.fromString(config.documentStoreType()); registerNodeStoreIfPossible(); } @@ -730,6 +730,11 @@ public class DocumentNodeStoreService { unregisterNodeStore(); } + @Reference(name = "blobStore", + cardinality = ReferenceCardinality.OPTIONAL, + policy = ReferencePolicy.DYNAMIC, + target = ONLY_STANDALONE_TARGET + ) @SuppressWarnings("UnusedDeclaration") protected void bindBlobStore(BlobStore blobStore) throws IOException { if (defaultBlobStore == blobStore){ @@ -749,6 +754,11 @@ public class DocumentNodeStoreService { unregisterNodeStore(); } + @Reference(name = "dataSource", + cardinality = ReferenceCardinality.OPTIONAL, + policy = ReferencePolicy.DYNAMIC, + target = "(datasource.name=oak)" + ) @SuppressWarnings("UnusedDeclaration") protected void bindDataSource(DataSource dataSource) throws IOException { if (this.dataSource != null) { @@ -771,6 +781,14 @@ public class DocumentNodeStoreService { } } + + private DocumentStoreType documentStoreType; + + @Reference(name = "blobDataSource", + cardinality = ReferenceCardinality.OPTIONAL, + policy = ReferencePolicy.DYNAMIC, + target = "(datasource.name=oak)" + ) @SuppressWarnings("UnusedDeclaration") protected void bindBlobDataSource(DataSource dataSource) throws IOException { if (this.blobDataSource != null) { @@ -794,6 +812,10 @@ public class DocumentNodeStoreService { } } + @Reference(name = "nodeStateCache", + cardinality = ReferenceCardinality.OPTIONAL, + policy = ReferencePolicy.DYNAMIC + ) @SuppressWarnings("UnusedDeclaration") protected void bindNodeStateCache(DocumentNodeStateCache nodeStateCache) throws IOException { if (nodeStore != null){ Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheService.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheService.java?rev=1810002&r1=1810001&r2=1810002&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheService.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/secondary/SecondaryStoreCacheService.java Thu Sep 28 14:09:26 2017 @@ -20,28 +20,16 @@ package org.apache.jackrabbit.oak.plugins.document.secondary; import static java.util.Arrays.asList; -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.toStringArray; import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean; import java.util.Collections; import java.util.Hashtable; import java.util.List; -import java.util.Map; import java.util.concurrent.Executor; import javax.annotation.Nonnull; import com.google.common.collect.Lists; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.PropertyUnbounded; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.ReferencePolicy; import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard; import org.apache.jackrabbit.oak.plugins.document.AbstractDocumentNodeState; import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStateCache; @@ -60,15 +48,47 @@ import org.apache.jackrabbit.oak.stats.S import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +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.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Component(label = "Apache Jackrabbit Oak DocumentNodeStateCache Provider", - metatype = true, - immediate = true, - description = "Configures a DocumentNodeStateCache based on a secondary NodeStore" -) +@Component +@Designate(ocd = SecondaryStoreCacheService.Configuration.class) public class SecondaryStoreCacheService { + + @ObjectClassDefinition( + name = "Apache Jackrabbit Oak DocumentNodeStateCache Provider", + description = "Configures a DocumentNodeStateCache based on a secondary NodeStore" + ) + @interface Configuration { + + @AttributeDefinition( + name = "Included Paths", + description = "List of paths which are to be included in the secondary store" + ) + String[] includedPaths() default {"/"}; + + @AttributeDefinition( + name = "Async Observation", + description = "Enable async observation processing" + ) + boolean enableAsyncObserver() default true; + + @AttributeDefinition( + name = "Observer queue size", + description = "Observer queue size. Used if 'enableAsyncObserver' is set to true" + ) + int observerQueueSize() default BackgroundObserver.DEFAULT_QUEUE_SIZE; + } + private final Logger log = LoggerFactory.getLogger(getClass()); /** * Having a reference to BlobStore ensures that DocumentNodeStoreService does register a BlobStore @@ -89,32 +109,9 @@ public class SecondaryStoreCacheService * Have an optional dependency on DocumentNodeStore such that we do not have hard dependency * on it and DocumentNodeStore can make use of this service even after it has unregistered */ - @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, + @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC) - private DocumentNodeStore documentNodeStore; - - @Property(unbounded = PropertyUnbounded.ARRAY, - label = "Included Paths", - description = "List of paths which are to be included in the secondary store", - value = {"/"} - ) - private static final String PROP_INCLUDES = "includedPaths"; - - private static final boolean PROP_ASYNC_OBSERVER_DEFAULT = true; - @Property( - boolValue = PROP_ASYNC_OBSERVER_DEFAULT, - label = "Async Observation", - description = "Enable async observation processing" - ) - private static final String PROP_ASYNC_OBSERVER = "enableAsyncObserver"; - - private static final int PROP_OBSERVER_QUEUE_SIZE_DEFAULT = BackgroundObserver.DEFAULT_QUEUE_SIZE; - @Property( - intValue = PROP_OBSERVER_QUEUE_SIZE_DEFAULT, - label = "Observer queue size", - description = "Observer queue size. Used if 'enableAsyncObserver' is set to true" - ) - private static final String PROP_OBSERVER_QUEUE_SIZE = "observerQueueSize"; + private volatile DocumentNodeStore documentNodeStore; private final List<Registration> oakRegs = Lists.newArrayList(); @@ -129,10 +126,10 @@ public class SecondaryStoreCacheService private final MultiplexingNodeStateDiffer differ = new MultiplexingNodeStateDiffer(); @Activate - private void activate(BundleContext context, Map<String, Object> config){ + private void activate(BundleContext context, Configuration config){ bundleContext = context; whiteboard = new OsgiWhiteboard(context); - String[] includedPaths = toStringArray(config.get(PROP_INCLUDES), new String[]{"/"}); + String[] includedPaths = config.includedPaths(); //TODO Support for exclude is not possible as once a NodeState is loaded from secondary //store it assumes that complete subtree is in same store. With exclude it would need to @@ -180,9 +177,9 @@ public class SecondaryStoreCacheService //~----------------------------------------------------< internal > - private void registerObserver(Observer observer, Map<String, Object> config) { - boolean enableAsyncObserver = toBoolean(config.get(PROP_ASYNC_OBSERVER), PROP_ASYNC_OBSERVER_DEFAULT); - int queueSize = toInteger(config.get(PROP_OBSERVER_QUEUE_SIZE), PROP_OBSERVER_QUEUE_SIZE_DEFAULT); + private void registerObserver(Observer observer, Configuration config) { + boolean enableAsyncObserver = config.enableAsyncObserver(); + int queueSize = config.observerQueueSize(); if (enableAsyncObserver){ BackgroundObserver bgObserver = new BackgroundObserver(observer, executor, queueSize); oakRegs.add(registerMBean(whiteboard, Modified: jackrabbit/oak/trunk/oak-store-spi/pom.xml URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-spi/pom.xml?rev=1810002&r1=1810001&r2=1810002&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-spi/pom.xml (original) +++ jackrabbit/oak/trunk/oak-store-spi/pom.xml Thu Sep 28 14:09:26 2017 @@ -91,11 +91,6 @@ <artifactId>org.osgi.compendium</artifactId> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.apache.felix</groupId> - <artifactId>org.apache.felix.scr.annotations</artifactId> - <scope>provided</scope> - </dependency> <!-- Dependencies to other Oak components --> <dependency>
