diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a66ae9098aa..81a7e0619e7 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -34,6 +34,8 @@ Improvements * SOLR-17516: `LBHttp2SolrClient` is now generic, adding support for `HttpJdkSolrClient`. (James Dyer) +* SOLR-17640: Support different filesystem implementations with EmbeddedSolrServer (Andrey Bozhko) + Optimizations --------------------- * SOLR-17568: The CLI bin/solr export tool now contacts the appropriate nodes directly for data instead of proxying through one. diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java index df44cda12e2..ec884a026c1 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -23,7 +23,6 @@ import java.lang.invoke.MethodHandles; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Map.Entry; import net.jcip.annotations.NotThreadSafe; @@ -148,12 +147,11 @@ public String lookupZKManagedSchemaPath() { */ public Path lookupLocalManagedSchemaPath() { final Path legacyManagedSchemaPath = - Paths.get( - loader.getConfigPath().toString(), - ManagedIndexSchemaFactory.LEGACY_MANAGED_SCHEMA_RESOURCE_NAME); + loader + .getConfigPath() + .resolve(ManagedIndexSchemaFactory.LEGACY_MANAGED_SCHEMA_RESOURCE_NAME); - Path managedSchemaPath = - Paths.get(loader.getConfigPath().toString(), managedSchemaResourceName); + Path managedSchemaPath = loader.getConfigPath().resolve(managedSchemaResourceName); // check if we are using the legacy managed-schema file name. if (Files.exists(legacyManagedSchemaPath)) { diff --git a/solr/core/src/test-files/solr/configsets/zipfs/conf/managed-schema.xml b/solr/core/src/test-files/solr/configsets/zipfs/conf/managed-schema.xml new file mode 100644 index 00000000000..61c720ee612 --- /dev/null +++ b/solr/core/src/test-files/solr/configsets/zipfs/conf/managed-schema.xml @@ -0,0 +1,32 @@ + + + + + id + + + + + + + + + + + + diff --git a/solr/core/src/test-files/solr/configsets/zipfs/conf/solrconfig.xml b/solr/core/src/test-files/solr/configsets/zipfs/conf/solrconfig.xml new file mode 100644 index 00000000000..933e181e35a --- /dev/null +++ b/solr/core/src/test-files/solr/configsets/zipfs/conf/solrconfig.xml @@ -0,0 +1,52 @@ + + + + + ${tests.luceneMatchVersion:LATEST} + + ${solr.data.dir:} + + + + + + + + + ${solr.ulog.dir:} + + + + + + + explicit + 10 + + + + + + org.apache.solr.rest.ManagedResourceStorage$InMemoryStorageIO + + + diff --git a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java index ec6d688fe17..825aaaa4ae1 100644 --- a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java +++ b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java @@ -17,7 +17,12 @@ package org.apache.solr.client.solrj.embedded; import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import org.apache.commons.io.file.PathUtils; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.request.CoreAdminRequest; @@ -58,4 +63,64 @@ public void testNodeConfigConstructor() throws Exception { assertEquals(1, server.query("newcore", new SolrQuery("*:*")).getResults().getNumFound()); } } + + @SuppressWarnings("removal") + @Test + public void testPathConstructorZipFS() throws Exception { + assumeTrue( + "Test only works without Security Manager due to SecurityConfHandlerLocal " + + "missing permission to read /1/2/3/4/security.json file", + System.getSecurityManager() == null); + + Path dataDir = createTempDir("data-dir"); + Path archive = createTempFile("configset", ".zip"); + Files.delete(archive); + + // When : + // Prepare a zip archive which contains + // the configset files as shown below: + // + // configset.zip + // └── 1 + // └── 2 + // └── 3 + // └── 4 + // ├── data + // │ └── core1 + // │ ├── conf + // │ │ ├── managed-schema.xml + // │ │ └── solrconfig.xml + // │ └── core.properties + // └── solr.xml + + var zipFs = FileSystems.newFileSystem(archive, Map.of("create", "true")); + try (zipFs) { + var destDir = zipFs.getPath("1", "2", "3", "4"); + var confDir = destDir.resolve("data/core1/conf"); + Files.createDirectories(confDir); + Files.copy(TEST_PATH().resolve("solr.xml"), destDir.resolve("solr.xml")); + PathUtils.copyDirectory(configset("zipfs"), confDir); + + // Need to make sure we circumvent any Solr attempts + // to modify the archive when we point solrHome to + // the archive content. Steps to achieve that: + // - set a custom data dir, + // - disable the update log, + // - configure the rest manager in the solrconfig.xml with InMemoryStorageIO. + Files.writeString( + confDir.resolveSibling("core.properties"), + String.join("\n", "solr.ulog.enable=false", "solr.data.dir=" + dataDir)); + } + + // Then : + // EmbeddedSolrServer successfully loads the core + // using the configset directly from the archive + var configSetFs = FileSystems.newFileSystem(archive); + try (configSetFs) { + var server = new EmbeddedSolrServer(configSetFs.getPath("/1/2/3/4"), null); + try (server) { + assertEquals(List.of("core1"), server.getCoreContainer().getAllCoreNames()); + } + } + } }