From 507ee790ce1426984c50e9a52152365ad33ad363 Mon Sep 17 00:00:00 2001 From: Vishnu Priya Chandra Sekar Date: Mon, 6 Apr 2026 15:01:59 -0700 Subject: [PATCH 1/5] SOLR-18055 Improved url scheme detection by prioritizing solr.ssl.enabled over solr.xml and cluster property - Improved ZkStateReader's urlScheme detection by giving higher precedence to "solr.ssl.enabled" over cluster property - Improved HttpShardHandlerFactory's urlScheme detection by giving higher precedence to "solr.ssl.enabled" over explicit configuration (ie., solr.xml) - Deprecated usage of the cluster property for detecting urlScheme in ZkController, ReplicaMutator, SliceMutator, and SystemInfoProvider; these now rely on ClusterStateProvider#getUrlScheme --- .../unreleased/SOLR-18056-urlScheme-csp.yml | 5 +++- solr/benchmark/src/resources/solr.xml | 1 - .../org/apache/solr/cloud/ZkController.java | 7 +---- .../solr/cloud/overseer/ReplicaMutator.java | 8 ++---- .../solr/cloud/overseer/SliceMutator.java | 8 ++---- .../handler/admin/SystemInfoProvider.java | 3 +- .../component/HttpShardHandlerFactory.java | 28 +++++++++++++++---- .../src/test-files/solr/solr-jmxreporter.xml | 1 - .../solr/solr-trackingshardhandler.xml | 1 - solr/core/src/test-files/solr/solr.xml | 1 - .../apache/solr/cloud/LeaderElectionTest.java | 6 ++-- .../solr/cloud/LeaderVoteWaitTimeoutTest.java | 9 +----- .../cloud/TestMiniSolrCloudClusterSSL.java | 19 ++++++------- .../cloud/overseer/ZkStateReaderTest.java | 10 +++++++ .../src/test-files/clustering/solr/solr.xml | 4 --- .../modules/cuvs/src/test-files/solr/solr.xml | 1 - .../src/test-files/solr/solr.xml | 1 - solr/modules/ltr/src/test-files/solr/solr.xml | 1 - .../src/test-files/solr/solr.xml | 1 - .../src/test-files/solrj/solr/solr.xml | 1 - .../solr/common/cloud/ZkStateReader.java | 28 ++++++++++++++++--- .../src/test-files/solrj/solr/shared/solr.xml | 1 - .../solrj/solr/solr-metrics-enabled.xml | 1 - solr/solrj/src/test-files/solrj/solr/solr.xml | 1 - .../solrj/impl/ClusterStateProviderTest.java | 8 +++--- .../java/org/apache/solr/SolrTestCaseJ4.java | 2 +- 26 files changed, 85 insertions(+), 72 deletions(-) diff --git a/changelog/unreleased/SOLR-18056-urlScheme-csp.yml b/changelog/unreleased/SOLR-18056-urlScheme-csp.yml index f7a3d2690b1e..ad1de8f8918e 100644 --- a/changelog/unreleased/SOLR-18056-urlScheme-csp.yml +++ b/changelog/unreleased/SOLR-18056-urlScheme-csp.yml @@ -1,8 +1,11 @@ # See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc -title: Improved CloudSolrClient's urlScheme detection by using the scheme of provided Solr URLs, or looking at "solr.ssl.enabled". +title: Improved CloudSolrClient's urlScheme detection by using the scheme of provided Solr URLs, or looking at "solr.ssl.enabled" and + improved existing url scheme detection in ZkStateReader and HttpShardHandlerFactory by prioritizing solr.ssl.enabled over solr.xml and cluster property type: changed authors: - name: Vishnu Priya Chandra Sekar links: - name: SOLR-18056 url: https://issues.apache.org/jira/browse/SOLR-18056 + - name: SOLR-18055 + url: https://issues.apache.org/jira/browse/SOLR-18055 diff --git a/solr/benchmark/src/resources/solr.xml b/solr/benchmark/src/resources/solr.xml index 38c9a776f53d..9292940b2221 100644 --- a/solr/benchmark/src/resources/solr.xml +++ b/solr/benchmark/src/resources/solr.xml @@ -28,7 +28,6 @@ ${solr.tests.security.allow.urls:} - ${urlScheme:} ${socketTimeout:15000} ${connTimeout:15000} diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index 4b574750ede8..a3702c1f1e31 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -365,13 +365,8 @@ public ZkController( }); zkStateReader.createClusterStateWatchersAndUpdate(); // and reads cluster properties - // note: Can't read cluster properties until createClusterState ^ is called - final String urlSchemeFromClusterProp = - zkStateReader.getClusterProperty(ZkStateReader.URL_SCHEME, ZkStateReader.HTTP); - // this must happen after zkStateReader has initialized the cluster props - this.baseURL = URLUtil.getBaseUrlForNodeName(this.nodeName, urlSchemeFromClusterProp); - + this.baseURL = zkStateReader.getBaseUrlForNodeName(this.nodeName); // Now that zkStateReader is available, read OVERSEER_ENABLED. final boolean overseerEnabled = Boolean.parseBoolean( diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java index 3b06bbe6df87..1536c5176fc8 100644 --- a/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java +++ b/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java @@ -52,6 +52,7 @@ import org.apache.solr.common.params.CollectionAdminParams; import org.apache.solr.common.util.CollectionUtil; import org.apache.solr.common.util.StrUtils; +import org.apache.solr.common.util.URLUtil; import org.apache.solr.common.util.Utils; import org.apache.solr.util.TestInjection; import org.slf4j.Logger; @@ -407,11 +408,8 @@ private ZkWriteCommand updateState( String nodeName = (String) replicaProps.get(ZkStateReader.NODE_NAME_PROP); if (nodeName != null) { String baseUrl = - Utils.getBaseUrlForNodeName( - nodeName, - cloudManager - .getClusterStateProvider() - .getClusterProperty(ZkStateReader.URL_SCHEME, "http")); + URLUtil.getBaseUrlForNodeName( + nodeName, cloudManager.getClusterStateProvider().getUrlScheme()); replicaProps.put(ZkStateReader.BASE_URL_PROP, baseUrl); } Replica replica = new Replica(coreNodeName, replicaProps, collectionName, sliceName); diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java index 962f7ea0b47b..9b72410a1140 100644 --- a/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java +++ b/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java @@ -39,6 +39,7 @@ import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.CollectionAdminParams; +import org.apache.solr.common.util.URLUtil; import org.apache.solr.common.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,11 +89,8 @@ public ZkWriteCommand addReplica(ClusterState clusterState, ZkNodeProps message) } String nodeName = message.getStr(ZkStateReader.NODE_NAME_PROP); String baseUrl = - Utils.getBaseUrlForNodeName( - nodeName, - cloudManager - .getClusterStateProvider() - .getClusterProperty(ZkStateReader.URL_SCHEME, "http")); + URLUtil.getBaseUrlForNodeName( + nodeName, cloudManager.getClusterStateProvider().getUrlScheme()); Map replicaProps = Utils.makeMap( diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java index 03e7df5c4b0e..a82f08629e48 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java @@ -320,8 +320,7 @@ public NodeSystemResponse.Security getSecurityInfo() { } if (cc != null && cc.getZkController() != null) { - String urlScheme = - cc.getZkController().zkStateReader.getClusterProperty(ZkStateReader.URL_SCHEME, "http"); + String urlScheme = cc.getZkController().zkStateReader.getUrlScheme(); info.tls = ZkStateReader.HTTPS.equals(urlScheme); } diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java index fa2392c5a1de..574a0b266a37 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java +++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java @@ -48,6 +48,7 @@ import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.ShardParams; import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.EnvUtils; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.IOUtils; import org.apache.solr.common.util.NamedList; @@ -109,6 +110,9 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory // URL scheme to be used in distributed search. static final String INIT_URL_SCHEME = "urlScheme"; + // system property to enable ssl or tls for communication within Solr + static final String SOLR_SSL_ENABLED = "solr.ssl.enabled"; + // The core size of the threadpool servicing requests static final String INIT_CORE_POOL_SIZE = "corePoolSize"; @@ -227,12 +231,7 @@ private void initReplicaListTransformers(NamedList routingConfig) { public void init(PluginInfo info) { StringBuilder sb = new StringBuilder(); NamedList args = info.initArgs; - // note: the sys prop is only used in testing - this.scheme = getParameter(args, INIT_URL_SCHEME, System.getProperty(INIT_URL_SCHEME), sb); - if (this.scheme != null && this.scheme.endsWith("://")) { - this.scheme = this.scheme.replace("://", ""); - } - + this.scheme = initUrlScheme(args, sb); String strategy = getParameter( args, "metricNameStrategy", UpdateShardHandlerConfig.DEFAULT_METRICNAMESTRATEGY, sb); @@ -436,6 +435,23 @@ private String buildUrl(String url) { return url; } + /** + * Get url scheme of host + * + * @return http or https or null + */ + private String initUrlScheme(NamedList args, StringBuilder sb) { + final Boolean isSolrSslEnabled = EnvUtils.getPropertyAsBool(SOLR_SSL_ENABLED, null); + if (isSolrSslEnabled != null) { + return isSolrSslEnabled ? "https" : "http"; + } + String urlScheme = getParameter(args, INIT_URL_SCHEME, System.getProperty(INIT_URL_SCHEME), sb); + if (urlScheme != null && urlScheme.endsWith("://")) { + urlScheme = urlScheme.replace("://", ""); + } + return urlScheme; + } + @Override public void initializeMetrics(SolrMetricsContext parentContext, Attributes attributes) { solrMetricsContext = parentContext.getChildContext(this); diff --git a/solr/core/src/test-files/solr/solr-jmxreporter.xml b/solr/core/src/test-files/solr/solr-jmxreporter.xml index c5b296994a44..559b2e303487 100644 --- a/solr/core/src/test-files/solr/solr-jmxreporter.xml +++ b/solr/core/src/test-files/solr/solr-jmxreporter.xml @@ -18,7 +18,6 @@ - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/core/src/test-files/solr/solr-trackingshardhandler.xml b/solr/core/src/test-files/solr/solr-trackingshardhandler.xml index a0ff99a60dbe..90efdebde0e6 100644 --- a/solr/core/src/test-files/solr/solr-trackingshardhandler.xml +++ b/solr/core/src/test-files/solr/solr-trackingshardhandler.xml @@ -36,7 +36,6 @@ - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/core/src/test-files/solr/solr.xml b/solr/core/src/test-files/solr/solr.xml index 92e3d7d6bf34..d2210695e772 100644 --- a/solr/core/src/test-files/solr/solr.xml +++ b/solr/core/src/test-files/solr/solr.xml @@ -32,7 +32,6 @@ 4 - ${urlScheme:} ${socketTimeout:15000} ${connTimeout:15000} diff --git a/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java b/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java index 7bac68872a12..e95c1b411116 100644 --- a/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java @@ -16,8 +16,6 @@ */ package org.apache.solr.cloud; -import static org.apache.solr.common.cloud.ZkStateReader.URL_SCHEME; - import java.lang.invoke.MethodHandles; import java.nio.file.Path; import java.util.ArrayList; @@ -233,7 +231,7 @@ public void testBasic() throws Exception { elector, "shard2", "collection1", "dummynode1", props, zkController); elector.setup(context); elector.joinElection(context, false); - String urlScheme = zkStateReader.getClusterProperty(URL_SCHEME, "http"); + String urlScheme = zkStateReader.getUrlScheme(); assertEquals(urlScheme + "://127.0.0.1:80/solr/", getLeaderUrl("collection1", "shard2")); } @@ -259,7 +257,7 @@ public void testCancelElection() throws Exception { Thread.sleep(1000); - String urlScheme = zkStateReader.getClusterProperty(URL_SCHEME, "http"); + String urlScheme = zkStateReader.getUrlScheme(); String url1 = Utils.getBaseUrlForNodeName("127.0.0.1:80_solr", urlScheme) + "/1/"; String url2 = Utils.getBaseUrlForNodeName("127.0.0.1:80_solr", urlScheme) + "/2/"; diff --git a/solr/core/src/test/org/apache/solr/cloud/LeaderVoteWaitTimeoutTest.java b/solr/core/src/test/org/apache/solr/cloud/LeaderVoteWaitTimeoutTest.java index 1c042c6f222e..4deca8cebd5d 100644 --- a/solr/core/src/test/org/apache/solr/cloud/LeaderVoteWaitTimeoutTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/LeaderVoteWaitTimeoutTest.java @@ -17,9 +17,6 @@ package org.apache.solr.cloud; -import static org.apache.solr.common.cloud.ZkStateReader.HTTP; -import static org.apache.solr.common.cloud.ZkStateReader.URL_SCHEME; - import java.io.IOException; import java.lang.invoke.MethodHandles; import java.net.URI; @@ -39,7 +36,6 @@ import org.apache.solr.client.solrj.request.GenericSolrRequest; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.cloud.Replica; -import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.util.NamedList; import org.apache.solr.embedded.JettySolrRunner; import org.apache.solr.util.SocketProxy; @@ -79,10 +75,7 @@ public static void tearDownCluster() { @Before public void setupTest() throws Exception { - configureCluster(NODE_COUNT) - .withProperty(ZkStateReader.URL_SCHEME, System.getProperty(URL_SCHEME, HTTP)) - .addConfig("conf", configset("cloud-minimal")) - .configure(); + configureCluster(NODE_COUNT).addConfig("conf", configset("cloud-minimal")).configure(); // Add proxies proxies = new HashMap<>(cluster.getJettySolrRunners().size()); diff --git a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java index 58b5a175ca8f..85072d26d329 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java @@ -32,7 +32,6 @@ import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest; -import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction; import org.apache.solr.embedded.JettyConfig; import org.apache.solr.embedded.JettySolrRunner; @@ -71,7 +70,7 @@ public class TestMiniSolrCloudClusterSSL extends SolrTestCaseJ4 { } private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - + private static final String SOLR_SSL_ENABLED = "solr.ssl.enabled"; public static final int NUM_SERVERS = 3; public static final String CONF_NAME = MethodHandles.lookup().lookupClass().getName(); @@ -86,14 +85,14 @@ public void before() { "NOTE: This Test ignores the randomized SSL & clientAuth settings selected by base class"); HttpClientUtil.resetHttpClientBuilder(); // also resets SocketFactoryRegistryProvider HttpJettySolrClient.resetSslContextFactory(); - System.clearProperty(ZkStateReader.URL_SCHEME); + System.clearProperty(SOLR_SSL_ENABLED); } @After public void after() { HttpClientUtil.resetHttpClientBuilder(); // also resets SocketFactoryRegistryProvider HttpJettySolrClient.resetSslContextFactory(); - System.clearProperty(ZkStateReader.URL_SCHEME); + System.clearProperty(SOLR_SSL_ENABLED); SSLContext.setDefault(DEFAULT_SSL_CONTEXT); } @@ -102,7 +101,7 @@ public void testNoSsl() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); // must be reset HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); // must be reset - System.setProperty(ZkStateReader.URL_SCHEME, "http"); + System.setProperty(SOLR_SSL_ENABLED, "false"); checkClusterWithNodeReplacement(sslConfig); } @@ -114,7 +113,7 @@ public void testNoSslButSillyClientAuth() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); - System.setProperty(ZkStateReader.URL_SCHEME, "http"); + System.setProperty(SOLR_SSL_ENABLED, "false"); checkClusterWithNodeReplacement(sslConfig); } @@ -123,7 +122,7 @@ public void testSslAndNoClientAuth() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); - System.setProperty(ZkStateReader.URL_SCHEME, "https"); + System.setProperty(SOLR_SSL_ENABLED, "true"); checkClusterWithNodeReplacement(sslConfig); } @@ -135,7 +134,7 @@ public void testSslAndClientAuth() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); - System.setProperty(ZkStateReader.URL_SCHEME, "https"); + System.setProperty(SOLR_SSL_ENABLED, "true"); checkClusterWithNodeReplacement(sslConfig); } @@ -144,7 +143,7 @@ public void testSslWithCheckPeerName() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); - System.setProperty(ZkStateReader.URL_SCHEME, "https"); + System.setProperty(SOLR_SSL_ENABLED, "true"); checkClusterWithNodeReplacement(sslConfig); } @@ -193,7 +192,7 @@ public void testSslWithInvalidPeerName() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); - System.setProperty(ZkStateReader.URL_SCHEME, "https"); + System.setProperty(SOLR_SSL_ENABLED, "true"); final JettyConfig config = JettyConfig.builder().withSSLConfig(sslConfig.buildServerSSLConfig()).build(); final MiniSolrCloudCluster cluster = diff --git a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java index 3e7e575ca441..8d1df5c0843b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java @@ -995,4 +995,14 @@ public void testFetchLowestSolrVersion_noLiveNodes() throws Exception { var lowestVersion = reader.fetchLowestSolrVersion(); assertFalse("Expected no lowest version when no live nodes exist", lowestVersion.isPresent()); } + + public void testGetUrlScheme_validSystemProperty() { + String expectedUrlScheme = isSSLMode() ? "https" : "http"; + assertEquals(expectedUrlScheme, fixture.reader.getUrlScheme()); + } + + public void testGetUrlScheme_noClusterAndSystemProperty() { + assumeFalse("Skip the test when ssl is enabled", isSSLMode()); + assertEquals("http", fixture.reader.getUrlScheme()); + } } diff --git a/solr/modules/clustering/src/test-files/clustering/solr/solr.xml b/solr/modules/clustering/src/test-files/clustering/solr/solr.xml index 3596eebbdafc..7370666792b9 100644 --- a/solr/modules/clustering/src/test-files/clustering/solr/solr.xml +++ b/solr/modules/clustering/src/test-files/clustering/solr/solr.xml @@ -25,8 +25,4 @@ cores/ - - ${urlScheme:} - - diff --git a/solr/modules/cuvs/src/test-files/solr/solr.xml b/solr/modules/cuvs/src/test-files/solr/solr.xml index 26d92c24f4cc..6a7a1ff36c24 100644 --- a/solr/modules/cuvs/src/test-files/solr/solr.xml +++ b/solr/modules/cuvs/src/test-files/solr/solr.xml @@ -23,7 +23,6 @@ ${coreRootDirectory:.} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/modules/language-models/src/test-files/solr/solr.xml b/solr/modules/language-models/src/test-files/solr/solr.xml index c201efd50d93..bea3624ec6f8 100644 --- a/solr/modules/language-models/src/test-files/solr/solr.xml +++ b/solr/modules/language-models/src/test-files/solr/solr.xml @@ -23,7 +23,6 @@ ${coreRootDirectory:.} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/modules/ltr/src/test-files/solr/solr.xml b/solr/modules/ltr/src/test-files/solr/solr.xml index c201efd50d93..bea3624ec6f8 100644 --- a/solr/modules/ltr/src/test-files/solr/solr.xml +++ b/solr/modules/ltr/src/test-files/solr/solr.xml @@ -23,7 +23,6 @@ ${coreRootDirectory:.} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/modules/opentelemetry/src/test-files/solr/solr.xml b/solr/modules/opentelemetry/src/test-files/solr/solr.xml index 1f5192084961..42f330816fdd 100644 --- a/solr/modules/opentelemetry/src/test-files/solr/solr.xml +++ b/solr/modules/opentelemetry/src/test-files/solr/solr.xml @@ -29,7 +29,6 @@ ${solr.tests.security.allow.urls:} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/solrj-streaming/src/test-files/solrj/solr/solr.xml b/solr/solrj-streaming/src/test-files/solrj/solr/solr.xml index 3e578e6cfddf..cd24ddbc2005 100644 --- a/solr/solrj-streaming/src/test-files/solrj/solr/solr.xml +++ b/solr/solrj-streaming/src/test-files/solrj/solr/solr.xml @@ -28,7 +28,6 @@ ${solr.tests.security.allow.urls:} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java index 2b5a46951299..ccdbbd65785b 100644 --- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java +++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java @@ -56,8 +56,10 @@ import org.apache.solr.common.params.CollectionAdminParams; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.util.CommonTestInjection; +import org.apache.solr.common.util.EnvUtils; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.ObjectReleaseTracker; +import org.apache.solr.common.util.URLUtil; import org.apache.solr.common.util.Utils; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.KeeperException.NoNodeException; @@ -1228,8 +1230,7 @@ public ConfigData getSecurityProps(boolean getFresh) { * @return url that looks like {@code https://localhost:8983/solr} */ public String getBaseUrlForNodeName(final String nodeName) { - String urlScheme = getClusterProperty(URL_SCHEME, "http"); - return Utils.getBaseUrlForNodeName(nodeName, urlScheme, false); + return URLUtil.getBaseUrlForNodeName(nodeName, getUrlScheme(), false); } /** @@ -1240,8 +1241,27 @@ public String getBaseUrlForNodeName(final String nodeName) { * @return url that looks like {@code https://localhost:8983/api} */ public String getBaseUrlV2ForNodeName(final String nodeName) { - String urlScheme = getClusterProperty(URL_SCHEME, "http"); - return Utils.getBaseUrlForNodeName(nodeName, urlScheme, true); + return URLUtil.getBaseUrlForNodeName(nodeName, getUrlScheme(), true); + } + + /** + * Returns the URL scheme for the host. + * + *

