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 al...@apache.org on 2014/10/23 12:05:04 UTC
svn commit: r1633783 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/index/
test/java/org/apache/jackrabbit/oak/plugins/index/
Author: alexparvulescu
Date: Thu Oct 23 10:05:04 2014
New Revision: 1633783
URL: http://svn.apache.org/r1633783
Log:
OAK-2203 Full reindexing is triggered when the IndexEditor is missing
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java?rev=1633783&r1=1633782&r2=1633783&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdate.java Thu Oct 23 10:05:04 2014
@@ -39,6 +39,7 @@ import org.apache.jackrabbit.oak.api.jmx
import org.apache.jackrabbit.oak.plugins.commit.AnnotatingConflictHandler;
import org.apache.jackrabbit.oak.plugins.commit.ConflictHook;
import org.apache.jackrabbit.oak.plugins.commit.ConflictValidatorProvider;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdate.MissingIndexProviderStrategy;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
@@ -121,6 +122,8 @@ public class AsyncIndexUpdate implements
*/
private final Set<String> reindexedDefinitions = new HashSet<String>();
+ private final MissingIndexProviderStrategy missingStrategy = new DefaultMissingIndexProviderStrategy();
+
public AsyncIndexUpdate(@Nonnull String name, @Nonnull NodeStore store,
@Nonnull IndexEditorProvider provider, boolean switchOnSync) {
this.name = checkNotNull(name);
@@ -341,7 +344,8 @@ public class AsyncIndexUpdate implements
NodeBuilder builder = store.getRoot().builder();
IndexUpdate indexUpdate =
- new IndexUpdate(provider, name, after, builder, callback);
+ new IndexUpdate(provider, name, after, builder, callback)
+ .withMissingProviderStrategy(missingStrategy);
CommitFailedException exception =
EditorDiff.process(VisibleEditor.wrap(indexUpdate), before, after);
if (exception != null) {
@@ -578,4 +582,24 @@ public class AsyncIndexUpdate implements
return name.charAt(0) == ':';
}
+ static class DefaultMissingIndexProviderStrategy extends
+ MissingIndexProviderStrategy {
+
+ private final Set<String> ignore = Sets.newHashSet("disabled");
+
+ @Override
+ public void onMissingIndex(String type, NodeBuilder definition)
+ throws CommitFailedException {
+ if (ignore.contains(type)) {
+ return;
+ }
+ throw new CommitFailedException("Async", 2,
+ "Missing index provider detected");
+ }
+ }
+
+ public boolean isFailing() {
+ return failing;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java?rev=1633783&r1=1633782&r2=1633783&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdate.java Thu Oct 23 10:05:04 2014
@@ -52,6 +52,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Objects;
public class IndexUpdate implements Editor {
+
private final Logger log = LoggerFactory.getLogger(getClass());
private final IndexEditorProvider provider;
@@ -86,6 +87,8 @@ public class IndexUpdate implements Edit
*/
private final IndexUpdateCallback updateCallback;
+ private MissingIndexProviderStrategy missingProvider = new MissingIndexProviderStrategy();
+
public IndexUpdate(
IndexEditorProvider provider, String async,
NodeState root, NodeBuilder builder,
@@ -154,12 +157,15 @@ public class IndexUpdate implements Edit
NodeBuilder definition = definitions.getChildNode(name);
if (Objects.equal(async, definition.getString(ASYNC_PROPERTY_NAME))) {
String type = definition.getString(TYPE_PROPERTY_NAME);
+ if (type == null) {
+ // probably not an index def
+ continue;
+ }
boolean shouldReindex = shouldReindex(definition,
before, name);
Editor editor = provider.getIndexEditor(type, definition, root, updateCallback);
if (editor == null) {
- // trigger reindexing when an indexer becomes available
- definition.setProperty(REINDEX_PROPERTY_NAME, true);
+ missingProvider.onMissingIndex(type, definition);
} else if (shouldReindex) {
if (definition.getBoolean(REINDEX_ASYNC_PROPERTY_NAME)
&& definition.getString(ASYNC_PROPERTY_NAME) == null) {
@@ -272,4 +278,18 @@ public class IndexUpdate implements Edit
return reindex.keySet();
}
+ public static class MissingIndexProviderStrategy {
+ public void onMissingIndex(String type, NodeBuilder definition)
+ throws CommitFailedException {
+ // trigger reindexing when an indexer becomes available
+ definition.setProperty(REINDEX_PROPERTY_NAME, true);
+ }
+ }
+
+ public IndexUpdate withMissingProviderStrategy(
+ MissingIndexProviderStrategy missingProvider) {
+ this.missingProvider = missingProvider;
+ return this;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java?rev=1633783&r1=1633782&r2=1633783&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/AsyncIndexUpdateTest.java Thu Oct 23 10:05:04 2014
@@ -20,6 +20,7 @@ import static com.google.common.collect.
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
import static org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider.TYPE;
import static org.junit.Assert.assertEquals;
@@ -27,6 +28,7 @@ import static org.junit.Assert.assertFal
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -36,12 +38,9 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexLookup;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
@@ -57,6 +56,10 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.junit.Test;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
public class AsyncIndexUpdateTest {
// TODO test index config deletes
@@ -553,6 +556,61 @@ public class AsyncIndexUpdateTest {
store.listCheckpoints().size() == 0);
}
+ /**
+ * OAK-2203 Test reindex behavior on an async index when the index provider is missing
+ * for a given type
+ */
+ @Test
+ public void testReindexMissingProvider() throws Exception {
+ MemoryNodeStore store = new MemoryNodeStore();
+ IndexEditorProvider provider = new PropertyIndexEditorProvider();
+
+ NodeBuilder builder = store.getRoot().builder();
+ createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+ "rootIndex", true, false, ImmutableSet.of("foo"), null)
+ .setProperty(ASYNC_PROPERTY_NAME, "asyncMissing");
+
+ builder.child("testRoot").setProperty("foo", "abc");
+
+ // merge it back in
+ store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+ AsyncIndexUpdate async = new AsyncIndexUpdate("asyncMissing", store,
+ provider);
+ //first run, creates a checkpoint and a ref to it as the last indexed state
+ async.run();
+ assertFalse(async.isFailing());
+ assertTrue("Expecting one checkpoint",
+ store.listCheckpoints().size() == 1);
+ String firstCp = store.listCheckpoints().iterator().next();
+ assertEquals(
+ firstCp,
+ store.getRoot().getChildNode(AsyncIndexUpdate.ASYNC)
+ .getString("asyncMissing"));
+
+ // second run, simulate an index going away
+ provider = CompositeIndexEditorProvider
+ .compose(new ArrayList<IndexEditorProvider>());
+ async = new AsyncIndexUpdate("asyncMissing", store, provider);
+ async.run();
+ assertTrue(async.isFailing());
+ // don't set reindex=true but skip the update
+ PropertyState reindex = store.getRoot()
+ .getChildNode(INDEX_DEFINITIONS_NAME).getChildNode("rootIndex")
+ .getProperty(REINDEX_PROPERTY_NAME);
+ assertTrue(reindex == null || !reindex.getValue(Type.BOOLEAN));
+
+ assertTrue("Expecting one checkpoint",
+ store.listCheckpoints().size() == 1);
+ String secondCp = store.listCheckpoints().iterator().next();
+ assertTrue("Store should not create a new checkpoint",
+ secondCp.equals(firstCp));
+ assertEquals(
+ firstCp,
+ store.getRoot().getChildNode(AsyncIndexUpdate.ASYNC)
+ .getString("asyncMissing"));
+ }
+
private static class FaultyIndexEditorProvder implements
IndexEditorProvider {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java?rev=1633783&r1=1633782&r2=1633783&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexUpdateTest.java Thu Oct 23 10:05:04 2014
@@ -35,6 +35,7 @@ import static org.junit.Assert.assertTru
import java.util.Set;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
@@ -45,6 +46,7 @@ import org.apache.jackrabbit.oak.query.Q
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
@@ -357,6 +359,46 @@ public class IndexUpdateTest {
"abc"));
}
+ /**
+ * OAK-2203 Test reindex behavior on a sync index when the index provider is missing
+ * for a given type
+ */
+ @Test
+ public void testReindexSyncMissingProvider() throws Exception {
+ EditorHook hook = new EditorHook(new IndexUpdateProvider(
+ emptyProvider()));
+ NodeState before = builder.getNodeState();
+
+ createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+ "rootIndex", true, false, ImmutableSet.of("foo"), null);
+ builder.child(INDEX_DEFINITIONS_NAME).child("azerty");
+ builder.child("testRoot").setProperty("foo", "abc");
+ NodeState after = builder.getNodeState();
+
+ NodeState indexed = hook.processCommit(before, after, CommitInfo.EMPTY);
+ NodeState rootIndex = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
+ "rootIndex");
+ PropertyState ps = rootIndex.getProperty(REINDEX_PROPERTY_NAME);
+ assertNotNull(ps);
+ assertTrue(ps.getValue(Type.BOOLEAN));
+
+ NodeState azerty = checkPathExists(indexed, INDEX_DEFINITIONS_NAME,
+ "azerty");
+ assertNull("Node should be ignored by reindexer",
+ azerty.getProperty(REINDEX_PROPERTY_NAME));
+ }
+
+ private static IndexEditorProvider emptyProvider() {
+ return new IndexEditorProvider() {
+ @Override
+ public Editor getIndexEditor(String type, NodeBuilder definition,
+ NodeState root, IndexUpdateCallback callback)
+ throws CommitFailedException {
+ return null;
+ }
+ };
+ }
+
private Set<String> find(PropertyIndexLookup lookup, String name,
String value) {
NodeState system = root.getChildNode(JCR_SYSTEM);