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=1817183&r1=1817182&r2=1817183&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 Tue Dec 5 12:41:23 2017 @@ -23,8 +23,10 @@ import static com.google.common.collect. import static java.util.Collections.emptyList; import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly; import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toLong; -import static org.apache.jackrabbit.oak.plugins.document.DocumentMK.Builder.DEFAULT_MEMORY_CACHE_SIZE; +import static org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder.DEFAULT_MEMORY_CACHE_SIZE; import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS_RESOLUTION; +import static org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentNodeStoreBuilder.newMongoDocumentNodeStoreBuilder; +import static org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentNodeStoreBuilder.newRDBDocumentNodeStoreBuilder; import static org.apache.jackrabbit.oak.spi.blob.osgi.SplitBlobStoreService.ONLY_STANDALONE_TARGET; import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean; import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.scheduleWithFixedDelay; @@ -63,6 +65,8 @@ import org.apache.jackrabbit.oak.api.jmx import org.apache.jackrabbit.oak.api.jmx.PersistentCacheStatsMBean; import org.apache.jackrabbit.oak.cache.CacheStats; import org.apache.jackrabbit.oak.plugins.document.VersionGarbageCollector.VersionGCStats; +import org.apache.jackrabbit.oak.plugins.document.mongo.MongoDocumentNodeStoreBuilder; +import org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentNodeStoreBuilder; import org.apache.jackrabbit.oak.plugins.document.util.Utils; import org.apache.jackrabbit.oak.spi.commit.ObserverTracker; import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard; @@ -248,83 +252,31 @@ public class DocumentNodeStoreService { } private void registerNodeStore() throws IOException { - 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(config.cache() * MB). - memoryCacheDistribution( - 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() { - - @Override - public void handleLeaseFailure() { - try { - // plan A: try stopping oak-core - log.error("handleLeaseFailure: stopping oak-core..."); - Bundle bundle = context.getBundleContext().getBundle(); - bundle.stop(Bundle.STOP_TRANSIENT); - log.error("handleLeaseFailure: stopped oak-core."); - // plan A worked, perfect! - } catch (BundleException e) { - log.error("handleLeaseFailure: exception while stopping oak-core: "+e, e); - // plan B: stop only DocumentNodeStoreService (to stop the background threads) - log.error("handleLeaseFailure: stopping DocumentNodeStoreService..."); - context.disableComponent(DocumentNodeStoreService.class.getName()); - log.error("handleLeaseFailure: stopped DocumentNodeStoreService"); - // plan B succeeded. - } - } - }). - setPrefetchExternalChanges(config.prefetchExternalChanges()). - setUpdateLimit(config.updateLimit()). - setJournalGCMaxAge(config.journalGCMaxAge()). - setNodeCachePredicate(createCachePredicate()); - - if (!Strings.isNullOrEmpty(persistentCache)) { - mkBuilder.setPersistentCache(persistentCache); - } - if (!Strings.isNullOrEmpty(journalCache)) { - mkBuilder.setJournalCache(journalCache); - } - - boolean wrappingCustomBlobStore = customBlobStore && blobStore instanceof BlobStoreWrapper; - - //Set blobstore before setting the DB - if (customBlobStore && !wrappingCustomBlobStore) { - checkNotNull(blobStore, "Use of custom BlobStore enabled via [%s] but blobStore reference not " + - "initialized", CUSTOM_BLOB_STORE); - mkBuilder.setBlobStore(blobStore); - } - + DocumentNodeStoreBuilder mkBuilder; if (documentStoreType == DocumentStoreType.RDB) { + RDBDocumentNodeStoreBuilder builder = newRDBDocumentNodeStoreBuilder(); + configureBuilder(builder); checkNotNull(dataSource, "DataStore type set [%s] but DataSource reference not initialized", PROP_DS_TYPE); if (!customBlobStore) { checkNotNull(blobDataSource, "DataStore type set [%s] but BlobDataSource reference not initialized", PROP_DS_TYPE); - mkBuilder.setRDBConnection(dataSource, blobDataSource); + builder.setRDBConnection(dataSource, blobDataSource); log.info("Connected to datasources {} {}", dataSource, blobDataSource); } else { if (blobDataSource != null && blobDataSource != dataSource) { log.info("Ignoring blobDataSource {} as custom blob store takes precedence.", blobDataSource); } - mkBuilder.setRDBConnection(dataSource); + builder.setRDBConnection(dataSource); log.info("Connected to datasource {}", dataSource); } + mkBuilder = builder; } else { String uri = config.mongouri(); String db = config.db(); boolean soKeepAlive = config.socketKeepAlive(); MongoClientURI mongoURI = new MongoClientURI(uri); + String persistentCache = resolvePath(config.persistentCache(), DEFAULT_PERSISTENT_CACHE); + String journalCache = resolvePath(config.journalCache(), DEFAULT_JOURNAL_CACHE); if (log.isInfoEnabled()) { // Take care around not logging the uri directly as it @@ -336,9 +288,12 @@ public class DocumentNodeStoreService { log.info("Mongo Connection details {}", MongoConnection.toString(mongoURI.getOptions())); } - mkBuilder.setMaxReplicationLag(config.maxReplicationLagInSecs(), TimeUnit.SECONDS); - mkBuilder.setSocketKeepAlive(soKeepAlive); - mkBuilder.setMongoDB(uri, db, config.blobCacheSize()); + MongoDocumentNodeStoreBuilder builder = newMongoDocumentNodeStoreBuilder(); + configureBuilder(builder); + builder.setMaxReplicationLag(config.maxReplicationLagInSecs(), TimeUnit.SECONDS); + builder.setSocketKeepAlive(soKeepAlive); + builder.setMongoDB(uri, db, config.blobCacheSize()); + mkBuilder = builder; log.info("Connected to database '{}'", db); } @@ -351,7 +306,7 @@ public class DocumentNodeStoreService { } //Set wrapping blob store after setting the DB - if (wrappingCustomBlobStore) { + if (isWrappingCustomBlobStore()) { ((BlobStoreWrapper) blobStore).setBlobStore(mkBuilder.getBlobStore()); mkBuilder.setBlobStore(blobStore); } @@ -373,7 +328,7 @@ public class DocumentNodeStoreService { mkBuilder.setGCMonitor(new DelegatingGCMonitor( newArrayList(gcMonitor, loggingGCMonitor))); - nodeStore = mkBuilder.getNodeStore(); + nodeStore = mkBuilder.build(); // ensure a clusterId is initialized // and expose it as 'oak.clusterid' repository descriptor @@ -463,6 +418,66 @@ public class DocumentNodeStoreService { nodeStore, props); } + private void configureBuilder(DocumentNodeStoreBuilder builder) { + String persistentCache = resolvePath(config.persistentCache(), DEFAULT_PERSISTENT_CACHE); + String journalCache = resolvePath(config.journalCache(), DEFAULT_JOURNAL_CACHE); + builder.setStatisticsProvider(statisticsProvider). + memoryCacheSize(config.cache() * MB). + memoryCacheDistribution( + 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() { + + @Override + public void handleLeaseFailure() { + try { + // plan A: try stopping oak-core + log.error("handleLeaseFailure: stopping oak-core..."); + Bundle bundle = context.getBundleContext().getBundle(); + bundle.stop(Bundle.STOP_TRANSIENT); + log.error("handleLeaseFailure: stopped oak-core."); + // plan A worked, perfect! + } catch (BundleException e) { + log.error("handleLeaseFailure: exception while stopping oak-core: "+e, e); + // plan B: stop only DocumentNodeStoreService (to stop the background threads) + log.error("handleLeaseFailure: stopping DocumentNodeStoreService..."); + context.disableComponent(DocumentNodeStoreService.class.getName()); + log.error("handleLeaseFailure: stopped DocumentNodeStoreService"); + // plan B succeeded. + } + } + }). + setPrefetchExternalChanges(config.prefetchExternalChanges()). + setUpdateLimit(config.updateLimit()). + setJournalGCMaxAge(config.journalGCMaxAge()). + setNodeCachePredicate(createCachePredicate()); + + if (!Strings.isNullOrEmpty(persistentCache)) { + builder.setPersistentCache(persistentCache); + } + if (!Strings.isNullOrEmpty(journalCache)) { + builder.setJournalCache(journalCache); + } + + //Set blobstore before setting the document store + if (customBlobStore && !isWrappingCustomBlobStore()) { + checkNotNull(blobStore, "Use of custom BlobStore enabled via [%s] but blobStore reference not " + + "initialized", CUSTOM_BLOB_STORE); + builder.setBlobStore(blobStore); + } + } + + private boolean isWrappingCustomBlobStore() { + return customBlobStore && blobStore instanceof BlobStoreWrapper; + } + private Predicate<String> createCachePredicate() { if (config.persistentCacheIncludes().length == 0) { return Predicates.alwaysTrue(); @@ -671,7 +686,7 @@ public class DocumentNodeStoreService { } } - private void registerJMXBeans(final DocumentNodeStore store, DocumentMK.Builder mkBuilder) throws + private void registerJMXBeans(final DocumentNodeStore store, DocumentNodeStoreBuilder mkBuilder) throws IOException { registerCacheStatsMBean(store.getNodeCacheStats()); registerCacheStatsMBean(store.getNodeChildrenCacheStats());
Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java?rev=1817183&r1=1817182&r2=1817183&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java Tue Dec 5 12:41:23 2017 @@ -49,7 +49,7 @@ public class LocalDiffCache extends Diff private final Cache<RevisionsKey, Diff> diffCache; private final CacheStats diffCacheStats; - LocalDiffCache(DocumentMK.Builder builder) { + LocalDiffCache(DocumentNodeStoreBuilder builder) { this.diffCache = builder.buildLocalDiffCache(); this.diffCacheStats = new CacheStats(diffCache, "Document-LocalDiff", Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java?rev=1817183&r1=1817182&r2=1817183&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java Tue Dec 5 12:41:23 2017 @@ -59,7 +59,7 @@ public class MemoryDiffCache extends Dif protected final CacheStats diffCacheStats; - protected MemoryDiffCache(DocumentMK.Builder builder) { + protected MemoryDiffCache(DocumentNodeStoreBuilder builder) { diffCache = builder.buildMemoryDiffCache(); diffCacheStats = new CacheStats(diffCache, "Document-MemoryDiff", builder.getWeigher(), builder.getMemoryDiffCacheSize()); Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java?rev=1817183&r1=1817182&r2=1817183&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java Tue Dec 5 12:41:23 2017 @@ -32,7 +32,7 @@ class TieredDiffCache extends DiffCache private final DiffCache localCache; private final DiffCache memoryCache; - TieredDiffCache(DocumentMK.Builder builder) { + TieredDiffCache(DocumentNodeStoreBuilder builder) { this.localCache = new LocalDiffCache(builder); this.memoryCache = new MemoryDiffCache(builder); } Added: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilder.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilder.java?rev=1817183&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilder.java (added) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilder.java Tue Dec 5 12:41:23 2017 @@ -0,0 +1,222 @@ +/* + * 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.mongo; + +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nonnull; + +import com.mongodb.DB; +import com.mongodb.MongoClientOptions; +import com.mongodb.ReadConcernLevel; + +import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder; +import org.apache.jackrabbit.oak.plugins.document.DocumentStore; +import org.apache.jackrabbit.oak.plugins.document.MissingLastRevSeeker; +import org.apache.jackrabbit.oak.plugins.document.VersionGCSupport; +import org.apache.jackrabbit.oak.plugins.document.util.MongoConnection; +import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.google.common.base.Suppliers.memoize; +import static org.apache.jackrabbit.oak.plugins.document.util.MongoConnection.readConcernLevel; + +/** + * A builder for a {@link DocumentNodeStore} backed by MongoDB. + */ +public class MongoDocumentNodeStoreBuilder<T extends MongoDocumentNodeStoreBuilder<T>> + extends DocumentNodeStoreBuilder<T> { + + private static final Logger LOG = LoggerFactory.getLogger(MongoDocumentNodeStoreBuilder.class); + + private String mongoUri; + private boolean socketKeepAlive; + private MongoStatus mongoStatus; + private long maxReplicationLagMillis = TimeUnit.HOURS.toMillis(6); + + /** + * @return a new {@link MongoDocumentNodeStoreBuilder}. + */ + public static MongoDocumentNodeStoreBuilder newMongoDocumentNodeStoreBuilder() { + return new MongoDocumentNodeStoreBuilder(); + } + + @SuppressWarnings("unchecked") + @Override + protected T thisBuilder() { + return (T) this; + } + + /** + * Uses the given information to connect to to MongoDB as backend + * storage for the DocumentNodeStore. The write concern is either + * taken from the URI or determined automatically based on the MongoDB + * setup. When running on a replica set without explicit write concern + * in the URI, the write concern will be {@code MAJORITY}, otherwise + * {@code ACKNOWLEDGED}. + * + * @param uri a MongoDB URI. + * @param name the name of the database to connect to. This overrides + * any database name given in the {@code uri}. + * @param blobCacheSizeMB the blob cache size in MB. + * @return this + * @throws UnknownHostException if one of the hosts given in the URI + * is unknown. + */ + public T setMongoDB(@Nonnull String uri, + @Nonnull String name, + int blobCacheSizeMB) + throws UnknownHostException { + this.mongoUri = uri; + + MongoClientOptions.Builder options = MongoConnection.getDefaultBuilder(); + options.socketKeepAlive(socketKeepAlive); + DB db = new MongoConnection(uri, options).getDB(name); + MongoStatus status = new MongoStatus(db); + if (!MongoConnection.hasWriteConcern(uri)) { + db.setWriteConcern(MongoConnection.getDefaultWriteConcern(db)); + } + if (status.isMajorityReadConcernSupported() && status.isMajorityReadConcernEnabled() && !MongoConnection.hasReadConcern(uri)) { + db.setReadConcern(MongoConnection.getDefaultReadConcern(db)); + } + setMongoDB(db, status, blobCacheSizeMB); + return thisBuilder(); + } + + /** + * Use the given MongoDB as backend storage for the DocumentNodeStore. + * + * @param db the MongoDB connection + * @return this + */ + public T setMongoDB(@Nonnull DB db, + int blobCacheSizeMB) { + return setMongoDB(db, new MongoStatus(db), blobCacheSizeMB); + } + + /** + * Use the given MongoDB as backend storage for the DocumentNodeStore. + * + * @param db the MongoDB connection + * @return this + */ + public T setMongoDB(@Nonnull DB db) { + return setMongoDB(db, 16); + } + + /** + * Enables the socket keep-alive option for MongoDB. The default is + * disabled. + * + * @param enable whether to enable it. + * @return this + */ + public T setSocketKeepAlive(boolean enable) { + this.socketKeepAlive = enable; + return thisBuilder(); + } + + public T setMaxReplicationLag(long duration, TimeUnit unit){ + maxReplicationLagMillis = unit.toMillis(duration); + return thisBuilder(); + } + + public VersionGCSupport createVersionGCSupport() { + DocumentStore store = getDocumentStore(); + if (store instanceof MongoDocumentStore) { + return new MongoVersionGCSupport((MongoDocumentStore) store); + } else { + return super.createVersionGCSupport(); + } + } + + public Iterable<ReferencedBlob> createReferencedBlobs(DocumentNodeStore ns) { + final DocumentStore store = getDocumentStore(); + if (store instanceof MongoDocumentStore) { + return () -> new MongoBlobReferenceIterator(ns, (MongoDocumentStore) store); + } else { + return super.createReferencedBlobs(ns); + } + } + + public MissingLastRevSeeker createMissingLastRevSeeker() { + final DocumentStore store = getDocumentStore(); + if (store instanceof MongoDocumentStore) { + return new MongoMissingLastRevSeeker((MongoDocumentStore) store, getClock()); + } else { + return super.createMissingLastRevSeeker(); + } + } + + /** + * Returns the Mongo URI used in the {@link #setMongoDB(String, String, int)} method. + * + * @return the Mongo URI or null if the {@link #setMongoDB(String, String, int)} method hasn't + * been called. + */ + String getMongoUri() { + return mongoUri; + } + + /** + * Returns the status of the Mongo server configured in the {@link #setMongoDB(String, String, int)} method. + * + * @return the status or null if the {@link #setMongoDB(String, String, int)} method hasn't + * been called. + */ + MongoStatus getMongoStatus() { + return mongoStatus; + } + + long getMaxReplicationLagMillis() { + return maxReplicationLagMillis; + } + + private T setMongoDB(@Nonnull DB db, + MongoStatus status, + int blobCacheSizeMB) { + if (!MongoConnection.hasSufficientWriteConcern(db)) { + LOG.warn("Insufficient write concern: " + db.getWriteConcern() + + " At least " + MongoConnection.getDefaultWriteConcern(db) + " is recommended."); + } + if (status.isMajorityReadConcernSupported() && !status.isMajorityReadConcernEnabled()) { + LOG.warn("The read concern should be enabled on mongod using --enableMajorityReadConcern"); + } else if (status.isMajorityReadConcernSupported() && !MongoConnection.hasSufficientReadConcern(db)) { + ReadConcernLevel currentLevel = readConcernLevel(db.getReadConcern()); + ReadConcernLevel recommendedLevel = readConcernLevel(MongoConnection.getDefaultReadConcern(db)); + if (currentLevel == null) { + LOG.warn("Read concern hasn't been set. At least " + recommendedLevel + " is recommended."); + } else { + LOG.warn("Insufficient read concern: " + currentLevel + ". At least " + recommendedLevel + " is recommended."); + } + } + + this.mongoStatus = status; + this.documentStoreSupplier = memoize(() -> new MongoDocumentStore( + db, MongoDocumentNodeStoreBuilder.this)); + + if (this.blobStore == null) { + GarbageCollectableBlobStore s = new MongoBlobStore(db, blobCacheSizeMB * 1024 * 1024L); + setGCBlobStore(s); + } + return thisBuilder(); + } +} Propchange: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilder.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1817183&r1=1817182&r2=1817183&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java Tue Dec 5 12:41:23 2017 @@ -54,7 +54,6 @@ import org.apache.jackrabbit.oak.cache.C import org.apache.jackrabbit.oak.cache.CacheValue; import org.apache.jackrabbit.oak.plugins.document.Collection; import org.apache.jackrabbit.oak.plugins.document.Document; -import org.apache.jackrabbit.oak.plugins.document.DocumentMK; import org.apache.jackrabbit.oak.plugins.document.DocumentStore; import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException; import org.apache.jackrabbit.oak.plugins.document.DocumentStoreStatsCollector; @@ -231,7 +230,7 @@ public class MongoDocumentStore implemen private static final Key KEY_MODIFIED = new Key(MODIFIED_IN_SECS, null); - public MongoDocumentStore(DB db, DocumentMK.Builder builder) { + public MongoDocumentStore(DB db, MongoDocumentNodeStoreBuilder builder) { MongoStatus mongoStatus = builder.getMongoStatus(); if (mongoStatus == null) { mongoStatus = new MongoStatus(db); Added: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java?rev=1817183&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java (added) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java Tue Dec 5 12:41:23 2017 @@ -0,0 +1,107 @@ +/* + * 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.rdb; + +import javax.sql.DataSource; + +import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder; +import org.apache.jackrabbit.oak.plugins.document.DocumentStore; +import org.apache.jackrabbit.oak.plugins.document.VersionGCSupport; +import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore; + +import static com.google.common.base.Suppliers.ofInstance; + +/** + * A builder for a {@link DocumentNodeStore} backed by a relational database. + */ +public class RDBDocumentNodeStoreBuilder<T extends RDBDocumentNodeStoreBuilder<T>> + extends DocumentNodeStoreBuilder<T> { + + /** + * @return a new {@link RDBDocumentNodeStoreBuilder}. + */ + public static RDBDocumentNodeStoreBuilder newRDBDocumentNodeStoreBuilder() { + return new RDBDocumentNodeStoreBuilder(); + } + + @SuppressWarnings("unchecked") + @Override + protected T thisBuilder() { + return (T) this; + } + + /** + * Sets a {@link DataSource} to use for the RDB document and blob + * stores. + * + * @return this + */ + public T setRDBConnection(DataSource ds) { + setRDBConnection(ds, new RDBOptions()); + return thisBuilder(); + } + + /** + * Sets a {@link DataSource} to use for the RDB document and blob + * stores, including {@link RDBOptions}. + * + * @return this + */ + public T setRDBConnection(DataSource ds, RDBOptions options) { + this.documentStoreSupplier = ofInstance(new RDBDocumentStore(ds, this, options)); + if(blobStore == null) { + GarbageCollectableBlobStore s = new RDBBlobStore(ds, options); + setGCBlobStore(s); + } + return thisBuilder(); + } + + /** + * Sets a {@link DataSource}s to use for the RDB document and blob + * stores. + * + * @return this + */ + public T setRDBConnection(DataSource documentStoreDataSource, DataSource blobStoreDataSource) { + this.documentStoreSupplier = ofInstance(new RDBDocumentStore(documentStoreDataSource, this)); + if(blobStore == null) { + GarbageCollectableBlobStore s = new RDBBlobStore(blobStoreDataSource); + setGCBlobStore(s); + } + return thisBuilder(); + } + + public VersionGCSupport createVersionGCSupport() { + DocumentStore store = getDocumentStore(); + if (store instanceof RDBDocumentStore) { + return new RDBVersionGCSupport((RDBDocumentStore) store); + } else { + return super.createVersionGCSupport(); + } + } + + public Iterable<ReferencedBlob> createReferencedBlobs(DocumentNodeStore ns) { + final DocumentStore store = getDocumentStore(); + if (store instanceof RDBDocumentStore) { + return () -> new RDBBlobReferenceIterator(ns, (RDBDocumentStore) store); + } else { + return super.createReferencedBlobs(ns); + } + } +} Propchange: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentNodeStoreBuilder.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1817183&r1=1817182&r2=1817183&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java (original) +++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java Tue Dec 5 12:41:23 2017 @@ -66,7 +66,7 @@ import org.apache.jackrabbit.oak.cache.C import org.apache.jackrabbit.oak.cache.CacheValue; import org.apache.jackrabbit.oak.plugins.document.Collection; import org.apache.jackrabbit.oak.plugins.document.Document; -import org.apache.jackrabbit.oak.plugins.document.DocumentMK; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBuilder; import org.apache.jackrabbit.oak.plugins.document.DocumentStore; import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException; import org.apache.jackrabbit.oak.plugins.document.DocumentStoreStatsCollector; @@ -233,9 +233,9 @@ public class RDBDocumentStore implements /** * Creates a {@linkplain RDBDocumentStore} instance using the provided - * {@link DataSource}, {@link DocumentMK.Builder}, and {@link RDBOptions}. + * {@link DataSource}, {@link DocumentNodeStoreBuilder}, and {@link RDBOptions}. */ - public RDBDocumentStore(DataSource ds, DocumentMK.Builder builder, RDBOptions options) { + public RDBDocumentStore(DataSource ds, DocumentNodeStoreBuilder builder, RDBOptions options) { try { initialize(ds, builder, options); } catch (Exception ex) { @@ -245,10 +245,10 @@ public class RDBDocumentStore implements /** * Creates a {@linkplain RDBDocumentStore} instance using the provided - * {@link DataSource}, {@link DocumentMK.Builder}, and default + * {@link DataSource}, {@link DocumentNodeStoreBuilder}, and default * {@link RDBOptions}. */ - public RDBDocumentStore(DataSource ds, DocumentMK.Builder builder) { + public RDBDocumentStore(DataSource ds, DocumentNodeStoreBuilder builder) { this(ds, builder, new RDBOptions()); } @@ -829,7 +829,7 @@ public class RDBDocumentStore implements private final RDBDocumentSerializer ser = new RDBDocumentSerializer(this); - private void initialize(DataSource ds, DocumentMK.Builder builder, RDBOptions options) throws Exception { + private void initialize(DataSource ds, DocumentNodeStoreBuilder builder, RDBOptions options) throws Exception { this.stats = builder.getDocumentStoreStatsCollector(); this.tableMeta.put(Collection.NODES, new RDBTableMetaData(createTableName(options.getTablePrefix(), TABLEMAP.get(Collection.NODES))));