Examples: + * + *

+ * + * @return the URL scheme ("http" or "https") + */ + public String getUrlScheme() { + final Boolean isSolrSslEnabled = EnvUtils.getPropertyAsBool("solr.ssl.enabled"); + if (isSolrSslEnabled != null) { + return isSolrSslEnabled ? "https" : "http"; + } + return getClusterProperty(URL_SCHEME, "http"); } /** Watches a single collection's state.json. */ diff --git a/solr/solrj/src/test-files/solrj/solr/shared/solr.xml b/solr/solrj/src/test-files/solrj/solr/shared/solr.xml index 7f48a511a6f0..08d3596ec35c 100644 --- a/solr/solrj/src/test-files/solrj/solr/shared/solr.xml +++ b/solr/solrj/src/test-files/solrj/solr/shared/solr.xml @@ -23,7 +23,6 @@ ${coreRootDirectory:.} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/solrj/src/test-files/solrj/solr/solr-metrics-enabled.xml b/solr/solrj/src/test-files/solrj/solr/solr-metrics-enabled.xml index a48c29f7e278..e2e4fc7c10d3 100644 --- a/solr/solrj/src/test-files/solrj/solr/solr-metrics-enabled.xml +++ b/solr/solrj/src/test-files/solrj/solr/solr-metrics-enabled.xml @@ -30,7 +30,6 @@ ${solr.tests.security.allow.urls:} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/solrj/src/test-files/solrj/solr/solr.xml b/solr/solrj/src/test-files/solrj/solr/solr.xml index 6957862f4d9f..f9ec9e5ec968 100644 --- a/solr/solrj/src/test-files/solrj/solr/solr.xml +++ b/solr/solrj/src/test-files/solrj/solr/solr.xml @@ -28,7 +28,6 @@ ${solr.tests.security.allow.urls:} - ${urlScheme:} ${socketTimeout:90000} ${connTimeout:15000} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java index 175264ede478..63f3ab56657e 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java @@ -472,6 +472,7 @@ public void testZkClusterStateProviderUrlScheme() throws Exception { } private void testUrlSchemeDefault(SolrZkClient client) throws Exception { + assumeFalse("Skip the test when ssl is enabled", isSSLMode()); try (var zkStateReader = new ZkStateReader(client); var clusterStateProvider = new ZkClientClusterStateProvider(zkStateReader)) { assertEquals("http", clusterStateProvider.getUrlScheme()); @@ -479,16 +480,15 @@ private void testUrlSchemeDefault(SolrZkClient client) throws Exception { } private void testUrlSchemeWithSystemProperties(SolrZkClient client) throws Exception { - System.setProperty(SOLR_SSL_ENABLED, "true"); try (var zkStateReader = new ZkStateReader(client); var clusterStateProvider = new ZkClientClusterStateProvider(zkStateReader)) { - assertEquals("https", clusterStateProvider.getUrlScheme()); - } finally { - System.clearProperty(SOLR_SSL_ENABLED); + String expectedUrlScheme = isSSLMode() ? "https" : "http"; + assertEquals(expectedUrlScheme, clusterStateProvider.getUrlScheme()); } } private void testUrlSchemeWithClusterProperties(SolrZkClient client) throws Exception { + assumeFalse("Skip the test when ssl is enabled", isSSLMode()); ClusterProperties cp = new ClusterProperties(client); cp.setClusterProperty("urlScheme", "ftp"); try (var zkStateReader = new ZkStateReader(client); diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java index ca7677a7e787..e8ab25676774 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java @@ -287,7 +287,7 @@ public static void setupTestCases() { HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); if (isSSLMode()) { // SolrCloud tests should usually clear this - System.setProperty("urlScheme", "https"); + System.setProperty("solr.ssl.enabled", "true"); } ExecutorUtil.resetThreadLocalProviders(); From 699423cce2656f3455aa4032224aacec49d3a498 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Fri, 24 Apr 2026 22:12:33 -0400 Subject: [PATCH 2/5] remove verbose javadocs --- .../java/org/apache/solr/common/cloud/ZkStateReader.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java index ccdbbd65785b..5cf8100ec331 100644 --- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java +++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java @@ -1245,14 +1245,7 @@ public String getBaseUrlV2ForNodeName(final String nodeName) { } /** - * Returns the URL scheme for the host. - * - *

Examples: - * - *

    - *
  • Returns {@code "https"} when SSL is enabled via configuration. - *
  • Returns {@code "http"} when no explicit configuration is provided. - *
+ * Returns the URL scheme for hosts in the cluster. * * @return the URL scheme ("http" or "https") */ From 3d10e22eeca7b225ba4eb7705fdb980fc2da7f17 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Fri, 24 Apr 2026 22:46:07 -0400 Subject: [PATCH 3/5] SOLR_SSL_ENABLED now propagages to solr.ssl.enabled --- solr/solrj/src/resources/EnvToSyspropMappings.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/solr/solrj/src/resources/EnvToSyspropMappings.properties b/solr/solrj/src/resources/EnvToSyspropMappings.properties index 7571f2968d30..ed6e742cebcc 100644 --- a/solr/solrj/src/resources/EnvToSyspropMappings.properties +++ b/solr/solrj/src/resources/EnvToSyspropMappings.properties @@ -71,7 +71,6 @@ SOLR_SSL_CLIENT_KEY_STORE_TYPE= SOLR_SSL_CLIENT_TRUST_STORE= SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD= SOLR_SSL_CLIENT_TRUST_STORE_TYPE= -SOLR_SSL_ENABLED= SOLR_SSL_KEY_STORE= SOLR_SSL_KEY_STORE_PASSWORD= SOLR_SSL_KEY_STORE_TYPE= From b4dbc3f66f806751a655034f44aa869e100dd91d Mon Sep 17 00:00:00 2001 From: David Smiley Date: Fri, 24 Apr 2026 23:12:18 -0400 Subject: [PATCH 4/5] ref guide --- .../pages/configuring-solr-xml.adoc | 3 +- .../deployment-guide/pages/enabling-ssl.adoc | 59 +------------------ .../pages/major-changes-in-solr-10.adoc | 4 ++ 3 files changed, 9 insertions(+), 57 deletions(-) diff --git a/solr/solr-ref-guide/modules/configuration-guide/pages/configuring-solr-xml.adoc b/solr/solr-ref-guide/modules/configuration-guide/pages/configuring-solr-xml.adoc index 2aed51b89e31..66e6d21dc7ac 100644 --- a/solr/solr-ref-guide/modules/configuration-guide/pages/configuring-solr-xml.adoc +++ b/solr/solr-ref-guide/modules/configuration-guide/pages/configuring-solr-xml.adoc @@ -552,7 +552,8 @@ Defaults to the `distribUpdateConnTimeout` specified in the `` sectio |Optional |Default: none |=== + -The URL scheme to be used in distributed search. +The URL scheme to be used in distributed search and other inter-node communication. +Note: this is obsoleted by the `solr.ssl.enabled` boolean system property. `maxConnectionsPerHost`:: + diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc index dd8998b8e19a..902af2e19c78 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc @@ -62,10 +62,10 @@ If you want to use curl on OS X Yosemite (10.10), you'll need to create a certif $ openssl pkcs12 -nokeys -in solr-ssl.keystore.p12 -out solr-ssl.cacert.pem ---- -=== Set Common SSL-Related System Properties +=== Set Common SSL-Related Environment Variables -The Solr Control Script is already setup to pass SSL-related Java system properties to the JVM. -To activate the SSL settings, uncomment and update the set of properties beginning with `SOLR_SSL_*` in `bin/solr.in.sh` on *nix systems or `bin\solr.in.cmd` on Windows. +The Solr Control Script is already setup to pass SSL-related environment variables. +To activate the SSL settings, uncomment and update the set of variables beginning with `SOLR_SSL_*` in `bin/solr.in.sh` on *nix systems or `bin\solr.in.cmd` on Windows. [tabs#solr-in] ====== @@ -132,59 +132,6 @@ They are mutually exclusive and Jetty will select one of them which may not be w When you start Solr, the `bin/solr` script includes these settings and will pass them as system properties to the JVM. -If you are using SolrCloud, you need to <> before starting Solr. - -If you are running Solr in a user-managed cluster or single-node installation, you can skip to <>. - -=== Configure ZooKeeper - -After creating the keystore described above and before you start any SolrCloud nodes, you must configure your Solr cluster properties in ZooKeeper so that Solr nodes know to communicate via SSL. - -This section assumes you have created and started an external ZooKeeper. -See xref:zookeeper-ensemble.adoc[] for more information. - -The `urlScheme` cluster-wide property needs to be set to `https` before any Solr node starts up. -The examples below use the `bin/solr` tool that comes with Solr to do this. - -[tabs#zkclusterprops] -====== -*nix:: -+ -==== -[source,terminal] ----- -$ bin/solr cluster --property urlScheme --value https --zk-host server1:2181,server2:2181,server3:2181 ----- -==== - -Windows:: -+ -==== -[source,powershell] ----- -C:\> bin/solr.cmd cluster --property urlScheme --value https --zk-host server1:2181,server2:2181,server3:2181 ----- -==== -====== - -Be sure to use the correct `--zk-host` value for your system. -If you have set up your ZooKeeper ensemble to use a xref:taking-solr-to-production.adoc#zookeeper-chroot[chroot for Solr], make sure to include it in the `zkHost` string, e.g., `--zk-host server1:2181,server2:2181,server3:2181/solr`. - -=== Update Cluster Properties for Existing Collections - -If you are using SolrCloud and have collections created before enabling SSL, you will need to update the cluster properties to use HTTPS. - -If you do not have existing collections or are not using SolrCloud, you can skip ahead and start Solr. - -Updating cluster properties can be done with the Collections API xref:cluster-node-management.adoc#clusterprop[CLUSTERPROP command], as in this example (update the hostname and port as appropriate for your system): - -[source,terminal] -$ http://localhost:8983/solr/admin/collections?action=CLUSTERPROP&name=urlScheme&val=https - -This command only needs to be run on one node of the cluster, the change will apply to all nodes. - -Once this and all other steps are complete, you can go ahead and start Solr. - == Starting Solr After Enabling SSL === Start SolrCloud diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc index 4954860be117..fb748bf116d3 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc @@ -36,6 +36,10 @@ Solr 10.0 requires at least Java 21, while SolrJ 10.0 requires at least Java 17. == Solr 10.1 +For SSL (https), it's no longer necessary to set the "urlScheme" cluster property since the `SOLR_SSL_ENABLED` env var (or `solr.ssl.enabled` sys-prop) suffices. +These are now honored by CloudSolrClient, as well as scheme detection from the connection string / hosts. +The "urlScheme" cluster property and httpShardHandlerFactory configuration is likely to be deprecated; feedback welcome. + === v2 API Starting in Solr 10.1 it is no longer possible for users to disable the v2 API by use of the `solr.api.v2.enabled` system property, and the Solr server and tooling (`bin/solr`, Admin UI, etc.) will start using these APIs internally. From 8c661405ec62534ee94f4edb5d198d3e41e80555 Mon Sep 17 00:00:00 2001 From: Vishnu Priya <9874772+VishnuPriyaChandraSekar@users.noreply.github.com> Date: Thu, 30 Apr 2026 09:39:51 -0700 Subject: [PATCH 5/5] Update SOLR-18056-urlScheme-csp.yml Updated the title based on the comment from the reviewer --- changelog/unreleased/SOLR-18056-urlScheme-csp.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelog/unreleased/SOLR-18056-urlScheme-csp.yml b/changelog/unreleased/SOLR-18056-urlScheme-csp.yml index ad1de8f8918e..12691974908c 100644 --- a/changelog/unreleased/SOLR-18056-urlScheme-csp.yml +++ b/changelog/unreleased/SOLR-18056-urlScheme-csp.yml @@ -1,6 +1,5 @@ # See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc -title: Improved CloudSolrClient's urlScheme detection by using the scheme of provided Solr URLs, or looking at "solr.ssl.enabled" and - improved existing url scheme detection in ZkStateReader and HttpShardHandlerFactory by prioritizing solr.ssl.enabled over solr.xml and cluster property +title: Improved CloudSolrClient's http/https (SSL) detection by using the scheme of provided Solr URLs, or looking at the "solr.ssl.enabled" system property. Likewise improved Solr itself to consider this property as an alternative to the urlScheme cluster property. type: changed authors: - name: Vishnu Priya Chandra Sekar