This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit f0367c7721f2021afb5864e285632979603c05e2 Author: Serhiy Bzhezytskyy <[email protected]> AuthorDate: Thu Oct 8 18:31:17 2026 +0300 SOLR-18511: Port ClusterTool to picocli (#5038) Co-authored-by: Jan Høydahl <[email protected]> (cherry picked from commit 4ae645ef0e1a5d0249eb859e98188341ec63f0bc) --- .../SOLR-17697-picocli-experimental-cli.yml | 2 + .../src/java/org/apache/solr/cli/ClusterTool.java | 44 ++++++++++- .../core/src/java/org/apache/solr/cli/SolrCLI.java | 3 +- .../apache/solr/cli/ZkSubcommandsPicocliTest.java | 14 ++++ .../org/apache/solr/cli/ZkSubcommandsTest.java | 20 ++++- .../modules/deployment-guide/deployment-nav.adoc | 1 + .../modules/deployment-guide/pages/cli/index.adoc | 1 + .../deployment-guide/pages/cli/solr-cluster.adoc | 85 ++++++++++++++++++++++ 8 files changed, 164 insertions(+), 6 deletions(-) diff --git a/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml b/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml index 410b7c408a5..b554c9600fb 100644 --- a/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml +++ b/changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml @@ -15,3 +15,5 @@ links: url: https://issues.apache.org/jira/browse/SOLR-18510 - name: SOLR-18509 url: https://issues.apache.org/jira/browse/SOLR-18509 + - name: SOLR-18511 + url: https://issues.apache.org/jira/browse/SOLR-18511 diff --git a/solr/core/src/java/org/apache/solr/cli/ClusterTool.java b/solr/core/src/java/org/apache/solr/cli/ClusterTool.java index ce43eff54f1..baf98380fca 100644 --- a/solr/core/src/java/org/apache/solr/cli/ClusterTool.java +++ b/solr/core/src/java/org/apache/solr/cli/ClusterTool.java @@ -32,9 +32,23 @@ import org.apache.solr.common.cloud.SolrZkClient; * * <p>Set cluster properties by directly manipulating ZooKeeper. */ +@SuppressWarnings("UnnecessarilyFullyQualified") [email protected]( + name = "cluster", + description = "Set cluster properties by directly manipulating ZooKeeper.", + footerHeading = "%nExamples:%n", + footer = { + " # Set the urlScheme cluster property", + " bin/solr cluster --property urlScheme --value https" + }) public class ClusterTool extends ToolBase { // It is a shame this tool doesn't more closely mimic how the ConfigTool works. + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option PROPERTY_OPTION = Option.builder() .longOpt("property") @@ -44,6 +58,11 @@ public class ClusterTool extends ToolBase { .desc("Name of the Cluster property to apply the action to, such as: 'urlScheme'.") .get(); + /** + * @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated + * field. + */ + @Deprecated private static final Option VALUE_OPTION = Option.builder() .longOpt("value") @@ -55,6 +74,27 @@ public class ClusterTool extends ToolBase { /** Parameters for the cluster command, independent of the command line parser. */ record ClusterParams(String propertyName, String propertyValue, String zkHost) {} + // --- picocli fields --- + + @picocli.CommandLine.Option( + names = "--property", + required = true, + paramLabel = "PROPERTY", + description = "Name of the Cluster property to apply the action to, such as: 'urlScheme'.") + private String propertyOpt; + + @picocli.CommandLine.Option( + names = "--value", + paramLabel = "VALUE", + description = "Set the property to this value.") + private String valueOpt; + + @picocli.CommandLine.Mixin private ZkConnectionOptions zkOpts; + + public ClusterTool() { + this(new DefaultToolRuntime()); + } + public ClusterTool(ToolRuntime runtime) { super(runtime); } @@ -111,6 +151,8 @@ public class ClusterTool extends ToolBase { @Override public int callTool() throws Exception { - throw new UnsupportedOperationException("This tool does not yet support PicoCli"); + ClusterParams params = new ClusterParams(propertyOpt, valueOpt, zkOpts.resolveZkHost()); + setClusterProperty(params); + return 0; } } diff --git a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java index cc14b1569c0..978d3681cf6 100755 --- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java +++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java @@ -83,7 +83,8 @@ import org.slf4j.LoggerFactory; CreateTool.class, DeleteTool.class, AssertTool.class, - ApiTool.class + ApiTool.class, + ClusterTool.class }) public class SolrCLI implements CLIO, java.util.concurrent.Callable<Integer> { diff --git a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsPicocliTest.java b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsPicocliTest.java index 9b631013cd5..72279717ea9 100644 --- a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsPicocliTest.java +++ b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsPicocliTest.java @@ -17,6 +17,8 @@ package org.apache.solr.cli; import java.util.Arrays; +import org.apache.solr.common.cloud.ClusterProperties; +import org.junit.Test; import picocli.CommandLine; /** @@ -48,4 +50,16 @@ public class ZkSubcommandsPicocliTest extends ZkSubcommandsTest { .setDefaultValueProvider(new CliDefaultValueProvider()) .execute(toolArgs); } + + @Test + public void testSetClusterPropertyWithSolrConnection() throws Exception { + // picocli only: the picocli tool takes the shared connection options, commons-cli has -z alone + ClusterProperties properties = new ClusterProperties(zkClient); + String[] args = + new String[] { + "cluster", "--property", "urlScheme", "--value", "https", "-s", zkServer.getZkAddress() + }; + assertEquals(0, runTool(args, ClusterTool.class)); + assertEquals("https", properties.getClusterProperty("urlScheme", "none")); + } } diff --git a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java index 4aebf94ee76..80d02217a89 100644 --- a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java +++ b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java @@ -59,7 +59,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 { protected ZkTestServer zkServer; - private SolrZkClient zkClient; + SolrZkClient zkClient; protected static final Path SOLR_HOME = SolrTestCaseJ4.TEST_HOME(); @@ -590,22 +590,34 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 { @Test public void testSetClusterProperty() throws Exception { - // ClusterTool is not a picocli ZK subcommand; always use the commons-cli path. ClusterProperties properties = new ClusterProperties(zkClient); // add property urlScheme=http String[] args = new String[] { "cluster", "--property", "urlScheme", "--value", "http", "-z", zkServer.getZkAddress() }; - assertEquals(0, CLITestHelper.runTool(args, ClusterTool.class)); + assertEquals(0, runTool(args, ClusterTool.class)); assertEquals("http", properties.getClusterProperty("urlScheme", "none")); args = new String[] {"cluster", "--property", "urlScheme", "-z", zkServer.getZkAddress()}; - assertEquals(0, CLITestHelper.runTool(args, ClusterTool.class)); + assertEquals(0, runTool(args, ClusterTool.class)); assertNull(properties.getClusterProperty("urlScheme", (String) null)); } + @Test + public void testSetClusterPropertyUsesZkHostProperty() throws Exception { + ClusterProperties properties = new ClusterProperties(zkClient); + System.setProperty("zkHost", zkServer.getZkAddress()); + try { + String[] args = new String[] {"cluster", "--property", "urlScheme", "--value", "https"}; + assertEquals(0, runTool(args, ClusterTool.class)); + } finally { + System.clearProperty("zkHost"); + } + assertEquals("https", properties.getClusterProperty("urlScheme", "none")); + } + @Test public void testUpdateAcls() throws Exception { diff --git a/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc b/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc index a5c2d787e0b..0d6de3d1693 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/deployment-nav.adoc @@ -23,6 +23,7 @@ *** xref:cli/solr-api.adoc[api] *** xref:cli/solr-assert.adoc[assert] *** xref:cli/solr-auth.adoc[auth] +*** xref:cli/solr-cluster.adoc[cluster] *** xref:cli/solr-create.adoc[create] *** xref:cli/solr-delete.adoc[delete] *** xref:cli/solr-start.adoc[start] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc index ed3b6ccda34..cc5d9215739 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/index.adoc @@ -62,6 +62,7 @@ Any command not listed here is unavailable when the picocli implementation is en |xref:cli/solr-api.adoc[bin/solr api] |xref:cli/solr-assert.adoc[bin/solr assert] |xref:cli/solr-auth.adoc[bin/solr auth] +|xref:cli/solr-cluster.adoc[bin/solr cluster] |xref:cli/solr-create.adoc[bin/solr create] |xref:cli/solr-delete.adoc[bin/solr delete] |xref:cli/solr-start.adoc[bin/solr start] diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-cluster.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-cluster.adoc new file mode 100644 index 00000000000..cd4c7ee8792 --- /dev/null +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/cli/solr-cluster.adoc @@ -0,0 +1,85 @@ +// 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. +// +// DO NOT EDIT -- this page is auto-generated from picocli annotations. +// To update: modify the @Command/@Option annotations in the Java source, then run: +// ./gradlew :solr:solr-ref-guide:generateCliDocs + += bin/solr cluster +:page-toclevels: 2 + +[WARNING] +==== +This page documents the *experimental* picocli implementation of `bin/solr`, which is not enabled by default. +For what `bin/solr` does by default, see xref:solr-control-script-reference.adoc[]. +See xref:cli/index.adoc[] to enable this implementation and for its known limitations. +==== + +// tag::picocli-generated-man-section-synopsis[] +== Synopsis + +.... +bin/solr cluster [-hv] --property=PROPERTY [-s=<solrConnection>] + [--solr-url=<solrUrl>] [-u=<credentials>] [--value=VALUE] + [-z=<zkHost>] +.... + +// end::picocli-generated-man-section-synopsis[] + +// tag::picocli-generated-man-section-description[] +== Description + +Set cluster properties by directly manipulating ZooKeeper. + +// end::picocli-generated-man-section-description[] + +// tag::picocli-generated-man-section-options[] +== Options + +*-h*, *--help*:: + Print this help message and exit. + +*--property*=_PROPERTY_:: + *(required)* Name of the Cluster property to apply the action to, such as: 'urlScheme'. + +*-s*, *--solr-connection*=_<solrConnection>_:: + Zookeeper or HTTP(s) connection string; unnecessary if SOLR_CONNECTION is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +*--solr-url*=_<solrUrl>_:: + Base Solr URL, which can be used to determine the zk-host if --zk-host is not known + +*-u*, *--credentials*=_<credentials>_:: + Credentials in the format username:password. Example: --credentials solr:SolrRocks + +*-v*, *--verbose*:: + Enable verbose mode. + +*--value*=_VALUE_:: + Set the property to this value. + +*-z*, *--zk-host*=_<zkHost>_:: + Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to localhost:9983. + +// end::picocli-generated-man-section-options[] + +// tag::picocli-generated-man-section-footer[] +== Examples +[%hardbreaks] + # Set the urlScheme cluster property + bin/solr cluster --property urlScheme --value https + +// end::picocli-generated-man-section-footer[]
