blob: b8aeb6a8c4ae5dbb93be7f23736d503c483b0843 [file] [log] [blame]
/*
* 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.lucene;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.index.ContextAwareCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexCommitCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
import org.apache.jackrabbit.oak.plugins.index.IndexingContext;
import org.apache.jackrabbit.oak.plugins.index.lucene.IndexTracker;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexDefinition;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditor;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorContext;
import org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil;
import org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.DocumentQueue;
import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
import org.apache.jackrabbit.oak.spi.commit.CommitContext;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.commit.SimpleCommitContext;
import org.apache.jackrabbit.oak.spi.mount.Mounts;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.junit.Test;
import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
import static org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
import static org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class LuceneIndexEditorProviderTest {
private NodeState root = INITIAL_CONTENT;
private NodeBuilder builder = root.builder();
@Test
public void readOnlyBuilderUsedForSync() throws Exception {
LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
null,
null,
null,
Mounts.defaultMountInfoProvider());
editorProvider.setIndexingQueue(mock(DocumentQueue.class));
IndexUpdateCallback callback = new TestCallback("/oak:index/fooIndex", newCommitInfo(), false, false);
NodeBuilder defnBuilder = createIndexDefinition("fooIndex").builder();
Editor editor = editorProvider.getIndexEditor(TYPE_LUCENE, defnBuilder, root, callback);
LuceneIndexEditor luceneEditor = (LuceneIndexEditor) editor;
NodeBuilder builderFromContext =
(NodeBuilder) FieldUtils.readField(luceneEditor.getContext(), "definitionBuilder", true);
try {
builderFromContext.setProperty("foo", "bar");
fail("Should have been read only builder");
} catch (UnsupportedOperationException ignore) {
}
}
@Test
public void reuseOldIndexDefinition() throws Exception{
IndexTracker tracker = mock(IndexTracker.class);
LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
tracker,
null,
null,
Mounts.defaultMountInfoProvider());
editorProvider.setIndexingQueue(mock(DocumentQueue.class));
//Set up a different IndexDefinition which needs to be returned
//from tracker with a marker property
NodeBuilder testBuilder = createIndexDefinition("fooIndex").builder();
testBuilder.setProperty("foo", "bar");
LuceneIndexDefinition defn = new LuceneIndexDefinition(root, testBuilder.getNodeState(), "/foo");
when(tracker.getIndexDefinition("/oak:index/fooIndex")).thenReturn(defn);
IndexUpdateCallback callback = new TestCallback("/oak:index/fooIndex", newCommitInfo(), false, false);
NodeBuilder defnBuilder = createIndexDefinition("fooIndex").builder();
Editor editor = editorProvider.getIndexEditor(TYPE_LUCENE, defnBuilder, root, callback);
LuceneIndexEditor luceneEditor = (LuceneIndexEditor) editor;
LuceneIndexEditorContext context = luceneEditor.getContext();
//Definition should reflect the marker property
assertEquals("bar", context.getDefinition().getDefinitionNodeState().getString("foo"));
}
@Test
public void editorNullInCaseOfReindex() throws Exception{
LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
null,
null,
null,
Mounts.defaultMountInfoProvider());
editorProvider.setIndexingQueue(mock(DocumentQueue.class));
IndexUpdateCallback callback = new TestCallback("/oak:index/fooIndex", newCommitInfo(), true, false);
NodeBuilder defnBuilder = createIndexDefinition("fooIndex").builder();
Editor editor = editorProvider.getIndexEditor(TYPE_LUCENE, defnBuilder, root, callback);
assertNull(editor);
}
private NodeState createIndexDefinition(String idxName) {
NodeBuilder idx = newLucenePropertyIndexDefinition(builder.child("oak:index"),
idxName, ImmutableSet.of("foo"), "async");
TestUtil.enableIndexingMode(idx, FulltextIndexConstants.IndexingMode.NRT);
LuceneIndexEditorContext.configureUniqueId(idx);
LuceneIndexDefinition.updateDefinition(idx);
return idx.getNodeState();
}
private CommitInfo newCommitInfo() {
CommitInfo info = new CommitInfo("admin", "s1",
ImmutableMap.<String, Object>of(CommitContext.NAME, new SimpleCommitContext()));
return info;
}
private static class TestCallback implements IndexUpdateCallback, IndexingContext, ContextAwareCallback {
private final String indexPath;
private final CommitInfo commitInfo;
private final boolean reindexing;
private final boolean async;
private TestCallback(String indexPath, CommitInfo commitInfo, boolean reindexing, boolean async) {
this.indexPath = indexPath;
this.commitInfo = commitInfo;
this.reindexing = reindexing;
this.async = async;
}
@Override
public String getIndexPath() {
return indexPath;
}
@Override
public CommitInfo getCommitInfo() {
return commitInfo;
}
@Override
public boolean isReindexing() {
return reindexing;
}
@Override
public boolean isAsync() {
return async;
}
@Override
public void indexUpdateFailed(Exception e) {
}
@Override
public void indexUpdate() throws CommitFailedException {
}
@Override
public IndexingContext getIndexingContext() {
return this;
}
@Override
public void registerIndexCommitCallback(IndexCommitCallback callback) {
}
}
}