Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/unreleased/SOLR-17697-picocli-experimental-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ links:
url: https://issues.apache.org/jira/browse/SOLR-17697
- name: SOLR-18510
url: https://issues.apache.org/jira/browse/SOLR-18510
- name: SOLR-18509
url: https://issues.apache.org/jira/browse/SOLR-18509
34 changes: 33 additions & 1 deletion solr/core/src/java/org/apache/solr/cli/ApiTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,22 @@
*
* <p>Used to send an arbitrary HTTP request to a Solr API endpoint.
*/
@SuppressWarnings("UnnecessarilyFullyQualified")
@picocli.CommandLine.Command(
name = "api",
description = "Used to send an arbitrary HTTP GET request to a Solr API endpoint.",
footerHeading = "%nExamples:%n",
footer = {
" # Send a GET request to a Solr API endpoint",
" bin/solr api -s http://localhost:8983/api/collections"
})
public class ApiTool extends ToolBase {

/**
* @deprecated Only used by the commons-cli parser; the picocli path declares this as an annotated
* field.
*/
@Deprecated
private static final Option SOLR_URL_OPTION =
Option.builder("s")
.longOpt("solr-url")
Expand All @@ -45,6 +59,22 @@ public class ApiTool extends ToolBase {
/** Parameters for the api command, independent of the command line parser. */
record ApiParams(String getUrl, String credentials) {}

// --- picocli fields ---

@picocli.CommandLine.Option(
names = {"-s", "--solr-url"},
required = true,
paramLabel = "URL",
description =
"Full URL of the Solr API endpoint to GET, e.g. http://localhost:8983/api/collections")
private String solrUrlOpt;

@picocli.CommandLine.Mixin private CredentialsOptions credentialsOptions;

public ApiTool() {
this(new DefaultToolRuntime());
}

public ApiTool(ToolRuntime runtime) {
super(runtime);
}
Expand Down Expand Up @@ -124,6 +154,8 @@ public static ModifiableSolrParams getSolrParamsFromUri(URI uri) {

@Override
public int callTool() throws Exception {
throw new UnsupportedOperationException("This tool does not yet support PicoCli");
ApiParams params = new ApiParams(solrUrlOpt, credentialsOptions.credentials);
callApi(params);
return 0;
}
}
3 changes: 2 additions & 1 deletion solr/core/src/java/org/apache/solr/cli/SolrCLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
AuthTool.class,
CreateTool.class,
DeleteTool.class,
AssertTool.class
AssertTool.class,
ApiTool.class
})
public class SolrCLI implements CLIO, java.util.concurrent.Callable<Integer> {

Expand Down
39 changes: 39 additions & 0 deletions solr/core/src/test/org/apache/solr/cli/ApiToolPicocliTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.solr.cli;

import java.util.Arrays;
import picocli.CommandLine;

/**
* Runs all {@link ApiToolTest} tests through the picocli invocation path.
*
* <p>All {@code @Test} methods are inherited; only the invocation strategy is overridden.
*/
public class ApiToolPicocliTest extends ApiToolTest {

@Override
protected int runTool(String[] args, Class<? extends ToolBase> clazz) throws Exception {
// args[0] is the tool name used by commons-cli dispatch; strip it for picocli.
String[] toolArgs = Arrays.copyOfRange(args, 1, args.length);
ToolRuntime runtime = new CLITestHelper.TestingRuntime(false);
ToolBase tool = clazz.getDeclaredConstructor(ToolRuntime.class).newInstance(runtime);
return new CommandLine(tool)
.setDefaultValueProvider(new CliDefaultValueProvider())
.execute(toolArgs);
}
}
19 changes: 19 additions & 0 deletions solr/core/src/test/org/apache/solr/cli/ApiToolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
public class ApiToolTest extends SolrCloudTestCase {
static String COLLECTION_NAME = "globalLoaderColl";

/** Runs the tool. Overridden by the picocli variant of this test. */
protected int runTool(String[] args, Class<? extends ToolBase> clazz) throws Exception {
return CLITestHelper.runTool(args, clazz);
}

@BeforeClass
public static void setupCluster() throws Exception {
configureCluster(1)
Expand All @@ -40,6 +45,20 @@ public static void setupCluster() throws Exception {
.configure();
}

@Test
public void testApiCommandSucceedsOnAnOkResponse() throws Exception {
String url = cluster.getJettySolrRunner(0).getBaseUrl() + "/admin/info/system";

assertEquals(0, runTool(new String[] {"api", "-s", url}, ApiTool.class));
}

@Test
public void testApiCommandFailsOnANon2xxResponse() throws Exception {
String url = cluster.getJettySolrRunner(0).getBaseUrl() + "/admin/no-such-handler";

assertEquals(1, runTool(new String[] {"api", "-s", url}, ApiTool.class));
}

@Test
public void testParsingGetUrl() throws URISyntaxException {

Expand Down
2 changes: 2 additions & 0 deletions solr/packaging/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ task integrationTestsPicocli(type: BatsTask) {
'test/test_delete_collection.bats',
'test/test_zk.bats',
'test/test_auth.bats',
'test/test_modules.bats',
'test/test_security_manager.bats',
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* xref:solr-control-script-reference.adoc[]
** xref:cli/index.adoc[Experimental picocli CLI]
// CLI-DOCS-START
*** xref:cli/solr-api.adoc[api]
*** xref:cli/solr-assert.adoc[assert]
*** xref:cli/solr-auth.adoc[auth]
*** xref:cli/solr-create.adoc[create]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Any command not listed here is unavailable when the picocli implementation is en
|===
|Command

|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-create.adoc[bin/solr create]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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 api
: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 api [-hv] -s=URL [-u=<credentials>]
....

// end::picocli-generated-man-section-synopsis[]

// tag::picocli-generated-man-section-description[]
== Description

Used to send an arbitrary HTTP GET request to a Solr API endpoint.

// end::picocli-generated-man-section-description[]

// tag::picocli-generated-man-section-options[]
== Options

*-h*, *--help*::
Print this help message and exit.

*-s*, *--solr-url*=_URL_::
*(required)* Full URL of the Solr API endpoint to GET, e.g. http://localhost:8983/api/collections

*-u*, *--credentials*=_<credentials>_::
Credentials in the format username:password. Example: --credentials solr:SolrRocks

*-v*, *--verbose*::
Enable verbose mode.

// end::picocli-generated-man-section-options[]

// tag::picocli-generated-man-section-footer[]
== Examples
[%hardbreaks]
# Send a GET request to a Solr API endpoint
bin/solr api -s http://localhost:8983/api/collections

// end::picocli-generated-man-section-footer[]
Loading