diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporter.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporter.java index fbe8f9e7c91..a2362eb5cb3 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporter.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporter.java @@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.plugins.index.MetricsUtils; import org.apache.jackrabbit.oak.plugins.index.importer.AsyncIndexerLock.LockToken; import org.apache.jackrabbit.oak.plugins.index.upgrade.IndexDisabler; +import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; import org.apache.jackrabbit.oak.spi.commit.EditorDiff; import org.apache.jackrabbit.oak.spi.commit.VisibleEditor; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; @@ -58,6 +59,9 @@ import static org.apache.jackrabbit.oak.commons.conditions.Validate.checkArgument; import static java.util.Objects.requireNonNull; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEXING_MODE_NRT; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME; +import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME; import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.INDEXING_PHASE_LOGGER; import static org.apache.jackrabbit.oak.plugins.index.importer.IndexDefinitionUpdater.INDEX_DEFINITIONS_JSON; import static org.apache.jackrabbit.oak.plugins.index.importer.NodeStoreUtils.mergeWithConcurrentCheck; @@ -67,6 +71,10 @@ public class IndexImporter { * Symbolic name use to indicate sync indexes */ static final String ASYNC_LANE_SYNC = "sync"; + /** + * Symbolic name use to indicate elasticsearch index type + */ + static final String TYPE_ELASTICSEARCH = "elasticsearch"; /* * System property name for flag for preserve checkpoint. If this is set to true, then checkpoint cleanup will be skipped. * Default is set to false. @@ -200,6 +208,20 @@ void switchLanes() throws CommitFailedException { if (!indexInfo.newIndex) { NodeBuilder idxBuilder = NodeStoreUtils.childBuilder(builder, indexInfo.indexPath); indexPathsToUpdate.add(indexInfo.indexPath); + String idxBuilderType = idxBuilder.getString(TYPE_PROPERTY_NAME); + + // check if provided index definitions is of different type than existing one + // also check if one of them is an elasticsearch type + if (idxBuilderType != null && + !idxBuilderType.equals(indexInfo.type) && + (idxBuilderType.equals(TYPE_ELASTICSEARCH) || indexInfo.type.equals(TYPE_ELASTICSEARCH))) { + + LOG.info("Provided index [{}] has a different type [{}] compared to the existing index [{}]." + + " Using lane from the index definition provided", indexInfo.indexPath, indexInfo.type, idxBuilderType); + + PropertyState asyncProperty = PropertyStates.createProperty(ASYNC_PROPERTY_NAME, List.of(indexInfo.asyncLaneName), Type.STRINGS); + idxBuilder.setProperty(asyncProperty); + } AsyncLaneSwitcher.switchLane(idxBuilder, AsyncLaneSwitcher.getTempLaneName(indexInfo.asyncLaneName)); } } diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporterTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporterTest.java index 121c56e0383..260967d5c01 100644 --- a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporterTest.java +++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/importer/IndexImporterTest.java @@ -25,6 +25,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.text.MessageFormat; +import java.util.List; import java.util.Properties; import java.util.Set; @@ -77,6 +78,7 @@ import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME; import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition; import static org.apache.jackrabbit.oak.plugins.index.importer.AsyncIndexerLock.NOOP_LOCK; +import static org.apache.jackrabbit.oak.plugins.index.importer.AsyncLaneSwitcher.ASYNC_PREVIOUS; import static org.apache.jackrabbit.oak.plugins.index.importer.IndexDefinitionUpdater.INDEX_DEFINITIONS_JSON; import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE; import static org.junit.Assert.assertEquals; @@ -142,6 +144,50 @@ public void switchLanes() throws Exception{ assertEquals(AsyncLaneSwitcher.getTempLaneName("async"), idxb.getString(ASYNC_PROPERTY_NAME)); } + @Test + public void switchLanesLuceneToElastic() throws Exception{ + NodeBuilder builder = store.getRoot().builder(); + builder.child("idx-a").setProperty("type", "elasticsearch"); + builder.child("idx-a").setProperty("async", "elastic-async"); + + store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + createIndexDirs("/idx-a"); + + builder.child("idx-a").setProperty("type", "lucene"); + builder.child("idx-a").setProperty("async", asList("async", "nrt"), Type.STRINGS); + + store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + + IndexImporter importer = new IndexImporter(store, temporaryFolder.getRoot(), provider, NOOP_LOCK); + importer.switchLanes(); + + NodeState idxa = NodeStateUtils.getNode(store.getRoot(), "/idx-a"); + assertEquals(AsyncLaneSwitcher.getTempLaneName("elastic-async"), idxa.getString(ASYNC_PROPERTY_NAME)); + assertEquals(idxa.getStrings(ASYNC_PREVIOUS), List.of("elastic-async")); + } + + @Test + public void switchLanesElasticToLucene() throws Exception{ + NodeBuilder builder = store.getRoot().builder(); + builder.child("idx-a").setProperty("type", "lucene"); + builder.child("idx-a").setProperty("async", List.of("async"), Type.STRINGS); + + store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + createIndexDirs("/idx-a"); + + builder.child("idx-a").setProperty("type", "elasticsearch"); + builder.child("idx-a").setProperty("async", List.of("elastic-async"), Type.STRINGS); + + store.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + + IndexImporter importer = new IndexImporter(store, temporaryFolder.getRoot(), provider, NOOP_LOCK); + importer.switchLanes(); + + NodeState idxa = NodeStateUtils.getNode(store.getRoot(), "/idx-a"); + assertEquals(AsyncLaneSwitcher.getTempLaneName("async"), idxa.getString(ASYNC_PROPERTY_NAME)); + assertEquals(idxa.getStrings(ASYNC_PREVIOUS), List.of("async")); + } + @Test(expected = NullPointerException.class) public void importData_NoProvider() throws Exception{ NodeBuilder builder = store.getRoot().builder();