Author: thomasm
Date: Thu Jul 25 10:42:31 2019
New Revision: 1863731
URL: http://svn.apache.org/viewvc?rev=1863731&view=rev
Log:
OAK-8328 Bug in index definition can block indexing / cause indexing in a loop
(test case)
Modified:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
Modified:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java?rev=1863731&r1=1863730&r2=1863731&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
Thu Jul 25 10:42:31 2019
@@ -66,12 +66,15 @@ import java.util.Set;
import javax.jcr.PropertyType;
+import ch.qos.logback.classic.Level;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.junit.LogCustomizer;
import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdate;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
import
org.apache.jackrabbit.oak.plugins.index.lucene.directory.DefaultDirectoryFactory;
import org.apache.jackrabbit.oak.plugins.index.lucene.directory.LocalIndexDir;
@@ -119,6 +122,7 @@ import org.apache.lucene.queries.CustomS
import org.apache.lucene.queries.CustomScoreQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
+import org.hamcrest.core.IsCollectionContaining;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Assert;
@@ -915,6 +919,92 @@ public class LuceneIndexTest {
assertEquals(indexPath, defn.getIndexName());
assertEquals(indexPath, defn.getIndexPath());
}
+
+ /**
+ * Given a lucene index with a config error , it should not block other
+ * indexes to index content and should log a meaningful Exception . Once
+ * fixed and reindexed - it should reindex content as expected.
+ */
+ @Test
+ public void testConfigErrorInIndexDefintion() throws Exception {
+ LogCustomizer customLogs =
LogCustomizer.forLogger(IndexUpdate.class.getName()).enable(Level.ERROR).create();
+
+ // Create 2 index def - one with config related error and one without
+ NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+ newLucenePropertyIndexDefinition(index, "luceneTest",
ImmutableSet.of("foo"), null);
+ newLucenePropertyIndexDefinition(index, "luceneTest2",
ImmutableSet.of("foo2"), null);
+
+
builder.child(INDEX_DEFINITIONS_NAME).child("luceneTest").setProperty(IndexConstants.ENTRY_COUNT_PROPERTY_NAME,
ImmutableList.of(2L), Type.LONGS);
+
+ NodeState before = builder.getNodeState();
+ // Add some content that qualifies to be indexed by both of the above
indexes (separately)
+ builder.child("a").setProperty("foo", "bar");
+ builder.child("a").child("b").setProperty("foo", "bar");
+ builder.child("a").child("b").child("c").setProperty("foo2", "bar");
+
+ NodeState after = builder.getNodeState();
+ NodeState indexed;
+ try {
+ customLogs.starting();
+ String expectedLogMessage = "Unable to get Index Editor for index
at /oak:index/luceneTest . " +
+ "Please correct the index definition and reindex after
correction. " +
+ "Additional Info : java.lang.IllegalStateException:
Multiple values provided for property entryCount in index definition . Single
value was expected";
+ indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+ tracker = new IndexTracker();
+ tracker.update(indexed);
+ Assert.assertThat(customLogs.getLogs(),
IsCollectionContaining.hasItems(expectedLogMessage));
+
+ } finally {
+ customLogs.finished();
+ }
+
+ AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker);
+ FilterImpl filter = createFilter(NT_BASE);
+ filter.restrictProperty("foo", Operator.EQUAL,
+ PropertyValues.newString("bar"));
+ List<IndexPlan> plans = queryIndex.getPlans(filter, null, indexed);
+
+ // Since the index serving property foo has a config error , no plan
should be available
+ assertTrue(plans.size() == 0);
+
+ // Now we check the config error in index1 should not impact the query
results and content getting indexed for index 2
+ FilterImpl filter2 = createFilter(NT_BASE);
+ filter2.restrictProperty("foo2", Operator.EQUAL,
+ PropertyValues.newString("bar"));
+ List<IndexPlan> plans2 = queryIndex.getPlans(filter2, null, indexed);
+ Cursor cursor2 = queryIndex.query(plans2.get(0), indexed);
+
+ assertTrue(cursor2.hasNext());
+ assertEquals("/a/b/c", cursor2.next().getPath());
+ assertFalse(cursor2.hasNext());
+
+ // Now let's fix the config error in index1 and check it now indexes
the correct data
+
+ before = builder.getNodeState();
+
builder.child(INDEX_DEFINITIONS_NAME).child("luceneTest").setProperty(IndexConstants.ENTRY_COUNT_PROPERTY_NAME,
2L, Type.LONG);
+
builder.child(INDEX_DEFINITIONS_NAME).child("luceneTest").setProperty(IndexConstants.REINDEX_PROPERTY_NAME,
true);
+
+ after = builder.getNodeState();
+ try {
+ customLogs.starting();
+ indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+ tracker.update(indexed);
+ // Since the config error is now fixed - there should not be any
more errors here
+ assertTrue(customLogs.getLogs().size() == 0);
+ } finally {
+ customLogs.finished();
+ }
+
+
+ plans = queryIndex.getPlans(filter, null, indexed);
+ Cursor cursor = queryIndex.query(plans.get(0), indexed);
+
+ assertTrue(cursor.hasNext());
+ assertEquals("/a/b", cursor.next().getPath());
+ assertEquals("/a", cursor.next().getPath());
+ assertFalse(cursor.hasNext());
+
+ }
@After