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 ju...@apache.org on 2013/06/11 15:00:06 UTC
svn commit: r1491780 [2/3] - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/
oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/
oak-core/src/main/java/org/a...
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java Tue Jun 11 13:00:04 2013
@@ -16,8 +16,6 @@
*/
package org.apache.jackrabbit.oak.plugins.index.property;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
import static org.apache.jackrabbit.JcrConstants.NT_BASE;
@@ -36,10 +34,11 @@ import java.util.Set;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
-import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
@@ -56,6 +55,9 @@ public class PropertyIndexTest {
private static final int MANY = 100;
+ private static final EditorHook HOOK = new EditorHook(
+ new IndexUpdateProvider(new PropertyIndexEditorProvider()));
+
@Test
public void testPropertyLookup() throws Exception {
NodeState root = new InitialContent().initialize(EMPTY_NODE);
@@ -67,7 +69,6 @@ public class PropertyIndexTest {
NodeState before = builder.getNodeState();
// Add some content and process it through the property index hook
- builder = before.builder();
builder.child("a").setProperty("foo", "abc");
builder.child("b").setProperty("foo", Arrays.asList("abc", "def"),
Type.STRINGS);
@@ -77,8 +78,7 @@ public class PropertyIndexTest {
}
NodeState after = builder.getNodeState();
- EditorDiff.process(new PropertyIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
FilterImpl f = createFilter(indexed, NT_BASE);
@@ -115,7 +115,6 @@ public class PropertyIndexTest {
NodeState before = builder.getNodeState();
// Add some content and process it through the property index hook
- builder = before.builder();
builder.child("a").setProperty("foo", "abc")
.setProperty("extrafoo", "pqr");
builder.child("b").setProperty("foo", Arrays.asList("abc", "def"),
@@ -127,8 +126,7 @@ public class PropertyIndexTest {
NodeState after = builder.getNodeState();
// Add an index
- EditorDiff.process(new PropertyIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
FilterImpl f = createFilter(indexed, NT_BASE);
@@ -168,7 +166,6 @@ public class PropertyIndexTest {
NodeState before = builder.getNodeState();
// Add some content and process it through the property index hook
- builder = before.builder();
builder.child("a")
.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, Type.NAME)
.setProperty("foo", "abc");
@@ -177,8 +174,7 @@ public class PropertyIndexTest {
.setProperty("foo", Arrays.asList("abc", "def"), Type.STRINGS);
NodeState after = builder.getNodeState();
- EditorDiff.process(new PropertyIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
FilterImpl f = createFilter(indexed, NT_UNSTRUCTURED);
@@ -216,14 +212,15 @@ public class PropertyIndexTest {
// Add index definitions
NodeBuilder builder = root.builder();
NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
- createIndexDefinition(index, "fooIndex", true, false,
+ createIndexDefinition(
+ index, "fooIndex", true, false,
ImmutableSet.of("foo", "extrafoo"), null);
- createIndexDefinition(index, "fooIndexFile", true, false,
+ createIndexDefinition(
+ index, "fooIndexFile", true, false,
ImmutableSet.of("foo"), ImmutableSet.of(NT_FILE));
NodeState before = builder.getNodeState();
// Add some content and process it through the property index hook
- builder = before.builder();
builder.child("a")
.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, Type.NAME)
.setProperty("foo", "abc");
@@ -233,8 +230,7 @@ public class PropertyIndexTest {
NodeState after = builder.getNodeState();
// Add an index
- EditorDiff.process(new PropertyIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
FilterImpl f = createFilter(after, NT_UNSTRUCTURED);
@@ -252,24 +248,22 @@ public class PropertyIndexTest {
}
}
- @Test
+ @Test(expected = CommitFailedException.class)
public void testUnique() throws Exception {
NodeState root = EMPTY_NODE;
// Add index definition
NodeBuilder builder = root.builder();
- createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+ createIndexDefinition(
+ builder.child(INDEX_DEFINITIONS_NAME),
"fooIndex", true, true, ImmutableSet.of("foo"), null);
NodeState before = builder.getNodeState();
- builder = before.builder();
builder.child("a").setProperty("foo", "abc");
builder.child("b").setProperty("foo", Arrays.asList("abc", "def"),
Type.STRINGS);
NodeState after = builder.getNodeState();
- CommitFailedException expected = EditorDiff.process(
- new PropertyIndexEditor(builder), before, after);
- assertNotNull("Unique constraint should be respected", expected);
+ HOOK.processCommit(before, after); // should throw
}
@Test
@@ -282,19 +276,16 @@ public class PropertyIndexTest {
"fooIndex", true, true, ImmutableSet.of("foo"),
ImmutableSet.of("typeFoo"));
NodeState before = builder.getNodeState();
- builder = before.builder();
builder.child("a").setProperty(JCR_PRIMARYTYPE, "typeFoo", Type.NAME)
.setProperty("foo", "abc");
builder.child("b").setProperty(JCR_PRIMARYTYPE, "typeBar", Type.NAME)
.setProperty("foo", "abc");
NodeState after = builder.getNodeState();
- CommitFailedException unexpected = EditorDiff.process(
- new PropertyIndexEditor(builder), before, after);
- assertNull(unexpected);
+ HOOK.processCommit(before, after); // should not throw
}
- @Test
+ @Test(expected = CommitFailedException.class)
public void testUniqueByTypeKO() throws Exception {
NodeState root = EMPTY_NODE;
@@ -304,16 +295,13 @@ public class PropertyIndexTest {
"fooIndex", true, true, ImmutableSet.of("foo"),
ImmutableSet.of("typeFoo"));
NodeState before = builder.getNodeState();
- builder = before.builder();
builder.child("a").setProperty(JCR_PRIMARYTYPE, "typeFoo", Type.NAME)
.setProperty("foo", "abc");
builder.child("b").setProperty(JCR_PRIMARYTYPE, "typeFoo", Type.NAME)
.setProperty("foo", "abc");
NodeState after = builder.getNodeState();
- CommitFailedException expected = EditorDiff.process(
- new PropertyIndexEditor(builder), before, after);
- assertNotNull("Unique constraint should be respected", expected);
+ HOOK.processCommit(before, after); // should throw
}
@Test
@@ -330,13 +318,10 @@ public class PropertyIndexTest {
builder.child("b").setProperty(JCR_PRIMARYTYPE, "typeBar", Type.NAME)
.setProperty("foo", "abc");
NodeState before = builder.getNodeState();
- builder = before.builder();
builder.getChildNode("b").remove();
NodeState after = builder.getNodeState();
- CommitFailedException unexpected = EditorDiff.process(
- new PropertyIndexEditor(builder), before, after);
- assertNull(unexpected);
+ HOOK.processCommit(before, after); // should not throw
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategyTest.java Tue Jun 11 13:00:04 2013
@@ -16,9 +16,12 @@
*/
package org.apache.jackrabbit.oak.plugins.index.property.strategy;
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.Arrays.asList;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import java.util.Collections;
+import java.util.Set;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -29,10 +32,12 @@ import org.apache.jackrabbit.oak.spi.sta
import org.junit.Assert;
import org.junit.Test;
-import com.google.common.collect.Sets;
-
public class ContentMirrorStoreStrategyTest {
+ private static final Set<String> empty = newHashSet();
+
+ private static final Set<String> key = newHashSet("key");
+
/**
* <p>
* Tests the index pruning mechanism
@@ -54,8 +59,9 @@ public class ContentMirrorStoreStrategyT
NodeState root = EMPTY_NODE;
NodeBuilder index = root.builder();
- store.insert(index, "key",
- Sets.newHashSet("/", "a/b/c", "a/b/d", "b", "d/e", "d/e/f"));
+ for (String path : asList("/", "a/b/c", "a/b/d", "b", "d/e", "d/e/f")) {
+ store.update(index, path, empty, key);
+ }
checkPath(index, "key", "", true);
checkPath(index, "key", "a/b/c", true);
checkPath(index, "key", "a/b/d", true);
@@ -65,27 +71,30 @@ public class ContentMirrorStoreStrategyT
// remove the root key, removes just the "match" property, when the
// index is not empty
- store.remove(index, "key", Sets.newHashSet("/"));
+ store.update(index, "/", key, empty);
checkPath(index, "key", "d/e/f", true);
// removing intermediary path doesn't remove the entire subtree
- store.remove(index, "key", Sets.newHashSet("d/e"));
+ store.update(index, "d/e", key, empty);
checkPath(index, "key", "d/e/f", true);
// removing intermediary path doesn't remove the entire subtree
- store.remove(index, "key", Sets.newHashSet("d/e/f"));
+ store.update(index, "d/e/f", key, empty);
checkNotPath(index, "key", "d");
// brother segment removed
- store.remove(index, "key", Sets.newHashSet("a/b/d", "a/b"));
+ store.update(index, "a/b/d", key, empty);
+ store.update(index, "a/b", key, empty);
checkPath(index, "key", "a/b/c", true);
// reinsert root and remove everything else
- store.insert(index, "key", Sets.newHashSet("/"));
- store.remove(index, "key", Sets.newHashSet("d/e/f", "b", "a/b/c"));
+ store.update(index, "", empty, key);
+ store.update(index, "d/e/f", key, empty);
+ store.update(index, "b", key, empty);
+ store.update(index, "a/b/c", key, empty);
// remove the root key when the index is empty
- store.remove(index, "key", Sets.newHashSet("/"));
+ store.update(index, "", key, empty);
Assert.assertEquals(0, index.getChildNodeCount());
}
@@ -121,8 +130,8 @@ public class ContentMirrorStoreStrategyT
IndexStoreStrategy store = new ContentMirrorStoreStrategy();
NodeState root = EMPTY_NODE;
NodeBuilder index = root.builder();
- store.insert(index, "key", Sets.newHashSet("a"));
- store.insert(index, "key", Sets.newHashSet("b"));
+ store.update(index, "a", empty, key);
+ store.update(index, "b", empty, key);
Assert.assertTrue(
"ContentMirrorStoreStrategy should guarantee uniqueness on insert",
store.count(index.getNodeState(), Collections.singleton("key"), 2) > 1);
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java Tue Jun 11 13:00:04 2013
@@ -16,77 +16,150 @@
*/
package org.apache.jackrabbit.oak.plugins.index.lucene;
+import static org.apache.jackrabbit.JcrConstants.JCR_DATA;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getString;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.getChildOrNull;
-import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
-import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
-import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.isHidden;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newFulltextField;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPathField;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.FieldFactory.newPropertyField;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.ANALYZER;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INCLUDE_PROPERTY_TYPES;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_DATA_CHILD_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_PATH;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TO_WRITE_LOCK_MS;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TermFactory.newPathTerm;
-import java.io.Closeable;
+import java.io.File;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
+import java.io.InputStream;
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.api.Blob;
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.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
+import org.apache.jackrabbit.oak.plugins.index.lucene.aggregation.AggregatedState;
+import org.apache.jackrabbit.oak.plugins.index.lucene.aggregation.NodeAggregator;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
-import org.apache.tika.config.TikaConfig;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SerialMergeScheduler;
+import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
+import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
+import org.apache.tika.sax.WriteOutContentHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* {@link IndexEditor} implementation that is responsible for keeping the
* {@link LuceneIndex} up to date
*
* @see LuceneIndex
- *
*/
-public class LuceneIndexEditor implements IndexEditor, Closeable {
+public class LuceneIndexEditor implements IndexEditor {
- private final LuceneIndexEditor parent;
+ private static final Logger log =
+ LoggerFactory.getLogger(LuceneIndexEditor.class);
+
+ private static final IndexWriterConfig config = getIndexWriterConfig();
+
+ private static final NodeAggregator aggregator = new NodeAggregator();
+
+ private static final Parser parser = new AutoDetectParser();
+
+ private static IndexWriterConfig getIndexWriterConfig() {
+ // FIXME: Hack needed to make Lucene work in an OSGi environment
+ Thread thread = Thread.currentThread();
+ ClassLoader loader = thread.getContextClassLoader();
+ thread.setContextClassLoader(IndexWriterConfig.class.getClassLoader());
+ try {
+ IndexWriterConfig config = new IndexWriterConfig(VERSION, ANALYZER);
+ config.setMergeScheduler(new SerialMergeScheduler());
+ config.setWriteLockTimeout(TO_WRITE_LOCK_MS);
+ return config;
+ } finally {
+ thread.setContextClassLoader(loader);
+ }
+ }
+
+ private static Directory newIndexDirectory(NodeBuilder definition)
+ throws CommitFailedException {
+ String path = getString(definition, PERSISTENCE_PATH);
+ if (path == null) {
+ return new ReadWriteOakDirectory(
+ definition.child(INDEX_DATA_CHILD_NAME));
+ } else {
+ try {
+ File file = new File(path);
+ file.mkdirs();
+ return FSDirectory.open(file); // TODO: close() is never called
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Lucene", 1, "Failed to open the index in " + path, e);
+ }
+ }
+ }
- private final NodeBuilder node;
+ /** Parent editor, or {@code null} if this is the root editor. */
+ private final LuceneIndexEditor parent;
+ /** Name of this node, or {@code null} for the root node. */
private final String name;
+ /** Path of this editor, built lazily in {@link #getPath()}. */
private String path;
- private final Map<String, LuceneIndexUpdate> updates;
+ /** Index definition node builder */
+ private final NodeBuilder definition;
- /**
- * the root editor in charge of applying the updates
- */
- private final boolean isRoot;
-
- private final Parser parser = new AutoDetectParser(
- TikaConfig.getDefaultConfig());
-
- private LuceneIndexEditor(LuceneIndexEditor parent, NodeBuilder node,
- String name, String path, Map<String, LuceneIndexUpdate> updates,
- boolean isRoot) {
- this.parent = parent;
- this.node = node;
- this.name = name;
- this.path = path;
- this.updates = updates;
- this.isRoot = isRoot;
- }
+ private final int propertyTypes;
- private LuceneIndexEditor(LuceneIndexEditor parent, String name) {
- this(parent, getChildOrNull(parent.node, name), name, null,
- parent.updates, false);
+ private IndexWriter writer = null;
+
+ private boolean propertiesChanged = false;
+
+ LuceneIndexEditor(NodeBuilder definition) throws CommitFailedException {
+ this.parent = null;
+ this.name = null;
+ this.path = "/";
+ this.definition = definition;
+
+ PropertyState ps = definition.getProperty(INCLUDE_PROPERTY_TYPES);
+ if (ps != null) {
+ int types = 0;
+ for (String inc : ps.getValue(Type.STRINGS)) {
+ try {
+ types |= 1 << PropertyType.valueFromName(inc);
+ } catch (IllegalArgumentException e) {
+ log.warn("Unknown property type: " + inc);
+ }
+ }
+ this.propertyTypes = types;
+ } else {
+ this.propertyTypes = -1;
+ }
}
- public LuceneIndexEditor(NodeBuilder root) {
- this(null, root, null, "/", new HashMap<String, LuceneIndexUpdate>(),
- true);
+ private LuceneIndexEditor(LuceneIndexEditor parent, String name) {
+ this.parent = parent;
+ this.name = name;
+ this.path = null;
+ this.definition = parent.definition;
+ this.writer = parent.writer;
+ this.propertyTypes = parent.propertyTypes;
}
public String getPath() {
@@ -96,26 +169,15 @@ public class LuceneIndexEditor implement
return path;
}
- private static boolean isIndexNode(NodeBuilder node) {
- return TYPE_LUCENE.equals(getString(node, TYPE_PROPERTY_NAME));
- }
-
@Override
public void enter(NodeState before, NodeState after)
throws CommitFailedException {
- if (node != null && node.hasChildNode(INDEX_DEFINITIONS_NAME)) {
- NodeBuilder index = node.child(INDEX_DEFINITIONS_NAME);
- for (String indexName : index.getChildNodeNames()) {
- NodeBuilder child = index.child(indexName);
- if (isIndexNode(child) && !this.updates.containsKey(getPath())) {
- this.updates.put(getPath(), new LuceneIndexUpdate(
- getPath(), child, parser));
- }
- }
- }
- if (node != null && name != null && !isHidden(name)) {
- for (LuceneIndexUpdate update : updates.values()) {
- update.insert(getPath(), node);
+ if (parent == null) {
+ try {
+ writer = new IndexWriter(newIndexDirectory(definition), config);
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Lucene", 2, "Unable to create a new index writer", e);
}
}
}
@@ -123,78 +185,158 @@ public class LuceneIndexEditor implement
@Override
public void leave(NodeState before, NodeState after)
throws CommitFailedException {
- if (!isRoot) {
- return;
+ if (propertiesChanged || !before.exists()) {
+ String path = getPath();
+ try {
+ writer.updateDocument(
+ newPathTerm(path), makeDocument(path, after));
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Lucene", 3, "Failed to index the node " + path, e);
+ }
}
- for (LuceneIndexUpdate update : updates.values()) {
- update.apply();
+
+ if (parent == null) {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Lucene", 4, "Failed to close the Lucene index", e);
+ }
}
- updates.clear();
}
@Override
- public void propertyAdded(PropertyState after) throws CommitFailedException {
- for (LuceneIndexUpdate update : updates.values()) {
- update.insert(getPath(), node);
- }
+ public void propertyAdded(PropertyState after) {
+ propertiesChanged = true;
}
@Override
- public void propertyChanged(PropertyState before, PropertyState after)
- throws CommitFailedException {
- for (LuceneIndexUpdate update : updates.values()) {
- update.insert(getPath(), node);
- }
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ propertiesChanged = true;
}
@Override
- public void propertyDeleted(PropertyState before)
- throws CommitFailedException {
- for (LuceneIndexUpdate update : updates.values()) {
- update.insert(getPath(), node);
- }
+ public void propertyDeleted(PropertyState before) {
+ propertiesChanged = true;
}
@Override
- public Editor childNodeAdded(String name, NodeState after)
- throws CommitFailedException {
- if (isHidden(name)) {
- return null;
- }
- for (LuceneIndexUpdate update : updates.values()) {
- update.insert(concat(getPath(), name), new ReadOnlyBuilder(after));
- }
- return childNodeChanged(name, EMPTY_NODE, after);
+ public Editor childNodeAdded(String name, NodeState after) {
+ return new LuceneIndexEditor(this, name);
}
@Override
- public Editor childNodeChanged(String name, NodeState before,
- NodeState after) throws CommitFailedException {
- if (isHidden(name)) {
- return null;
- }
+ public Editor childNodeChanged(
+ String name, NodeState before, NodeState after) {
return new LuceneIndexEditor(this, name);
}
@Override
public Editor childNodeDeleted(String name, NodeState before)
throws CommitFailedException {
- if (isHidden(name)) {
- return null;
+ String path = PathUtils.concat(getPath(), name);
+
+ try {
+ // Remove all index entries in the removed subtree
+ writer.deleteDocuments(newPathTerm(path));
+ writer.deleteDocuments(new PrefixQuery(newPathTerm(path + "/")));
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Lucene", 5, "Failed to remove the index entries of"
+ + " the removed subtree " + path, e);
+ }
+
+ return null; // no need to recurse down the removed subtree
+ }
+
+ private Document makeDocument(String path, NodeState state) {
+ Document document = new Document();
+ document.add(newPathField(path));
+
+ for (PropertyState property : state.getProperties()) {
+ String pname = property.getName();
+ if (isVisible(pname)
+ && (propertyTypes & (1 << property.getType().tag())) != 0) {
+ if (Type.BINARY.tag() == property.getType().tag()) {
+ addBinaryValue(document, property, state);
+ } else {
+ for (String value : property.getValue(Type.STRINGS)) {
+ document.add(newPropertyField(pname, value));
+ document.add(newFulltextField(value));
+ }
+ }
+ }
}
- for (LuceneIndexUpdate update : updates.values()) {
- update.remove(concat(getPath(), name));
+
+ for (AggregatedState agg : aggregator.getAggregates(state)) {
+ for (PropertyState property : agg.getProperties()) {
+ String pname = property.getName();
+ if (isVisible(pname)
+ && (propertyTypes & (1 << property.getType().tag())) != 0) {
+ if (Type.BINARY.tag() == property.getType().tag()) {
+ addBinaryValue(document, property, agg.get());
+ } else {
+ for (String v : property.getValue(Type.STRINGS)) {
+ document.add(newFulltextField(v));
+ }
+ }
+ }
+ }
}
- return null;
+
+ return document;
}
- // -----------------------------------------------------< Closeable >--
+ private static boolean isVisible(String name) {
+ return name.charAt(0) != ':';
+ }
- @Override
- public void close() throws IOException {
- for (LuceneIndexUpdate update : updates.values()) {
- update.close();
+ private void addBinaryValue(
+ Document doc, PropertyState property, NodeState state) {
+ Metadata metadata = new Metadata();
+ if (JCR_DATA.equals(property.getName())) {
+ String type = getString(state, JcrConstants.JCR_MIMETYPE);
+ if (type != null) { // not mandatory
+ metadata.set(Metadata.CONTENT_TYPE, type);
+ }
+ String encoding = getString(state, JcrConstants.JCR_ENCODING);
+ if (encoding != null) { // not mandatory
+ metadata.set(Metadata.CONTENT_ENCODING, encoding);
+ }
}
- updates.clear();
+
+ for (Blob v : property.getValue(Type.BINARIES)) {
+ doc.add(newFulltextField(parseStringValue(v, metadata)));
+ }
+ }
+
+ private String parseStringValue(Blob v, Metadata metadata) {
+ WriteOutContentHandler handler = new WriteOutContentHandler();
+ try {
+ InputStream stream = v.getNewStream();
+ try {
+ parser.parse(stream, handler, metadata, new ParseContext());
+ } finally {
+ stream.close();
+ }
+ } catch (LinkageError e) {
+ // Capture and ignore errors caused by extraction libraries
+ // not being present. This is equivalent to disabling
+ // selected media types in configuration, so we can simply
+ // ignore these errors.
+ } catch (Throwable t) {
+ // Capture and report any other full text extraction problems.
+ // The special STOP exception is used for normal termination.
+ if (!handler.isWriteLimitReached(t)) {
+ log.debug("Failed to extract text from a binary property."
+ + " This is a fairly common case, and nothing to"
+ + " worry about. The stack trace is included to"
+ + " help improve the text extraction feature.", t);
+ return "TextExtractionError";
+ }
+ }
+ return handler.toString();
}
+
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorProvider.java Tue Jun 11 13:00:04 2013
@@ -20,10 +20,12 @@ import static org.apache.jackrabbit.oak.
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
* Service that provides Lucene based {@link IndexEditor}s
@@ -37,9 +39,11 @@ import org.apache.jackrabbit.oak.spi.sta
public class LuceneIndexEditorProvider implements IndexEditorProvider {
@Override
- public Editor getIndexEditor(String type, NodeBuilder builder) {
+ public Editor getIndexEditor(
+ String type, NodeBuilder definition, NodeState root)
+ throws CommitFailedException {
if (TYPE_LUCENE.equals(type)) {
- return new LuceneIndexEditor(builder);
+ return new LuceneIndexEditor(definition);
}
return null;
}
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/aggregation/NodeAggregator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/aggregation/NodeAggregator.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/aggregation/NodeAggregator.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/aggregation/NodeAggregator.java Tue Jun 11 13:00:04 2013
@@ -23,19 +23,12 @@ import static org.apache.jackrabbit.oak.
import java.util.List;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import com.google.common.collect.ImmutableList;
public class NodeAggregator {
- private final NodeBuilder index;
-
- public NodeAggregator(NodeBuilder index) {
- this.index = index;
- }
-
public List<AggregatedState> getAggregates(NodeState state) {
// FIXME remove hardcoded aggregates
String type = getString(state, JCR_PRIMARYTYPE);
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneIndexHelper.java Tue Jun 11 13:00:04 2013
@@ -50,12 +50,12 @@ public class LuceneIndexHelper {
public static NodeBuilder newLuceneIndexDefinition(
@Nonnull NodeBuilder index, @Nonnull String name,
@Nullable Set<String> propertyTypes) {
- return newLuceneIndexDefinition(index, name, propertyTypes, false);
+ return newLuceneIndexDefinition(index, name, propertyTypes, null);
}
public static NodeBuilder newLuceneIndexDefinition(
@Nonnull NodeBuilder index, @Nonnull String name,
- @Nullable Set<String> propertyTypes, boolean async) {
+ @Nullable Set<String> propertyTypes, String async) {
if (index.hasChildNode(name)) {
return index.child(name);
}
@@ -63,8 +63,8 @@ public class LuceneIndexHelper {
index.setProperty(JCR_PRIMARYTYPE, INDEX_DEFINITIONS_NODE_TYPE, NAME)
.setProperty(TYPE_PROPERTY_NAME, TYPE_LUCENE)
.setProperty(REINDEX_PROPERTY_NAME, true);
- if (async) {
- index.setProperty(ASYNC_PROPERTY_NAME, true);
+ if (async != null) {
+ index.setProperty(ASYNC_PROPERTY_NAME, async);
}
if (propertyTypes != null && !propertyTypes.isEmpty()) {
index.setProperty(PropertyStates.createProperty(
@@ -76,14 +76,14 @@ public class LuceneIndexHelper {
public static NodeBuilder newLuceneFileIndexDefinition(
@Nonnull NodeBuilder index, @Nonnull String name,
@Nullable Set<String> propertyTypes, @Nonnull String path) {
- return newLuceneFileIndexDefinition(index, name, propertyTypes, path,
- false);
+ return newLuceneFileIndexDefinition(
+ index, name, propertyTypes, path, null);
}
public static NodeBuilder newLuceneFileIndexDefinition(
@Nonnull NodeBuilder index, @Nonnull String name,
@Nullable Set<String> propertyTypes, @Nonnull String path,
- boolean async) {
+ String async) {
if (index.hasChildNode(name)) {
return index.child(name);
}
@@ -93,8 +93,8 @@ public class LuceneIndexHelper {
.setProperty(PERSISTENCE_NAME, PERSISTENCE_FILE)
.setProperty(PERSISTENCE_PATH, path)
.setProperty(REINDEX_PROPERTY_NAME, true);
- if (async) {
- index.setProperty(ASYNC_PROPERTY_NAME, true);
+ if (async != null) {
+ index.setProperty(ASYNC_PROPERTY_NAME, async);
}
if (propertyTypes != null && !propertyTypes.isEmpty()) {
index.setProperty(PropertyStates.createProperty(
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/LuceneInitializerHelper.java Tue Jun 11 13:00:04 2013
@@ -34,7 +34,7 @@ public class LuceneInitializerHelper imp
private final String filePath;
- private boolean async = false;
+ private String async = null;
public LuceneInitializerHelper(String name) {
this(name, LuceneIndexHelper.JR_PROPERTY_INCLUDES);
@@ -52,7 +52,7 @@ public class LuceneInitializerHelper imp
}
public LuceneInitializerHelper async() {
- async = true;
+ async = "async";
return this;
}
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=1491780&r1=1491779&r2=1491780&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 Tue Jun 11 13:00:04 2013
@@ -26,12 +26,15 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
+import javax.jcr.PropertyType;
+
import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
import org.apache.jackrabbit.oak.query.ast.Operator;
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
-import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
import org.apache.jackrabbit.oak.spi.query.Cursor;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.PropertyValues;
@@ -44,6 +47,9 @@ import com.google.common.collect.Immutab
public class LuceneIndexTest {
+ private static final EditorHook HOOK = new EditorHook(
+ new IndexUpdateProvider(new LuceneIndexEditorProvider()));
+
private NodeState root = new InitialContent().initialize(EMPTY_NODE);
private NodeBuilder builder = root.builder();
@@ -57,8 +63,7 @@ public class LuceneIndexTest {
builder.setProperty("foo", "bar");
NodeState after = builder.getNodeState();
- EditorDiff.process(new LuceneIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
QueryIndex queryIndex = new LuceneIndex();
FilterImpl filter = createFilter(NT_BASE);
@@ -84,8 +89,7 @@ public class LuceneIndexTest {
NodeState after = builder.getNodeState();
- EditorDiff.process(new LuceneIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
QueryIndex queryIndex = new LuceneIndex();
FilterImpl filter = createFilter(NT_BASE);
@@ -95,17 +99,18 @@ public class LuceneIndexTest {
Cursor cursor = queryIndex.query(filter, indexed);
assertTrue(cursor.hasNext());
- assertEquals("/", cursor.next().getPath());
- assertEquals("/a", cursor.next().getPath());
- assertEquals("/a/b", cursor.next().getPath());
assertEquals("/a/b/c", cursor.next().getPath());
+ assertEquals("/a/b", cursor.next().getPath());
+ assertEquals("/a", cursor.next().getPath());
+ assertEquals("/", cursor.next().getPath());
assertFalse(cursor.hasNext());
}
@Test
public void testLucene3() throws Exception {
NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
- newLuceneIndexDefinition(index, "lucene", ImmutableSet.of(Type.STRING.toString()));
+ newLuceneIndexDefinition(
+ index, "lucene", ImmutableSet.of(PropertyType.TYPENAME_STRING));
NodeState before = builder.getNodeState();
builder.setProperty("foo", "bar");
@@ -115,8 +120,7 @@ public class LuceneIndexTest {
NodeState after = builder.getNodeState();
- EditorDiff.process(new LuceneIndexEditor(builder), before, after);
- NodeState indexed = builder.getNodeState();
+ NodeState indexed = HOOK.processCommit(before, after);
QueryIndex queryIndex = new LuceneIndex();
FilterImpl filter = createFilter(NT_BASE);
@@ -126,8 +130,8 @@ public class LuceneIndexTest {
Cursor cursor = queryIndex.query(filter, indexed);
assertTrue(cursor.hasNext());
- assertEquals("/", cursor.next().getPath());
assertEquals("/a", cursor.next().getPath());
+ assertEquals("/", cursor.next().getPath());
assertFalse(cursor.hasNext());
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/OakSolrUtils.java Tue Jun 11 13:00:04 2013
@@ -17,10 +17,9 @@
package org.apache.jackrabbit.oak.plugins.index.solr;
import java.io.IOException;
+
import javax.annotation.Nonnull;
-import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
-import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexHookProvider;
import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndexProvider;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
import org.apache.solr.client.solrj.SolrServer;
@@ -47,27 +46,6 @@ public class OakSolrUtils {
}
/**
- * adapts the OSGi Solr {@link IndexEditorProvider} service
- *
- * @return a {@link SolrIndexHookProvider}
- */
- public static IndexEditorProvider adaptOsgiIndexHookProvider() {
- IndexEditorProvider indexHookProvider = null;
- try {
- BundleContext ctx = BundleReference.class.cast(SolrIndexHookProvider.class
- .getClassLoader()).getBundle().getBundleContext();
-
- ServiceReference serviceReference = ctx.getServiceReference(IndexEditorProvider.class.getName());
- if (serviceReference != null) {
- indexHookProvider = IndexEditorProvider.class.cast(ctx.getService(serviceReference));
- }
- } catch (Throwable e) {
- // do nothing
- }
- return indexHookProvider;
- }
-
- /**
* adapts the OSGi Solr {@link QueryIndexProvider} service
*
* @return a {@link SolrQueryIndexProvider}
Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditor.java?rev=1491780&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditor.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditor.java Tue Jun 11 13:00:04 2013
@@ -0,0 +1,194 @@
+/*
+ * 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.index.solr.index;
+
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+
+import java.io.IOException;
+
+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.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrUtils;
+import org.apache.jackrabbit.oak.spi.commit.Editor;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.common.SolrInputDocument;
+
+/**
+ * Index editor for keeping a Solr index up to date.
+ */
+public class SolrIndexEditor implements IndexEditor {
+
+ /** Parent editor, or {@code null} if this is the root editor. */
+ private final SolrIndexEditor parent;
+
+ /** Name of this node, or {@code null} for the root node. */
+ private final String name;
+
+ /** Path of this editor, built lazily in {@link #getPath()}. */
+ private String path;
+
+ /** Index definition node builder */
+ private final NodeBuilder definition;
+
+ private final SolrServer solrServer;
+
+ private final OakSolrConfiguration configuration;
+
+ private boolean propertiesChanged = false;
+
+ SolrIndexEditor(
+ NodeBuilder definition, SolrServer solrServer,
+ OakSolrConfiguration configuration) throws CommitFailedException {
+ this.parent = null;
+ this.name = null;
+ this.path = "/";
+ this.definition = definition;
+ this.solrServer = solrServer;
+ this.configuration = configuration;
+ }
+
+ private SolrIndexEditor(SolrIndexEditor parent, String name) {
+ this.parent = parent;
+ this.name = name;
+ this.path = null;
+ this.definition = parent.definition;
+ this.solrServer = parent.solrServer;
+ this.configuration = parent.configuration;
+ }
+
+ public String getPath() {
+ if (path == null) { // => parent != null
+ path = concat(parent.getPath(), name);
+ }
+ return path;
+ }
+
+ @Override
+ public void enter(NodeState before, NodeState after) {
+ }
+
+ @Override
+ public void leave(NodeState before, NodeState after)
+ throws CommitFailedException {
+ if (propertiesChanged || !before.exists()) {
+ try {
+ solrServer.add(docFromState(after));
+ } catch (SolrServerException e) {
+ throw new CommitFailedException(
+ "Solr", 2, "Failed to add a document to Solr", e);
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Solr", 6, "Failed to send data to Solr", e);
+ }
+ }
+
+ if (parent == null) {
+ try {
+ OakSolrUtils.commitByPolicy(
+ solrServer, configuration.getCommitPolicy());
+ } catch (SolrServerException e) {
+ throw new CommitFailedException(
+ "Solr", 3, "Failed to commit changes to Solr", e);
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Solr", 6, "Failed to send data to Solr", e);
+ }
+ }
+ }
+
+ @Override
+ public void propertyAdded(PropertyState after) {
+ propertiesChanged = true;
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ propertiesChanged = true;
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ propertiesChanged = true;
+ }
+
+ @Override
+ public Editor childNodeAdded(String name, NodeState after) {
+ return new SolrIndexEditor(this, name);
+ }
+
+ @Override
+ public Editor childNodeChanged(
+ String name, NodeState before, NodeState after) {
+ return new SolrIndexEditor(this, name);
+ }
+
+ @Override
+ public Editor childNodeDeleted(String name, NodeState before)
+ throws CommitFailedException {
+ // TODO: Proper escaping
+ String path = PathUtils.concat(getPath(), name).replace("/", "\\/");
+
+ try {
+ solrServer.deleteByQuery(String.format(
+ "%s:%s\\/*", configuration.getPathField(), path));
+ } catch (SolrServerException e) {
+ throw new CommitFailedException(
+ "Solr", 5, "Failed to remove documents from Solr", e);
+ } catch (IOException e) {
+ throw new CommitFailedException(
+ "Solr", 6, "Failed to send data to Solr", e);
+ }
+
+ return null; // no need to recurse down the removed subtree
+ }
+
+ private SolrInputDocument docFromState(NodeState state) {
+ SolrInputDocument inputDocument = new SolrInputDocument();
+ String path = getPath();
+ if (!path.endsWith("/")) {
+ path = path + "/";
+ }
+ inputDocument.addField(configuration.getPathField(), path);
+ for (PropertyState property : state.getProperties()) {
+ // try to get the field to use for this property from configuration
+ String fieldName = configuration.getFieldNameFor(property.getType());
+ if (fieldName != null) {
+ inputDocument.addField(
+ fieldName, property.getValue(property.getType()));
+ } else {
+ // or fallback to adding propertyName:stringValue(s)
+ if (property.isArray()) {
+ for (String s : property.getValue(Type.STRINGS)) {
+ inputDocument.addField(property.getName(), s);
+ }
+ } else {
+ inputDocument.addField(
+ property.getName(), property.getValue(Type.STRING));
+ }
+ }
+ }
+ return inputDocument;
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditor.java
------------------------------------------------------------------------------
svn:eol-style = native
Copied: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorProvider.java (from r1491447, jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorProvider.java?p2=jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorProvider.java&p1=jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java&r1=1491447&r2=1491780&rev=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookProvider.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorProvider.java Tue Jun 11 13:00:04 2013
@@ -6,7 +6,7 @@
* (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
+ * 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,
@@ -16,14 +16,13 @@
*/
package org.apache.jackrabbit.oak.plugins.index.solr.index;
-
-import javax.annotation.CheckForNull;
+import static org.apache.felix.scr.annotations.ReferencePolicy.STATIC;
+import static org.apache.felix.scr.annotations.ReferencePolicyOption.GREEDY;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.ReferencePolicyOption;
import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfigurationProvider;
@@ -31,47 +30,53 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
/**
- * Service that provides {@link SolrIndexHookProvider} based {@link IndexEditor}s.
- *
- * @see org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider
+ * Service that provides Lucene based {@link IndexEditor}s
+ *
+ * @see SolrIndexEditor
+ * @see IndexEditorProvider
+ *
*/
@Component
@Service(IndexEditorProvider.class)
-public class SolrIndexHookProvider implements IndexEditorProvider {
+public class SolrIndexEditorProvider implements IndexEditorProvider {
- private final Logger log = LoggerFactory.getLogger(SolrIndexHookProvider.class);
-
- @Reference(policyOption = ReferencePolicyOption.GREEDY, policy = ReferencePolicy.STATIC)
+ @Reference(policyOption = GREEDY, policy = STATIC)
private SolrServerProvider solrServerProvider;
- @Reference(policyOption = ReferencePolicyOption.GREEDY, policy = ReferencePolicy.STATIC)
+ @Reference(policyOption = GREEDY, policy = STATIC)
private OakSolrConfigurationProvider oakSolrConfigurationProvider;
- public SolrIndexHookProvider() {
- }
-
- public SolrIndexHookProvider(SolrServerProvider solrServerProvider, OakSolrConfigurationProvider oakSolrConfigurationProvider) {
+ public SolrIndexEditorProvider(
+ SolrServerProvider solrServerProvider,
+ OakSolrConfigurationProvider oakSolrConfigurationProvider) {
this.solrServerProvider = solrServerProvider;
this.oakSolrConfigurationProvider = oakSolrConfigurationProvider;
}
- @Override @CheckForNull
- public Editor getIndexEditor(String type, NodeBuilder builder) {
- if (SolrQueryIndex.TYPE.equals(type) && solrServerProvider != null && oakSolrConfigurationProvider != null) {
+ public SolrIndexEditorProvider() {
+ }
+
+ @Override
+ public Editor getIndexEditor(
+ String type, NodeBuilder definition, NodeState root)
+ throws CommitFailedException {
+ if (SolrQueryIndex.TYPE.equals(type)
+ && solrServerProvider != null
+ && oakSolrConfigurationProvider != null) {
try {
- if (log.isDebugEnabled()) {
- log.debug("Creating a Solr index hook");
- }
- return new SolrIndexDiff(builder, solrServerProvider.getSolrServer(), oakSolrConfigurationProvider.getConfiguration());
+ return new SolrIndexEditor(
+ definition,
+ solrServerProvider.getSolrServer(),
+ oakSolrConfigurationProvider.getConfiguration());
} catch (Exception e) {
- log.error("unable to create Solr IndexHook ", e);
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
}
return null;
}
-}
\ No newline at end of file
+}
Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexEditorProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java Tue Jun 11 13:00:04 2013
@@ -16,11 +16,9 @@
*/
package org.apache.jackrabbit.oak.plugins.index.solr.query;
-
import java.util.Collection;
import org.apache.jackrabbit.oak.api.PropertyValue;
-import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
import org.apache.jackrabbit.oak.spi.query.Cursor;
import org.apache.jackrabbit.oak.spi.query.Filter;
@@ -44,19 +42,19 @@ public class SolrQueryIndex implements Q
private static final Logger log = LoggerFactory.getLogger(SolrQueryIndex.class);
public static final String TYPE = "solr";
- private final IndexDefinition index;
+ private final String name;
private final SolrServer solrServer;
private final OakSolrConfiguration configuration;
- public SolrQueryIndex(IndexDefinition indexDefinition, SolrServer solrServer, OakSolrConfiguration configuration) {
- this.index = indexDefinition;
+ public SolrQueryIndex(String name, SolrServer solrServer, OakSolrConfiguration configuration) {
+ this.name = name;
this.solrServer = solrServer;
this.configuration = configuration;
}
@Override
public String getIndexName() {
- return index.getName();
+ return name;
}
@Override
@@ -94,13 +92,13 @@ public class SolrQueryIndex implements Q
if (fieldName != null) {
queryBuilder.append(fieldName);
queryBuilder.append(':');
- // TODO : remove this hack for all descendants of root node
- if (path.equals("\\/") && pathRestriction.equals(Filter.PathRestriction.ALL_CHILDREN)) {
+ queryBuilder.append(path);
+ if (!path.equals("\\/")) {
+ queryBuilder.append("\\/");
+ }
+ // TODO: Also handle other path restriction types
+ if (pathRestriction.equals(Filter.PathRestriction.ALL_CHILDREN)) {
queryBuilder.append("*");
- } else {
- queryBuilder.append("\"");
- queryBuilder.append(path);
- queryBuilder.append("\"");
}
queryBuilder.append(" ");
}
@@ -128,6 +126,9 @@ public class SolrQueryIndex implements Q
queryBuilder.append(configuration.getPathField());
queryBuilder.append(':');
queryBuilder.append(first);
+ if (!first.equals("\\/")) {
+ queryBuilder.append("\\/");
+ }
} else {
queryBuilder.append(fieldName).append(':');
if (pr.first != null && pr.last != null && pr.first.equals(pr.last)) {
@@ -189,8 +190,7 @@ public class SolrQueryIndex implements Q
if (c == '\\' || c == '!' || c == '(' || c == ')' ||
c == ':' || c == '^' || c == '[' || c == ']' || c == '/' ||
c == '{' || c == '}' || c == '~' || c == '*' || c == '?' ||
- c == '-'
- ) {
+ c == '-' || c == ' ') {
sb.append('\\');
}
sb.append(c);
@@ -240,7 +240,13 @@ public class SolrQueryIndex implements Q
return new IndexRow() {
@Override
public String getPath() {
- return String.valueOf(doc.getFieldValue(configuration.getPathField()));
+ String path = String.valueOf(doc.getFieldValue(
+ configuration.getPathField()));
+ if ("/".equals(path)) {
+ return "/";
+ } else {
+ return path.substring(0, path.length() - 1);
+ }
}
@Override
Modified: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java Tue Jun 11 13:00:04 2013
@@ -16,6 +16,9 @@
*/
package org.apache.jackrabbit.oak.plugins.index.solr.query;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
@@ -25,17 +28,17 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.ReferencePolicyOption;
import org.apache.felix.scr.annotations.Service;
-import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfigurationProvider;
import org.apache.jackrabbit.oak.plugins.index.solr.SolrServerProvider;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.buildIndexDefinitions;
-
/**
* {@link QueryIndexProvider} for {@link SolrQueryIndex}
*/
@@ -63,18 +66,26 @@ public class SolrQueryIndexProvider impl
@Override
public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
List<QueryIndex> tempIndexes = new ArrayList<QueryIndex>();
- for (IndexDefinition child : buildIndexDefinitions(nodeState, "/",
- SolrQueryIndex.TYPE)) {
- if (log.isDebugEnabled()) {
- log.debug("found a Solr index definition {}", child);
+ if (solrServerProvider == null || oakSolrConfigurationProvider == null) {
+ return tempIndexes;
+ }
+ NodeState definitions = nodeState.getChildNode(INDEX_DEFINITIONS_NAME);
+ for (ChildNodeEntry entry : definitions.getChildNodeEntries()) {
+ NodeState definition = entry.getNodeState();
+ PropertyState type = definition.getProperty(TYPE_PROPERTY_NAME);
+ if (type != null
+ && SolrQueryIndex.TYPE.equals(type.getValue(Type.STRING))) {
+ log.debug("found a Solr index definition {}", entry.getName());
}
try {
- if (solrServerProvider != null && oakSolrConfigurationProvider != null) {
- tempIndexes.add(new SolrQueryIndex(child, solrServerProvider.getSolrServer(), oakSolrConfigurationProvider.getConfiguration()));
- }
+ tempIndexes.add(new SolrQueryIndex(
+ entry.getName(),
+ solrServerProvider.getSolrServer(),
+ oakSolrConfigurationProvider.getConfiguration()));
} catch (Exception e) {
- log.error("unable to create Solr query index at {} due to {}", new Object[]{child.getPath(), e});
+ log.error("unable to create Solr query index at " + entry.getName(), e);
}
+
}
return tempIndexes;
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java Tue Jun 11 13:00:04 2013
@@ -16,10 +16,18 @@
*/
package org.apache.jackrabbit.oak.plugins.index.solr;
+import javax.security.auth.Subject;
+
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.core.MicroKernelImpl;
import org.apache.jackrabbit.oak.core.RootImpl;
import org.apache.jackrabbit.oak.kernel.KernelNodeStore;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexEditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.commit.PostCommitHook;
+import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.solr.client.solrj.SolrServer;
import org.junit.After;
@@ -32,16 +40,21 @@ public abstract class SolrBaseTest {
protected KernelNodeStore store;
protected NodeState state;
+ protected TestUtils provider;
protected SolrServer server;
protected OakSolrConfiguration configuration;
+ protected EditorHook hook;
@Before
public void setUp() throws Exception {
MicroKernel microKernel = new MicroKernelImpl();
store = new KernelNodeStore(microKernel);
state = createInitialState(microKernel);
- server = TestUtils.createSolrServer();
- configuration = TestUtils.getTestConfiguration();
+ provider = new TestUtils();
+ server = provider.getSolrServer();
+ configuration = provider.getConfiguration();
+ hook = new EditorHook(new IndexUpdateProvider(
+ new SolrIndexEditorProvider(provider, provider)));
}
@After
@@ -53,16 +66,16 @@ public abstract class SolrBaseTest {
}
}
+ protected RootImpl createRootImpl() {
+ return new RootImpl(store, hook, PostCommitHook.EMPTY, "solr-query-engine-it", new Subject(),
+ new OpenSecurityProvider(), new CompositeQueryIndexProvider());
+ }
+
protected NodeState createInitialState(MicroKernel microKernel) {
String jsop = "^\"a\":1 ^\"b\":2 ^\"c\":3 +\"x\":{} +\"y\":{} +\"z\":{} " +
- "+\"solrIdx\":{\"core\":\"oak\", \"solrHome\":\"" +
- TestUtils.SOLR_HOME_PATH + "\", \"solrConfig\":\"" +
- TestUtils.SOLRCONFIG_PATH + "\"} ";
+ "+\"oak:index\":{\"solr\":{\"type\":\"solr\"}}";
microKernel.commit("/", jsop, microKernel.getHeadRevision(), "test data");
return store.getRoot();
}
- protected RootImpl createRootImpl() {
- return new RootImpl(store);
- }
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java Tue Jun 11 13:00:04 2013
@@ -20,73 +20,35 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
-import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexDiff;
import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
-import org.apache.jackrabbit.oak.spi.commit.Editor;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndexProvider;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.core.CoreContainer;
-import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.buildIndexDefinitions;
-
/**
* Utility class for tests
*/
-public class TestUtils {
+public class TestUtils
+ implements SolrServerProvider, OakSolrConfigurationProvider {
static final String SOLR_HOME_PATH = "target/test-classes/solr";
static final String SOLRCONFIG_PATH = "target/test-classes/solr/solr.xml";
- public static QueryIndexProvider getTestQueryIndexProvider(final SolrServer solrServer, final OakSolrConfiguration configuration) {
- return new QueryIndexProvider() {
- @Nonnull
- @Override
- public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
- List<QueryIndex> tempIndexes = new ArrayList<QueryIndex>();
- for (IndexDefinition child : buildIndexDefinitions(nodeState, "/",
- SolrQueryIndex.TYPE)) {
- try {
- tempIndexes.add(new SolrQueryIndex(child, solrServer, configuration));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- return tempIndexes;
- }
- };
- }
-
- public static IndexEditorProvider getTestIndexHookProvider(final SolrServer solrServer, final OakSolrConfiguration configuration) {
- return new IndexEditorProvider() {
- @Override @CheckForNull
- public Editor getIndexEditor(String type, NodeBuilder builder) {
- if (SolrQueryIndex.TYPE.equals(type)) {
- try {
- return new SolrIndexDiff(builder, solrServer, configuration);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- return null;
- }
- };
-
- }
-
- public static SolrServer createSolrServer() throws Exception {
+ public static SolrServer createSolrServer() {
CoreContainer coreContainer = new CoreContainer(SOLR_HOME_PATH);
- coreContainer.load(SOLR_HOME_PATH, new File(SOLRCONFIG_PATH));
+ try {
+ coreContainer.load(SOLR_HOME_PATH, new File(SOLRCONFIG_PATH));
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
return new EmbeddedSolrServer(coreContainer, "oak");
}
@@ -140,4 +102,19 @@ public class TestUtils {
};
}
+
+ private final SolrServer solrServer = createSolrServer();
+
+ private final OakSolrConfiguration configuration = getTestConfiguration();
+
+ @Override
+ public SolrServer getSolrServer() {
+ return solrServer;
+ }
+
+ @Override
+ public OakSolrConfiguration getConfiguration() {
+ return configuration;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java Tue Jun 11 13:00:04 2013
@@ -36,12 +36,6 @@ import org.junit.Test;
*/
public class SolrCommitHookIT extends SolrBaseTest {
- @Override
- protected RootImpl createRootImpl() {
- return new RootImpl(store, new SolrCommitHook(server), PostCommitHook.EMPTY, "solr-commit-hook-it", new Subject(),
- new OpenSecurityProvider(), new CompositeQueryIndexProvider());
- }
-
@Test
public void testAddSomeNodes() throws Exception {
Root r = createRootImpl();
@@ -63,21 +57,24 @@ public class SolrCommitHookIT extends So
@Test
public void testRemoveNode() throws Exception {
- // pre-populate the index with a node that is already in Oak
- SolrInputDocument doc = new SolrInputDocument();
- doc.addField("path_exact", "z");
- server.add(doc);
- server.commit();
-
- // remove the node in oak
Root r = createRootImpl();
- r.getTree("/").getChild("z").remove();
+
+ // Add a node
+ r.getTree("/").addChild("testRemoveNode").setProperty("foo", "bar");
r.commit();
// check the node is not in Solr anymore
SolrQuery query = new SolrQuery();
- query.setQuery("path_exact:z");
- QueryResponse queryResponse = server.query(query);
- assertTrue("item with id:z was found in the index", queryResponse.getResults().size() == 0);
+ query.setQuery("path_exact:\\/testRemoveNode\\/");
+ assertTrue("item with id:testRemoveNode was not found in the index",
+ server.query(query).getResults().size() > 0);
+
+ // remove the node in oak
+ r.getTree("/").getChild("testRemoveNode").remove();
+ r.commit();
+
+ // check the node is not in Solr anymore
+ assertTrue("item with id:testRemoveNode was found in the index",
+ server.query(query).getResults().size() == 0);
}
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java Tue Jun 11 13:00:04 2013
@@ -16,15 +16,12 @@
*/
package org.apache.jackrabbit.oak.plugins.index.solr.index;
-import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.IndexDefinitionImpl;
+import java.util.Set;
+
import org.apache.jackrabbit.oak.query.ast.Operator;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.plugins.index.solr.SolrBaseTest;
import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
-import org.apache.jackrabbit.oak.spi.commit.Editor;
-import org.apache.jackrabbit.oak.spi.commit.EditorHook;
-import org.apache.jackrabbit.oak.spi.commit.EditorProvider;
import org.apache.jackrabbit.oak.spi.query.Cursor;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.IndexRow;
@@ -32,8 +29,10 @@ import org.apache.jackrabbit.oak.spi.que
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrQuery;
import org.junit.Test;
+import static com.google.common.collect.Sets.newHashSet;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -56,21 +55,11 @@ public class SolrIndexHookIT extends Sol
builder.child("newnode").setProperty("prop", "val");
NodeState after = builder.getNodeState();
- EditorProvider provider = new EditorProvider() {
- @Override
- public Editor getRootEditor(NodeState before, NodeState after,
- NodeBuilder builder) {
- return new SolrIndexHook("/", builder, server);
- }
- };
- EditorHook hook = new EditorHook(provider);
NodeState indexed = hook.processCommit(before, after);
- IndexDefinition testDef = new IndexDefinitionImpl("solr",
- "solr", "/oak:index/solr");
- QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+ QueryIndex queryIndex = new SolrQueryIndex("solr", server, configuration);
FilterImpl filter = new FilterImpl(null, null);
- filter.restrictPath("newnode", Filter.PathRestriction.EXACT);
+ filter.restrictPath("/newnode", Filter.PathRestriction.EXACT);
filter.restrictProperty("prop", Operator.EQUAL,
PropertyValues.newString("val"));
Cursor cursor = queryIndex.query(filter, indexed);
@@ -78,7 +67,7 @@ public class SolrIndexHookIT extends Sol
assertTrue("no results found", cursor.hasNext());
IndexRow next = cursor.next();
assertNotNull("first returned item should not be null", next);
- assertEquals("newnode", next.getPath());
+ assertEquals("/newnode", next.getPath());
assertFalse(cursor.hasNext());
}
@@ -95,19 +84,9 @@ public class SolrIndexHookIT extends Sol
builder.setProperty("foo", "bar");
NodeState after = builder.getNodeState();
- EditorProvider provider = new EditorProvider() {
- @Override
- public Editor getRootEditor(NodeState before, NodeState after,
- NodeBuilder builder) {
- return new SolrIndexHook("/", builder, server);
- }
- };
- EditorHook hook = new EditorHook(provider);
NodeState indexed = hook.processCommit(before, after);
- IndexDefinition testDef = new IndexDefinitionImpl("solr",
- "solr", "/oak:index/solr");
- QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+ QueryIndex queryIndex = new SolrQueryIndex("solr", server, configuration);
FilterImpl filter = new FilterImpl(null, null);
filter.restrictProperty("foo", Operator.EQUAL,
PropertyValues.newString("bar"));
@@ -139,31 +118,24 @@ public class SolrIndexHookIT extends Sol
NodeState after = builder.getNodeState();
- EditorProvider provider = new EditorProvider() {
- @Override
- public Editor getRootEditor(NodeState before, NodeState after,
- NodeBuilder builder) {
- return new SolrIndexHook("/", builder, server);
- }
- };
- EditorHook hook = new EditorHook(provider);
NodeState indexed = hook.processCommit(before, after);
- IndexDefinition testDef = new IndexDefinitionImpl("solr",
- "solr", "/oak:index/solr");
- QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+ QueryIndex queryIndex = new SolrQueryIndex("solr", server, configuration);
FilterImpl filter = new FilterImpl(null, null);
filter.restrictProperty("foo", Operator.EQUAL,
PropertyValues.newString("bar"));
filter.restrictFulltextCondition("bar");
Cursor cursor = queryIndex.query(filter, indexed);
- assertTrue(cursor.hasNext());
- assertEquals("/", cursor.next().getPath());
- assertEquals("a", cursor.next().getPath());
- assertEquals("a/b", cursor.next().getPath());
- assertEquals("a/b/c", cursor.next().getPath());
- assertFalse(cursor.hasNext());
+ Set<String> paths = newHashSet();
+ while (cursor.hasNext()) {
+ paths.add(cursor.next().getPath());
+ }
+ assertTrue(paths.remove("/"));
+ assertTrue(paths.remove("/a"));
+ assertTrue(paths.remove("/a/b"));
+ assertTrue(paths.remove("/a/b/c"));
+ assertTrue(paths.isEmpty());
}
}
Modified: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java?rev=1491780&r1=1491779&r2=1491780&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java Tue Jun 11 13:00:04 2013
@@ -27,8 +27,8 @@ import java.util.Iterator;
import org.apache.jackrabbit.oak.Oak;
import org.apache.jackrabbit.oak.api.ContentRepository;
import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
import org.apache.jackrabbit.oak.plugins.index.solr.TestUtils;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
import org.apache.jackrabbit.oak.query.AbstractQueryTest;
import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
@@ -60,13 +60,13 @@ public class SolrIndexQueryTest extends
@Override
protected ContentRepository createRepository() {
- OakSolrConfiguration testConfiguration = TestUtils.getTestConfiguration();
+ TestUtils provider = new TestUtils();
+ solrServer = provider.getSolrServer();
try {
- solrServer = TestUtils.createSolrServer();
return new Oak().with(new InitialContent())
.with(new OpenSecurityProvider())
- .with(TestUtils.getTestQueryIndexProvider(solrServer, testConfiguration))
- .with(TestUtils.getTestIndexHookProvider(solrServer, testConfiguration))
+ .with(new SolrQueryIndexProvider(provider, provider))
+ .with(new SolrIndexEditorProvider(provider, provider))
.createContentRepository();
} catch (Exception e) {
throw new RuntimeException(e);