You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2018/10/02 11:02:44 UTC
svn commit: r1842610 - in /jackrabbit/oak/trunk:
oak-it/src/test/java/org/apache/jackrabbit/oak/composite/
oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/
oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/
Author: tomekr
Date: Tue Oct 2 11:02:44 2018
New Revision: 1842610
URL: http://svn.apache.org/viewvc?rev=1842610&view=rev
Log:
OAK-7796: Remove the support for the writeable partial stores
Modified:
jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreService.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java
jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/package-info.java
jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeChildrenCountTest.java
jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeCompareTest.java
Modified: jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-it/src/test/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreTest.java Tue Oct 2 11:02:44 2018
@@ -59,7 +59,6 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBDataSourceFactory;
import org.apache.jackrabbit.oak.plugins.document.rdb.RDBOptions;
-import org.apache.jackrabbit.oak.plugins.document.util.CountingDiff;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
@@ -121,9 +120,9 @@ public class CompositeNodeStoreTest {
@Before
public void initStore() throws Exception {
mip = Mounts.newBuilder()
- .mount("temp", "/tmp")
- .mount("deep", "/libs/mount")
- .mount("empty", "/nowhere")
+ .readOnlyMount("temp", "/tmp")
+ .readOnlyMount("deep", "/libs/mount")
+ .readOnlyMount("empty", "/nowhere")
.readOnlyMount("readOnly", "/readOnly")
.build();
@@ -272,19 +271,7 @@ public class CompositeNodeStoreTest {
globalBuilder.child("new");
globalStore.merge(globalBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
- // create a new child /tmp/new in the mounted store
- NodeBuilder mountedBuilder = mountedStore.getRoot().builder();
- mountedBuilder.getChildNode("tmp").child("new");
- mountedStore.merge(mountedBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- // create a new child /libs/mount/new in the deeply mounted store
- NodeBuilder deepMountBuilder = deepMountedStore.getRoot().builder();
- deepMountBuilder.getChildNode("libs").getChildNode("mount").child("new");
- deepMountedStore.merge(deepMountBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
assertFalse("store incorrectly exposes child at /new", store.retrieve(checkpoint).hasChildNode("new"));
- assertFalse("store incorrectly exposes child at /tmp/new", store.retrieve(checkpoint).getChildNode("tmp").hasChildNode("new"));
- assertFalse("store incorrectly exposes child at /libs/mount/new", store.retrieve(checkpoint).getChildNode("libs").getChildNode("mount").hasChildNode("new"));
}
@Test
@@ -374,19 +361,6 @@ public class CompositeNodeStoreTest {
}
@Test
- public void createNodeInMountedStore() throws Exception {
-
- NodeBuilder builder = store.getRoot().builder();
-
- builder.getChildNode("tmp").child("newNode");
-
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- assertTrue("Node must be added to composite store", store.getRoot().getChildNode("tmp").hasChildNode("newNode"));
- assertTrue("Node must be added to owning (mounted) store", mountedStore.getRoot().getChildNode("tmp").hasChildNode("newNode"));
- }
-
- @Test
public void removeNodeInRootStore() throws Exception {
NodeBuilder builder = store.getRoot().builder();
@@ -398,27 +372,6 @@ public class CompositeNodeStoreTest {
assertFalse("Node must be removed from the owning (root) store", globalStore.getRoot().hasChildNode("apps"));
}
-
- @Test
- public void removeNodeInMountedStore() throws Exception {
- NodeBuilder builder = store.getRoot().builder();
-
- builder.getChildNode("tmp").child("newNode");
-
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- assertTrue("Node must be added to composite store", store.getRoot().getChildNode("tmp").hasChildNode("newNode"));
-
- builder = store.getRoot().builder();
-
- builder.getChildNode("tmp").getChildNode("newNode").remove();
-
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- assertFalse("Node must be removed from the composite store", store.getRoot().getChildNode("tmp").hasChildNode("newNode"));
- assertFalse("Node must be removed from the owning (composite) store", globalStore.getRoot().getChildNode("tmp").hasChildNode("newNode"));
- }
-
@Test
public void builderChildrenCountInRootStore() throws Exception {
assertThat("root(childCount)", store.getRoot().builder().getChildNodeCount(100), equalTo(4l));
@@ -481,20 +434,6 @@ public class CompositeNodeStoreTest {
assertThat("Node apps must not have any properties", store.getRoot().getChildNode("apps").getPropertyCount(), equalTo(0l));
}
-
- @Test
- public void setChildNodeInMountStore() throws Exception {
- NodeBuilder builder = store.getRoot().builder();
-
- builder.getChildNode("tmp").setChildNode("child1");
-
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- assertTrue("Node child1 must still exist", store.getRoot().getChildNode("tmp").hasChildNode("child1"));
- assertThat("Node child1 must not have any properties", store.getRoot().getChildNode("tmp").getChildNode("child1").getPropertyCount(), equalTo(0l));
- }
-
-
@Test
public void builderBasedOnRootStoreChildNode() throws Exception {
NodeBuilder builder = store.getRoot().builder();
@@ -513,24 +452,6 @@ public class CompositeNodeStoreTest {
}
@Test
- public void builderBasedOnMountStoreChildNode() throws Exception {
- NodeBuilder builder = store.getRoot().builder();
- NodeBuilder tmpBuilder = builder.getChildNode("tmp");
-
- tmpBuilder.removeProperty("prop1");
- tmpBuilder.setChildNode("child3");
-
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- assertFalse("Node tmp must have no properties (composite store)", store.getRoot().getChildNode("tmp").hasProperty("prop1"));
- assertFalse("Node tmp must have no properties (mounted store)", mountedStore.getRoot().getChildNode("tmp").hasProperty("prop1"));
-
- assertTrue("Node /tmp/build3 must exist (composite store)", store.getRoot().getChildNode("tmp").hasChildNode("child3"));
- assertTrue("Node /tmp/child3 must exist (mounted store)", mountedStore.getRoot().getChildNode("tmp").hasChildNode("child3"));
-
- }
-
- @Test
public void freshBuilderForGlobalStore() {
NodeBuilder builder = store.getRoot().builder();
@@ -657,17 +578,6 @@ public class CompositeNodeStoreTest {
}
@Test
- public void resetOnMountedStore() {
- NodeBuilder rootBuilder = store.getRoot().builder();
- NodeBuilder builder = rootBuilder.getChildNode("tmp");
- builder.child("newChild");
-
- store.reset(rootBuilder);
-
- assertFalse("Newly added child should no longer be visible after reset", builder.getChildNode("tmp").hasChildNode("newChild"));
- }
-
- @Test
public void oldNodeStateDoesNotRefreshOnGlobalStore() throws Exception {
NodeState old = store.getRoot();
@@ -681,21 +591,6 @@ public class CompositeNodeStoreTest {
assertFalse("old NodeState should not see newly added child node after merge ", old.hasChildNode("newNode"));
}
- @Test
- public void oldNodeStateDoesNotRefreshOnMountedStore() throws Exception {
- NodeState old = store.getRoot();
-
- NodeBuilder builder = store.getRoot().builder();
-
- builder.getChildNode("tmp").child("newNode");
-
- assertFalse("old NodeState should not see newly added child node before merge ", old.getChildNode("tmp").hasChildNode("newNode"));
-
- store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- assertFalse("old NodeState should not see newly added child node after merge ", old.getChildNode("tmp").hasChildNode("newNode"));
- }
-
// this test ensures that when going from State -> Builder -> State -> Builder the state is properly maintained
@Test
public void nestedBuilderFromState() throws Exception {
@@ -741,20 +636,8 @@ public class CompositeNodeStoreTest {
globalBuilder.child("new");
globalStore.merge(globalBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
- // create a new child /tmp/new in the mounted store
- NodeBuilder mountedBuilder = mountedStore.getRoot().builder();
- mountedBuilder.getChildNode("tmp").child("new");
- mountedStore.merge(mountedBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
- // create a new child /libs/mount/new in the deeply mounted store
- NodeBuilder deepMountBuilder = deepMountedStore.getRoot().builder();
- deepMountBuilder.getChildNode("libs").getChildNode("mount").child("new");
- deepMountedStore.merge(deepMountBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
NodeBuilder rootCheckpointBuilder = store.retrieve(checkpoint).builder();
assertFalse("store incorrectly exposes child at /new", rootCheckpointBuilder.hasChildNode("new"));
- assertFalse("store incorrectly exposes child at /tmp/new", rootCheckpointBuilder.getChildNode("tmp").hasChildNode("new"));
- assertFalse("store incorrectly exposes child at /libs/mount/new", rootCheckpointBuilder.getChildNode("libs").getChildNode("mount").hasChildNode("new"));
}
@Test
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CommitHookEnhancer.java Tue Oct 2 11:02:44 2018
@@ -49,14 +49,9 @@ class CommitHookEnhancer implements Comm
Map<MountedNodeStore, NodeState> beforeStates = newHashMap();
Map<MountedNodeStore, NodeState> afterStates = newHashMap();
for (MountedNodeStore mns : ctx.getNonDefaultStores()) {
- if (mns.getMount().isReadOnly()) {
- NodeState root = mns.getNodeStore().getRoot();
- afterStates.put(mns, root);
- beforeStates.put(mns, root);
- } else {
- afterStates.put(mns, mns.getNodeStore().rebase(builder.getNodeBuilder(mns)));
- beforeStates.put(mns, builder.getNodeBuilder(mns).getBaseState());
- }
+ NodeState root = mns.getNodeStore().getRoot();
+ afterStates.put(mns, root);
+ beforeStates.put(mns, root);
}
afterStates.put(ctx.getGlobalStore(), after);
beforeStates.put(ctx.getGlobalStore(), before);
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStore.java Tue Oct 2 11:02:44 2018
@@ -29,7 +29,6 @@ import org.apache.jackrabbit.oak.composi
import org.apache.jackrabbit.oak.spi.commit.ChangeDispatcher;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
import org.apache.jackrabbit.oak.spi.commit.Observable;
import org.apache.jackrabbit.oak.spi.commit.Observer;
import org.apache.jackrabbit.oak.spi.mount.Mount;
@@ -37,7 +36,6 @@ import org.apache.jackrabbit.oak.spi.mou
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,9 +47,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeSet;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -61,11 +59,7 @@ import static com.google.common.collect.
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Maps.filterKeys;
import static com.google.common.collect.Maps.newHashMap;
-import static com.google.common.collect.Sets.difference;
-import static com.google.common.collect.Sets.filter;
-import static com.google.common.collect.Sets.newHashSet;
import static java.lang.System.currentTimeMillis;
-import static org.apache.jackrabbit.oak.commons.PathUtils.isAncestor;
import static org.apache.jackrabbit.oak.composite.ModifiedPathDiff.getModifiedPaths;
/**
@@ -98,42 +92,48 @@ public class CompositeNodeStore implemen
private static final String CHECKPOINT_METADATA_MOUNT = CHECKPOINT_METADATA + "mount.";
- private final TreeSet<String> ignoreReadOnlyWritePaths;
-
final CompositionContext ctx;
private final ChangeDispatcher dispatcher;
- private final Lock mergeLock;
+ private final Lock mergeLock = new ReentrantLock();
// visible for testing only
CompositeNodeStore(MountInfoProvider mip, NodeStore globalStore, List<MountedNodeStore> nonDefaultStore) {
- this(mip, globalStore, nonDefaultStore, Collections.<String>emptyList(), CompositeNodeStoreMonitor.EMPTY_INSTANCE, CompositeNodeStoreMonitor.EMPTY_INSTANCE);
+ this(mip, globalStore, nonDefaultStore, CompositeNodeStoreMonitor.EMPTY_INSTANCE, CompositeNodeStoreMonitor.EMPTY_INSTANCE);
}
- CompositeNodeStore(MountInfoProvider mip, NodeStore globalStore, List<MountedNodeStore> nonDefaultStore, List<String> ignoreReadOnlyWritePaths, CompositeNodeStoreMonitor nodeStateMonitor, CompositeNodeStoreMonitor nodeBuilderMonitor) {
+ CompositeNodeStore(MountInfoProvider mip, NodeStore globalStore, List<MountedNodeStore> nonDefaultStore, CompositeNodeStoreMonitor nodeStateMonitor, CompositeNodeStoreMonitor nodeBuilderMonitor) {
+ assertPartialMountsAreReadOnly(nonDefaultStore);
+
this.ctx = new CompositionContext(mip, globalStore, nonDefaultStore, nodeStateMonitor, nodeBuilderMonitor);
- this.ignoreReadOnlyWritePaths = new TreeSet<>(ignoreReadOnlyWritePaths);
- this.mergeLock = new ReentrantLock();
this.dispatcher = new ChangeDispatcher(getRoot());
// setup observation proxy mechanism for underlying store for events not dispatched from within our
// merge
if (globalStore instanceof Observable) {
Observable globalStoreObservable = (Observable) globalStore;
- globalStoreObservable.addObserver(new MountedNodeStoreObserver());
+ globalStoreObservable.addObserver((root, info) -> dispatcher.contentChanged(ctx.createRootNodeState(root), info));
}
}
+ private static void assertPartialMountsAreReadOnly(List<MountedNodeStore> nonDefaultStores) {
+ List<String> readWriteMountNames = nonDefaultStores
+ .stream()
+ .map(MountedNodeStore::getMount)
+ .filter(m -> !m.isReadOnly())
+ .map(Mount::getName)
+ .collect(Collectors.toList());
+
+ checkArgument(readWriteMountNames.isEmpty(),
+ "Following partial mounts are write-enabled: ", readWriteMountNames);
+ }
+
@Override
public NodeState getRoot() {
// the composite root state exposes the node states as they are
// at this certain point in time, so we eagerly retrieve them from all stores
- Map<MountedNodeStore, NodeState> nodeStates = newHashMap();
- for (MountedNodeStore nodeStore : ctx.getAllMountedNodeStores()) {
- nodeStates.put(nodeStore, nodeStore.getNodeStore().getRoot());
- }
- return ctx.createRootNodeState(nodeStates);
+ return ctx.createRootNodeState(ctx.getGlobalStore().getNodeStore().getRoot());
}
@Override
@@ -149,44 +149,22 @@ public class CompositeNodeStore implemen
mergeLock.lock();
try {
// merge the global builder and apply the commit hooks within
- Map<MountedNodeStore, NodeState> resultStates = newHashMap();
MountedNodeStore globalStore = ctx.getGlobalStore();
CommitHookEnhancer hookEnhancer = new CommitHookEnhancer(commitHook, ctx, nodeBuilder);
NodeState globalResult = globalStore.getNodeStore().merge(nodeBuilder.getNodeBuilder(globalStore), hookEnhancer, info);
- resultStates.put(globalStore, globalResult);
-
if (!hookEnhancer.getUpdatedBuilder().isPresent()) {
// it means that the commit hook wasn't invoked, because there were
// no changes on the global store. we should invoke it anyway.
hookEnhancer.processCommit(globalResult, globalResult, info);
}
- CompositeNodeBuilder updatedBuilder = hookEnhancer.getUpdatedBuilder().get();
-
- // merge the partial builders
- for (MountedNodeStore mns : ctx.getNonDefaultStores()) {
- NodeBuilder partialBuilder = updatedBuilder.getNodeBuilder(mns);
-
- if (mns.getMount().isReadOnly()) {
- assertNoChange(mns, partialBuilder);
- resultStates.put(mns, mns.getNodeStore().getRoot());
- } else {
- NodeState partialState = mns.getNodeStore().merge(partialBuilder, EmptyHook.INSTANCE, info);
- resultStates.put(mns, partialState);
- }
- }
-
- CompositeNodeState newRoot = ctx.createRootNodeState(resultStates);
- return newRoot;
+ return ctx.createRootNodeState(globalResult);
} finally {
mergeLock.unlock();
}
}
private void assertNoChangesOnReadOnlyMounts(CompositeNodeBuilder nodeBuilder) throws CommitFailedException {
- for (MountedNodeStore mountedNodeStore : ctx.getAllMountedNodeStores()) {
- if (!mountedNodeStore.getMount().isReadOnly()) {
- continue;
- }
+ for (MountedNodeStore mountedNodeStore : ctx.getNonDefaultStores()) {
NodeBuilder partialBuilder = nodeBuilder.getNodeBuilder(mountedNodeStore);
assertNoChange(mountedNodeStore, partialBuilder);
}
@@ -197,13 +175,8 @@ public class CompositeNodeStore implemen
NodeState nodeState = partialBuilder.getNodeState();
if (!nodeState.equals(baseState)) {
Set<String> changedPaths = getModifiedPaths(baseState, nodeState);
- Set<String> ignoredChangedPaths = getIgnoredPaths(changedPaths);
- if (!ignoredChangedPaths.isEmpty()) {
- LOG.debug("Can't merge following read-only paths (they are configured to be ignored): {}.", ignoredChangedPaths);
- }
- Set<String> failingChangedPaths = difference(changedPaths, ignoredChangedPaths);
- if (!failingChangedPaths.isEmpty()) {
- throw new CommitFailedException("CompositeStore", 31, "Unable to perform changes on read-only mount " + mountedNodeStore.getMount().getName() + ". Failing paths: " + failingChangedPaths.toString());
+ if (!changedPaths.isEmpty()) {
+ throw new CommitFailedException("CompositeStore", 31, "Unable to perform changes on read-only mount " + mountedNodeStore.getMount().getName() + ". Failing paths: " + changedPaths.toString());
}
}
}
@@ -211,41 +184,19 @@ public class CompositeNodeStore implemen
@Override
public NodeState rebase(NodeBuilder builder) {
checkArgument(builder instanceof CompositeNodeBuilder);
-
CompositeNodeBuilder nodeBuilder = (CompositeNodeBuilder) builder;
- Map<MountedNodeStore, NodeState> resultStates = newHashMap();
- for (MountedNodeStore mountedNodeStore : ctx.getAllMountedNodeStores()) {
- NodeStore nodeStore = mountedNodeStore.getNodeStore();
- NodeState result;
- if (mountedNodeStore.getMount().isReadOnly()) {
- result = nodeStore.getRoot();
- } else {
- NodeBuilder partialBuilder = nodeBuilder.getNodeBuilder(mountedNodeStore);
- result = nodeStore.rebase(partialBuilder);
- }
- resultStates.put(mountedNodeStore, result);
- }
- return ctx.createRootNodeState(resultStates);
+ MountedNodeStore globalStore = ctx.getGlobalStore();
+ NodeState globalResult = globalStore.getNodeStore().rebase(nodeBuilder.getNodeBuilder(globalStore));
+ return ctx.createRootNodeState(globalResult);
}
@Override
public NodeState reset(NodeBuilder builder) {
checkArgument(builder instanceof CompositeNodeBuilder);
-
CompositeNodeBuilder nodeBuilder = (CompositeNodeBuilder) builder;
- Map<MountedNodeStore, NodeState> resultStates = newHashMap();
- for (MountedNodeStore mountedNodeStore : ctx.getAllMountedNodeStores()) {
- NodeStore nodeStore = mountedNodeStore.getNodeStore();
- NodeState result;
- if (mountedNodeStore.getMount().isReadOnly()) {
- result = nodeStore.getRoot();
- } else {
- NodeBuilder partialBuilder = nodeBuilder.getNodeBuilder(mountedNodeStore);
- result = nodeStore.reset(partialBuilder);
- }
- resultStates.put(mountedNodeStore, result);
- }
- return ctx.createRootNodeState(resultStates);
+ MountedNodeStore globalStore = ctx.getGlobalStore();
+ NodeState globalResult = globalStore.getNodeStore().reset(nodeBuilder.getNodeBuilder(globalStore));
+ return ctx.createRootNodeState(globalResult);
}
@Override
@@ -288,13 +239,6 @@ public class CompositeNodeStore implemen
Map<String, String> globalProperties = newHashMap(properties);
globalProperties.put(CHECKPOINT_METADATA + "created", Long.toString(currentTimeMillis()));
globalProperties.put(CHECKPOINT_METADATA + "expires", Long.toString(currentTimeMillis() + lifetime));
- for (MountedNodeStore mns : ctx.getNonDefaultStores()) {
- if (mns.getMount().isReadOnly()) {
- continue;
- }
- String checkpoint = mns.getNodeStore().checkpoint(lifetime, properties);
- globalProperties.put(CHECKPOINT_METADATA_MOUNT + mns.getMount().getName(), checkpoint);
- }
String newCheckpoint = ctx.getGlobalStore().getNodeStore().checkpoint(lifetime, globalProperties);
if (LOG.isDebugEnabled()) {
LOG.debug("Created checkpoint {}. Debug info:\n{}", newCheckpoint, checkpointDebugInfo());
@@ -335,11 +279,11 @@ public class CompositeNodeStore implemen
Map<MountedNodeStore, NodeState> nodeStates = newHashMap();
nodeStates.put(ctx.getGlobalStore(), ctx.getGlobalStore().getNodeStore().retrieve(checkpoint));
for (MountedNodeStore nodeStore : ctx.getNonDefaultStores()) {
- NodeState nodeState = null;
+ NodeState nodeState;
String partialCheckpoint = getPartialCheckpointName(nodeStore, checkpoint, props, true);
- if (partialCheckpoint == null && nodeStore.getMount().isReadOnly()) {
+ if (partialCheckpoint == null) {
nodeState = nodeStore.getNodeStore().getRoot();
- } else if (partialCheckpoint != null) {
+ } else {
nodeState = nodeStore.getNodeStore().retrieve(partialCheckpoint);
}
nodeStates.put(nodeStore, nodeState);
@@ -362,17 +306,6 @@ public class CompositeNodeStore implemen
props = Collections.emptyMap();
result = true;
}
- for (MountedNodeStore nodeStore : ctx.getNonDefaultStores()) {
- if (nodeStore.getMount().isReadOnly()) {
- continue;
- }
- boolean released = false;
- String partialCheckpoint = getPartialCheckpointName(nodeStore, checkpoint, props, false);
- if (partialCheckpoint != null) {
- released = nodeStore.getNodeStore().release(partialCheckpoint);
- }
- result &= released;
- }
if (LOG.isDebugEnabled()) {
LOG.debug("Released checkpoint {}. Result: {}. Debug info:\n{}", checkpoint, result, checkpointDebugInfo());
}
@@ -449,16 +382,6 @@ public class CompositeNodeStore implemen
return dispatcher.addObserver(observer);
}
- private Set<String> getIgnoredPaths(Set<String> paths) {
- return newHashSet(filter(paths, new Predicate<String>() {
- @Override
- public boolean apply(String path) {
- String previousPath = ignoreReadOnlyWritePaths.floor(path);
- return previousPath != null && (previousPath.equals(path) || isAncestor(previousPath, path));
- }
- }));
- }
-
public static class Builder {
private final MountInfoProvider mip;
@@ -467,14 +390,10 @@ public class CompositeNodeStore implemen
private final List<MountedNodeStore> nonDefaultStores = Lists.newArrayList();
- private final List<String> ignoreReadOnlyWritePaths = Lists.newArrayList();
-
private CompositeNodeStoreMonitor nodeStateMonitor = CompositeNodeStoreMonitor.EMPTY_INSTANCE;
private CompositeNodeStoreMonitor nodeBuilderMonitor = CompositeNodeStoreMonitor.EMPTY_INSTANCE;
- private boolean partialReadOnly = true;
-
private NodeStoreChecks checks;
public Builder(MountInfoProvider mip, NodeStore globalStore) {
@@ -502,36 +421,12 @@ public class CompositeNodeStore implemen
return this;
}
- public Builder addIgnoredReadOnlyWritePath(String path) {
- ignoreReadOnlyWritePaths.add(path);
- return this;
- }
-
- public Builder setPartialReadOnly(boolean partialReadOnly) {
- this.partialReadOnly = partialReadOnly;
- return this;
- }
-
public CompositeNodeStore build() {
checkMountsAreConsistentWithMounts();
- if (partialReadOnly) {
- assertPartialMountsAreReadOnly();
- }
- if ( checks != null ) {
+ if (checks != null) {
nonDefaultStores.forEach( s -> checks.check(globalStore, s));
}
- return new CompositeNodeStore(mip, globalStore, nonDefaultStores, ignoreReadOnlyWritePaths, nodeStateMonitor, nodeBuilderMonitor);
- }
-
- public void assertPartialMountsAreReadOnly() {
- List<String> readWriteMountNames = Lists.newArrayList();
- for (Mount mount : mip.getNonDefaultMounts()) {
- if (!mount.isReadOnly()) {
- readWriteMountNames.add(mount.getName());
- }
- }
- checkArgument(readWriteMountNames.isEmpty(),
- "Following partial mounts are write-enabled: ", readWriteMountNames);
+ return new CompositeNodeStore(mip, globalStore, nonDefaultStores, nodeStateMonitor, nodeBuilderMonitor);
}
private void checkMountsAreConsistentWithMounts() {
@@ -542,16 +437,4 @@ public class CompositeNodeStore implemen
buildMountCount, mipMountCount);
}
}
-
- private class MountedNodeStoreObserver implements Observer {
- @Override
- public void contentChanged(@NotNull NodeState root, @NotNull CommitInfo info) {
- Map<MountedNodeStore, NodeState> nodeStates = newHashMap();
- for (MountedNodeStore nodeStore : ctx.getNonDefaultStores()) {
- nodeStates.put(nodeStore, nodeStore.getNodeStore().getRoot());
- }
- nodeStates.put(ctx.getGlobalStore(), root);
- dispatcher.contentChanged(ctx.createRootNodeState(nodeStates), info);
- }
- }
}
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreService.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreService.java Tue Oct 2 11:02:44 2018
@@ -22,7 +22,6 @@ import org.apache.felix.scr.annotations.
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.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
@@ -79,24 +78,12 @@ public class CompositeNodeStoreService {
@Reference
private StatisticsProvider statisticsProvider = StatisticsProvider.NOOP;
- @Property(label = "Ignore read only writes",
- unbounded = PropertyUnbounded.ARRAY,
- description = "Writes to these read-only paths won't fail the commit"
- )
- private static final String PROP_IGNORE_READ_ONLY_WRITES = "ignoreReadOnlyWrites";
-
@Property(label = "Enable node store checks",
description = "Whether the composite node store constraints should be checked before start",
boolValue = true
)
private static final String ENABLE_CHECKS = "enableChecks";
- @Property(label = "Read-only mounts",
- description = "The partial stores should be configured as read-only",
- boolValue = true
- )
- private static final String PROP_PARTIAL_READ_ONLY = "partialReadOnly";
-
@Property(label = "Pre-populate seed mount",
description = "Setting this parameter to a mount name will enable pre-populating the empty default store"
)
@@ -118,10 +105,6 @@ public class CompositeNodeStoreService {
private ObserverTracker observerTracker;
- private String[] ignoreReadOnlyWritePaths;
-
- private boolean partialReadOnly;
-
private String seedMount;
private boolean pathStats;
@@ -131,8 +114,6 @@ public class CompositeNodeStoreService {
@Activate
protected void activate(ComponentContext context, Map<String, ?> config) throws IOException, CommitFailedException {
this.context = context;
- ignoreReadOnlyWritePaths = PropertiesUtil.toStringArray(config.get(PROP_IGNORE_READ_ONLY_WRITES), new String[0]);
- partialReadOnly = PropertiesUtil.toBoolean(config.get(PROP_PARTIAL_READ_ONLY), true);
seedMount = PropertiesUtil.toString(config.get(PROP_SEED_MOUNT), null);
pathStats = PropertiesUtil.toBoolean(config.get(PATH_STATS), false);
enableChecks = PropertiesUtil.toBoolean(config.get(ENABLE_CHECKS), true);
@@ -180,10 +161,6 @@ public class CompositeNodeStoreService {
if (enableChecks) {
builder.with(checks);
}
- builder.setPartialReadOnly(partialReadOnly);
- for (String p : ignoreReadOnlyWritePaths) {
- builder.addIgnoredReadOnlyWritePath(p);
- }
for (NodeStoreWithProps ns : nodeStores) {
if (isGlobalNodeStore(ns)) {
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositionContext.java Tue Oct 2 11:02:44 2018
@@ -36,6 +36,7 @@ import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
import static java.util.Collections.singletonList;
class CompositionContext {
@@ -158,6 +159,15 @@ class CompositionContext {
return getOwningStore(PathUtils.concat(parentPath, childName)) == mountedNodeStore;
}
+ CompositeNodeState createRootNodeState(NodeState globalRootState) {
+ Map<MountedNodeStore, NodeState> nodeStates = newHashMap();
+ nodeStates.put(getGlobalStore(), globalRootState);
+ for (MountedNodeStore nodeStore : getNonDefaultStores()) {
+ nodeStates.put(nodeStore, nodeStore.getNodeStore().getRoot());
+ }
+ return createRootNodeState(nodeStates);
+ }
+
CompositeNodeState createRootNodeState(Map<MountedNodeStore, NodeState> rootStates) {
for (Map.Entry<MountedNodeStore, NodeState> e : rootStates.entrySet()) {
MountedNodeStore mns = e.getKey();
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/package-info.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/package-info.java Tue Oct 2 11:02:44 2018
@@ -55,7 +55,7 @@
* This is obviously correct but may be slow.
* {@link org.apache.jackrabbit.oak.composite.CompositionContext#getContributingStores(java.lang.String, java.util.function.Function)}
*/
-@Version("0.3.0")
+@Version("1.0.0")
package org.apache.jackrabbit.oak.composite;
import org.osgi.annotation.versioning.Version;
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeChildrenCountTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeChildrenCountTest.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeChildrenCountTest.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeChildrenCountTest.java Tue Oct 2 11:02:44 2018
@@ -34,7 +34,6 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
@@ -70,7 +69,7 @@ public class CompositeChildrenCountTest
@Test
public void multipleContributingStores() {
- MountInfoProvider mip = Mounts.newBuilder().mount("libs", "/libs", "/libs1", "/libs2", "/libs3", "/libs4").build();
+ MountInfoProvider mip = Mounts.newBuilder().readOnlyMount("libs", "/libs", "/libs1", "/libs2", "/libs3", "/libs4").build();
NodeStore globalStore = new MemoryNodeStore();
NodeStore libsStore = new MemoryNodeStore();
@@ -121,7 +120,7 @@ public class CompositeChildrenCountTest
@Test
public void contributingStoreReturnsInfinity() {
- MountInfoProvider mip = Mounts.newBuilder().mount("libs", "/libs", "/libs1", "/libs2", "/libs3", "/libs4").build();
+ MountInfoProvider mip = Mounts.newBuilder().readOnlyMount("libs", "/libs", "/libs1", "/libs2", "/libs3", "/libs4").build();
NodeStore globalStore = new MemoryNodeStore();
NodeStore libsStore = new MemoryNodeStore();
Modified: jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeCompareTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeCompareTest.java?rev=1842610&r1=1842609&r2=1842610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeCompareTest.java (original)
+++ jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/CompositeCompareTest.java Tue Oct 2 11:02:44 2018
@@ -97,7 +97,7 @@ public class CompositeCompareTest {
@Test
public void onlyPropertiesOnMainNodesAreCompared() throws CommitFailedException {
- MountInfoProvider mip = Mounts.newBuilder().mount("libs", "/libs").build();
+ MountInfoProvider mip = Mounts.newBuilder().readOnlyMount("libs", "/libs").build();
NodeStore globalStore = new MemoryNodeStore();
NodeStore libsStore = new MemoryNodeStore();
@@ -132,7 +132,7 @@ public class CompositeCompareTest {
@Test
public void nodesOutsideTheMountsAreIgnored() throws CommitFailedException {
- MountInfoProvider mip = Mounts.newBuilder().mount("libs", "/libs").build();
+ MountInfoProvider mip = Mounts.newBuilder().readOnlyMount("libs", "/libs").build();
NodeStore globalStore = new MemoryNodeStore();
NodeStore libsStore = new MemoryNodeStore();