This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_10x by this push:
new f85ea39cd1f Update org.apache.solr.cli classes to not use deprecated
methods. (#4142)
f85ea39cd1f is described below
commit f85ea39cd1ff5d91c7e22ebae18b63ff423b64e3
Author: Eric Pugh <[email protected]>
AuthorDate: Thu Feb 26 07:12:58 2026 -0500
Update org.apache.solr.cli classes to not use deprecated methods. (#4142)
Update calls that use deprecated methods, and general review of code
quality. Use more modern java patterns where possible.
(cherry picked from commit c1ac0369f214bc7eb58edcfd6fd1f326f21ca361)
---
.../core/src/java/org/apache/solr/cli/ApiTool.java | 4 +-
.../src/java/org/apache/solr/cli/AssertTool.java | 44 ++--
.../src/java/org/apache/solr/cli/AuthTool.java | 280 +++++++++++----------
.../src/java/org/apache/solr/cli/CLIUtils.java | 13 +-
.../src/java/org/apache/solr/cli/ClusterTool.java | 4 +-
.../java/org/apache/solr/cli/CommonCLIOptions.java | 12 +-
.../org/apache/solr/cli/ConfigSetDownloadTool.java | 4 +-
.../org/apache/solr/cli/ConfigSetUploadTool.java | 4 +-
.../src/java/org/apache/solr/cli/ConfigTool.java | 10 +-
.../src/java/org/apache/solr/cli/CreateTool.java | 41 ++-
.../src/java/org/apache/solr/cli/DeleteTool.java | 16 +-
.../src/java/org/apache/solr/cli/ExportTool.java | 49 ++--
.../java/org/apache/solr/cli/HealthcheckTool.java | 7 +-
.../java/org/apache/solr/cli/LinkConfigTool.java | 4 +-
.../src/java/org/apache/solr/cli/PackageTool.java | 12 +-
.../src/java/org/apache/solr/cli/PostLogsTool.java | 21 +-
.../src/java/org/apache/solr/cli/PostTool.java | 51 ++--
.../java/org/apache/solr/cli/RunExampleTool.java | 192 +++++++-------
.../org/apache/solr/cli/SnapshotCreateTool.java | 4 +-
.../org/apache/solr/cli/SnapshotDeleteTool.java | 4 +-
.../org/apache/solr/cli/SnapshotDescribeTool.java | 4 +-
.../org/apache/solr/cli/SnapshotExportTool.java | 25 +-
.../java/org/apache/solr/cli/SnapshotListTool.java | 2 +-
.../core/src/java/org/apache/solr/cli/SolrCLI.java | 49 +++-
.../org/apache/solr/cli/SolrProcessManager.java | 31 +--
.../src/java/org/apache/solr/cli/StatusTool.java | 13 +-
.../src/java/org/apache/solr/cli/StreamTool.java | 23 +-
.../src/java/org/apache/solr/cli/ZkCpTool.java | 2 +-
.../src/java/org/apache/solr/cli/ZkMkrootTool.java | 2 +-
.../src/java/org/apache/solr/cli/ZkRmTool.java | 2 +-
.../src/java/org/apache/solr/cli/ZkToolHelp.java | 4 +-
.../src/test/org/apache/solr/cli/ApiToolTest.java | 2 +-
.../test/org/apache/solr/cli/CLITestHelper.java | 3 +
.../src/test/org/apache/solr/cli/PostToolTest.java | 26 +-
.../org/apache/solr/cli/SolrCLIZkToolsTest.java | 2 +-
.../apache/solr/cli/SolrProcessManagerTest.java | 31 ++-
.../test/org/apache/solr/cli/StreamToolTest.java | 3 +-
.../test/org/apache/solr/cli/TestExportTool.java | 8 +-
.../org/apache/solr/cli/TestSolrCLIRunExample.java | 42 ++--
.../org/apache/solr/cli/ZkSubcommandsTest.java | 31 +--
40 files changed, 548 insertions(+), 533 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/cli/ApiTool.java
b/solr/core/src/java/org/apache/solr/cli/ApiTool.java
index 9da7d0495a8..4a9c86fb848 100644
--- a/solr/core/src/java/org/apache/solr/cli/ApiTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ApiTool.java
@@ -43,7 +43,7 @@ public class ApiTool extends ToolBase {
.argName("URL")
.required()
.desc("Send a GET request to a Solr API endpoint.")
- .build();
+ .get();
public ApiTool(ToolRuntime runtime) {
super(runtime);
@@ -77,7 +77,7 @@ public class ApiTool extends ToolBase {
try (var solrClient = CLIUtils.getSolrClient(solrUrl, credentials)) {
// For path parameter we need the path without the root so from the
second / char
// (because root can be configured)
- // E.g URL is http://localhost:8983/solr/admin/info/system path is
+ // E.g. URL is http://localhost:8983/solr/admin/info/system path is
// /solr/admin/info/system and the path without root is
/admin/info/system
var req =
new GenericSolrRequest(
diff --git a/solr/core/src/java/org/apache/solr/cli/AssertTool.java
b/solr/core/src/java/org/apache/solr/cli/AssertTool.java
index e0349cbf328..928065f0a79 100644
--- a/solr/core/src/java/org/apache/solr/cli/AssertTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/AssertTool.java
@@ -45,10 +45,10 @@ public class AssertTool extends ToolBase {
private static Long timeoutMs = 1000L;
private static final Option IS_NOT_ROOT_OPTION =
- Option.builder().desc("Asserts that we are NOT the root
user.").longOpt("not-root").build();
+ Option.builder().desc("Asserts that we are NOT the root
user.").longOpt("not-root").get();
private static final Option IS_ROOT_OPTION =
- Option.builder().desc("Asserts that we are the root
user.").longOpt("root").build();
+ Option.builder().desc("Asserts that we are the root
user.").longOpt("root").get();
private static final OptionGroup ROOT_OPTION =
new
OptionGroup().addOption(IS_NOT_ROOT_OPTION).addOption(IS_ROOT_OPTION);
@@ -59,7 +59,7 @@ public class AssertTool extends ToolBase {
.longOpt("not-started")
.hasArg()
.argName("url")
- .build();
+ .get();
private static final Option IS_RUNNING_ON_OPTION =
Option.builder()
@@ -67,7 +67,7 @@ public class AssertTool extends ToolBase {
.longOpt("started")
.hasArg()
.argName("url")
- .build();
+ .get();
private static final OptionGroup RUNNING_OPTION =
new
OptionGroup().addOption(IS_NOT_RUNNING_ON_OPTION).addOption(IS_RUNNING_ON_OPTION);
@@ -78,7 +78,7 @@ public class AssertTool extends ToolBase {
.longOpt("same-user")
.hasArg()
.argName("directory")
- .build();
+ .get();
private static final Option DIRECTORY_EXISTS_OPTION =
Option.builder()
@@ -86,7 +86,7 @@ public class AssertTool extends ToolBase {
.longOpt("exists")
.hasArg()
.argName("directory")
- .build();
+ .get();
private static final Option DIRECTORY_NOT_EXISTS_OPTION =
Option.builder()
@@ -94,7 +94,7 @@ public class AssertTool extends ToolBase {
.longOpt("not-exists")
.hasArg()
.argName("directory")
- .build();
+ .get();
private static final OptionGroup DIRECTORY_OPTION =
new
OptionGroup().addOption(DIRECTORY_EXISTS_OPTION).addOption(DIRECTORY_NOT_EXISTS_OPTION);
@@ -106,7 +106,7 @@ public class AssertTool extends ToolBase {
.longOpt("cloud")
.hasArg()
.argName("url")
- .build();
+ .get();
private static final Option IS_NOT_CLOUD_OPTION =
Option.builder()
@@ -115,7 +115,7 @@ public class AssertTool extends ToolBase {
.longOpt("not-cloud")
.hasArg()
.argName("url")
- .build();
+ .get();
private static final OptionGroup CLOUD_OPTION =
new
OptionGroup().addOption(IS_CLOUD_OPTION).addOption(IS_NOT_CLOUD_OPTION);
@@ -126,7 +126,7 @@ public class AssertTool extends ToolBase {
.longOpt("message")
.hasArg()
.argName("message")
- .build();
+ .get();
private static final Option TIMEOUT_OPTION =
Option.builder()
@@ -135,13 +135,13 @@ public class AssertTool extends ToolBase {
.hasArg()
.type(Long.class)
.argName("ms")
- .build();
+ .get();
private static final Option EXIT_CODE_OPTION =
Option.builder()
.desc("Return an exit code instead of printing error message on
assert fail.")
.longOpt("exitcode")
- .build();
+ .get();
public AssertTool(ToolRuntime runtime) {
super(runtime);
@@ -292,9 +292,10 @@ public class AssertTool extends ToolBase {
status.waitToSeeSolrUp(url, credentials, 1, TimeUnit.SECONDS);
try {
log.debug("Solr still up. Waiting before trying again to see if it
was stopped");
- Thread.sleep(1000L);
+ TimeUnit.MILLISECONDS.sleep(1000L);
} catch (InterruptedException interrupted) {
- timeout = 0; // stop looping
+ Thread.currentThread().interrupt();
+ break;
}
} catch (Exception se) {
if (CLIUtils.exceptionIsAuthRelated(se)) {
@@ -312,7 +313,7 @@ public class AssertTool extends ToolBase {
}
public int assertSolrRunningInCloudMode(String url, String credentials)
throws Exception {
- if (!isSolrRunningOn(url, credentials)) {
+ if (isSolrStoppedOn(url, credentials)) {
return exitOrException(
"Solr is not running on url "
+ url
@@ -328,7 +329,7 @@ public class AssertTool extends ToolBase {
}
public int assertSolrNotRunningInCloudMode(String url, String credentials)
throws Exception {
- if (!isSolrRunningOn(url, credentials)) {
+ if (isSolrStoppedOn(url, credentials)) {
return exitOrException(
"Solr is not running on url "
+ url
@@ -344,8 +345,9 @@ public class AssertTool extends ToolBase {
}
public static int sameUser(String directory) throws Exception {
- if (Files.exists(Path.of(directory))) {
- String userForDir = userForDir(Path.of(directory));
+ Path path = Path.of(directory);
+ if (Files.exists(path)) {
+ String userForDir = userForDir(path);
if (!currentUser().equals(userForDir)) {
return exitOrException("Must run as user " + userForDir + ". We are "
+ currentUser());
}
@@ -405,16 +407,16 @@ public class AssertTool extends ToolBase {
}
}
- private boolean isSolrRunningOn(String url, String credentials) throws
Exception {
+ private boolean isSolrStoppedOn(String url, String credentials) throws
Exception {
StatusTool status = new StatusTool(runtime);
try {
status.waitToSeeSolrUp(url, credentials, timeoutMs,
TimeUnit.MILLISECONDS);
- return true;
+ return false;
} catch (Exception se) {
if (CLIUtils.exceptionIsAuthRelated(se)) {
throw se;
}
- return false;
+ return true;
}
}
diff --git a/solr/core/src/java/org/apache/solr/cli/AuthTool.java
b/solr/core/src/java/org/apache/solr/cli/AuthTool.java
index 642411808fd..5c19ac300d7 100644
--- a/solr/core/src/java/org/apache/solr/cli/AuthTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/AuthTool.java
@@ -49,7 +49,7 @@ public class AuthTool extends ToolBase {
.hasArg()
.desc(
"The authentication mechanism to enable (currently only
basicAuth). Defaults to 'basicAuth'.")
- .build();
+ .get();
private static final Option PROMPT_OPTION =
Option.builder()
@@ -58,7 +58,7 @@ public class AuthTool extends ToolBase {
.type(Boolean.class)
.desc(
"Prompts the user to provide the credentials. Use either
--credentials or --prompt, not both.")
- .build();
+ .get();
private static final Option BLOCK_UNKNOWN_OPTION =
Option.builder()
@@ -67,7 +67,7 @@ public class AuthTool extends ToolBase {
.hasArg()
.argName("true|false")
.type(Boolean.class)
- .build();
+ .get();
private static final Option SOLR_INCLUDE_FILE_OPTION =
Option.builder()
@@ -78,7 +78,7 @@ public class AuthTool extends ToolBase {
.desc(
"The Solr include file which contains overridable environment
variables for configuring Solr configurations. Defaults to solr.in."
+ (CLIUtils.isWindows() ? ".cmd" : ".sh"))
- .build();
+ .get();
private static final Option UPDATE_INCLUDE_FILE_OPTION =
Option.builder()
@@ -88,7 +88,7 @@ public class AuthTool extends ToolBase {
+ " authentication (i.e. don't update security.json).")
.hasArg()
.type(Boolean.class)
- .build();
+ .get();
private static final Option AUTH_CONF_DIR_OPTION =
Option.builder()
@@ -98,7 +98,7 @@ public class AuthTool extends ToolBase {
.required()
.desc(
"This is where any authentication related configuration files,
if any, would be placed. Defaults to $SOLR_HOME.")
- .build();
+ .get();
public AuthTool(ToolRuntime runtime) {
super(runtime);
@@ -111,16 +111,20 @@ public class AuthTool extends ToolBase {
@Override
public String getUsage() {
- return "\n bin/solr auth enable [--type basicAuth] --credentials
user:pass [--block-unknown <true|false>] [--update-include-file-only
<true|false>] [-v]\n"
- + " bin/solr auth enable [--type basicAuth] --prompt <true|false>
[--block-unknown <true|false>] [--update-include-file-only <true|false>] [-v]\n"
- + " bin/solr auth disable [--update-include-file-only <true|false>]
[-v]\n";
+ return """
+
+ bin/solr auth enable [--type basicAuth] --credentials user:pass
[--block-unknown <true|false>] [--update-include-file-only <true|false>] [-v]
+ bin/solr auth enable [--type basicAuth] --prompt <true|false>
[--block-unknown <true|false>] [--update-include-file-only <true|false>] [-v]
+ bin/solr auth disable [--update-include-file-only <true|false>] [-v]
+ """;
}
@Override
public String getHeader() {
- return "Updates or enables/disables authentication. Must be run on the
Solr server itself.\n"
- + "\n"
- + "List of options:";
+ return """
+ Updates or enables/disables authentication. Must be run on the Solr
server itself.
+
+ List of options:""";
}
List<String> authenticationVariables =
@@ -162,142 +166,146 @@ public class AuthTool extends ToolBase {
Boolean.parseBoolean(cli.getOptionValue(UPDATE_INCLUDE_FILE_OPTION,
"false"));
switch (cmd) {
case "enable":
- if (!prompt && !cli.hasOption(CommonCLIOptions.CREDENTIALS_OPTION)) {
- CLIO.out("Option --credentials or --prompt is required with
enable.");
- runtime.exit(1);
- } else if (!prompt
- && (cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION) == null
- ||
!cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION).contains(":"))) {
- CLIO.out("Option --credentials is not in correct format.");
- runtime.exit(1);
- }
-
- String zkHost = null;
-
- if (!updateIncludeFileOnly) {
- try {
- zkHost = CLIUtils.getZkHost(cli);
- } catch (Exception ex) {
- if (cli.hasOption(CommonCLIOptions.ZK_HOST_OPTION)) {
- CLIO.out(
- "Couldn't get ZooKeeper host. Please make sure that
ZooKeeper is running and the correct zk-host has been passed in.");
- } else {
- CLIO.out(
- "Couldn't get ZooKeeper host. Please make sure Solr is
running in cloud mode, or a zk-host has been passed in.");
- }
+ {
+ if (!prompt && !cli.hasOption(CommonCLIOptions.CREDENTIALS_OPTION)) {
+ CLIO.out("Option --credentials or --prompt is required with
enable.");
+ runtime.exit(1);
+ } else if (!prompt
+ && (cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION) ==
null
+ ||
!cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION).contains(":"))) {
+ CLIO.out("Option --credentials is not in correct format.");
runtime.exit(1);
}
- if (zkHost == null) {
- if (cli.hasOption(CommonCLIOptions.ZK_HOST_OPTION)) {
- CLIO.out(
- "Couldn't get ZooKeeper host. Please make sure that
ZooKeeper is running and the correct zk-host has been passed in.");
- } else {
- CLIO.out(
- "Couldn't get ZooKeeper host. Please make sure Solr is
running in cloud mode, or a zk-host has been passed in.");
+
+ String zkHost = null;
+
+ if (!updateIncludeFileOnly) {
+ try {
+ zkHost = CLIUtils.getZkHost(cli);
+ } catch (Exception ex) {
+ if (cli.hasOption(CommonCLIOptions.ZK_HOST_OPTION)) {
+ CLIO.out(
+ "Couldn't get ZooKeeper host. Please make sure that
ZooKeeper is running and the correct zk-host has been passed in.");
+ } else {
+ CLIO.out(
+ "Couldn't get ZooKeeper host. Please make sure Solr is
running in cloud mode, or a zk-host has been passed in.");
+ }
+ runtime.exit(1);
+ }
+ if (zkHost == null) {
+ if (cli.hasOption(CommonCLIOptions.ZK_HOST_OPTION)) {
+ CLIO.out(
+ "Couldn't get ZooKeeper host. Please make sure that
ZooKeeper is running and the correct zk-host has been passed in.");
+ } else {
+ CLIO.out(
+ "Couldn't get ZooKeeper host. Please make sure Solr is
running in cloud mode, or a zk-host has been passed in.");
+ }
+ runtime.exit(1);
+ }
+
+ // check if security is already enabled or not
+ try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli,
zkHost)) {
+ checkSecurityJsonExists(zkClient);
}
- runtime.exit(1);
}
- // check if security is already enabled or not
- try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli, zkHost)) {
- checkSecurityJsonExists(zkClient);
+ String username, password;
+ if (cli.hasOption(CommonCLIOptions.CREDENTIALS_OPTION)) {
+ String credentials =
cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION);
+ username = credentials.split(":")[0];
+ password = credentials.split(":")[1];
+ } else {
+ Console console = System.console();
+ // keep prompting until they've entered a non-empty username &
password
+ do {
+ username = console.readLine("Enter username: ");
+ } while (username == null || username.trim().isEmpty());
+ username = username.trim();
+
+ do {
+ password = new String(console.readPassword("Enter password: "));
+ } while (password.isEmpty());
}
- }
- String username, password;
- if (cli.hasOption(CommonCLIOptions.CREDENTIALS_OPTION)) {
- String credentials =
cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION);
- username = credentials.split(":")[0];
- password = credentials.split(":")[1];
- } else {
- Console console = System.console();
- // keep prompting until they've entered a non-empty username &
password
- do {
- username = console.readLine("Enter username: ");
- } while (username == null || username.trim().length() == 0);
- username = username.trim();
-
- do {
- password = new String(console.readPassword("Enter password: "));
- } while (password.length() == 0);
- }
+ boolean blockUnknown =
+ Boolean.parseBoolean(cli.getOptionValue(BLOCK_UNKNOWN_OPTION,
"true"));
- boolean blockUnknown =
- Boolean.parseBoolean(cli.getOptionValue(BLOCK_UNKNOWN_OPTION,
"true"));
+ String resourceName = "security.json";
+ final URL resource =
SolrCore.class.getClassLoader().getResource(resourceName);
+ if (null == resource) {
+ throw new IllegalArgumentException("invalid resource name: " +
resourceName);
+ }
- String resourceName = "security.json";
- final URL resource =
SolrCore.class.getClassLoader().getResource(resourceName);
- if (null == resource) {
- throw new IllegalArgumentException("invalid resource name: " +
resourceName);
- }
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode securityJson1 = mapper.readTree(resource.openStream());
+ ((ObjectNode) securityJson1).put("blockUnknown", blockUnknown);
+ JsonNode credentialsNode =
securityJson1.get("authentication").get("credentials");
+ ((ObjectNode) credentialsNode)
+ .put(username,
Sha256AuthenticationProvider.getSaltedHashedValue(password));
+ JsonNode userRoleNode =
securityJson1.get("authorization").get("user-role");
+ String[] predefinedRoles = {"superadmin", "admin", "search",
"index"};
+ ArrayNode rolesNode = mapper.createArrayNode();
+ for (String role : predefinedRoles) {
+ rolesNode.add(role);
+ }
+ ((ObjectNode) userRoleNode).set(username, rolesNode);
+ String securityJson = securityJson1.toPrettyString();
- ObjectMapper mapper = new ObjectMapper();
- JsonNode securityJson1 = mapper.readTree(resource.openStream());
- ((ObjectNode) securityJson1).put("blockUnknown", blockUnknown);
- JsonNode credentialsNode =
securityJson1.get("authentication").get("credentials");
- ((ObjectNode) credentialsNode)
- .put(username,
Sha256AuthenticationProvider.getSaltedHashedValue(password));
- JsonNode userRoleNode =
securityJson1.get("authorization").get("user-role");
- String[] predefinedRoles = {"superadmin", "admin", "search", "index"};
- ArrayNode rolesNode = mapper.createArrayNode();
- for (String role : predefinedRoles) {
- rolesNode.add(role);
- }
- ((ObjectNode) userRoleNode).set(username, rolesNode);
- String securityJson = securityJson1.toPrettyString();
+ if (!updateIncludeFileOnly) {
+ echoIfVerbose("Uploading following security.json: " +
securityJson);
+ try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli,
zkHost)) {
+ zkClient.setData("/security.json",
securityJson.getBytes(StandardCharsets.UTF_8));
+ }
+ }
- if (!updateIncludeFileOnly) {
- echoIfVerbose("Uploading following security.json: " + securityJson);
- try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli, zkHost)) {
- zkClient.setData("/security.json",
securityJson.getBytes(StandardCharsets.UTF_8));
+ String solrIncludeFilename =
cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION);
+ Path includeFile = Path.of(solrIncludeFilename);
+ if (Files.notExists(includeFile) || !Files.isWritable(includeFile)) {
+ CLIO.out(
+ "Solr include file " + solrIncludeFilename + " doesn't exist
or is not writeable.");
+ printAuthEnablingInstructions(username, password);
+ runtime.exit(0);
}
- }
+ String authConfDir = cli.getOptionValue(AUTH_CONF_DIR_OPTION);
+ Path basicAuthConfFile = Path.of(authConfDir, "basicAuth.conf");
- String solrIncludeFilename =
cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION);
- Path includeFile = Path.of(solrIncludeFilename);
- if (Files.notExists(includeFile) || !Files.isWritable(includeFile)) {
- CLIO.out(
- "Solr include file " + solrIncludeFilename + " doesn't exist or
is not writeable.");
- printAuthEnablingInstructions(username, password);
- runtime.exit(0);
- }
- String authConfDir = cli.getOptionValue(AUTH_CONF_DIR_OPTION);
- Path basicAuthConfFile = Path.of(authConfDir, "basicAuth.conf");
+ if (!Files.isWritable(basicAuthConfFile.getParent())) {
+ CLIO.out("Cannot write to file: " +
basicAuthConfFile.toAbsolutePath());
+ printAuthEnablingInstructions(username, password);
+ runtime.exit(0);
+ }
- if (!Files.isWritable(basicAuthConfFile.getParent())) {
- CLIO.out("Cannot write to file: " +
basicAuthConfFile.toAbsolutePath());
- printAuthEnablingInstructions(username, password);
- runtime.exit(0);
+ Files.writeString(
+ basicAuthConfFile,
+ "httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" +
password,
+ StandardCharsets.UTF_8);
+
+ // update the solr.in.sh file to contain the necessary
authentication lines
+ updateIncludeFileEnableAuth(includeFile, basicAuthConfFile);
+ final String successMessage =
+ String.format(
+ Locale.ROOT, "Successfully enabled basic auth with username
[%s].", username);
+ echo(successMessage);
+ return;
}
-
- Files.writeString(
- basicAuthConfFile,
- "httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" +
password,
- StandardCharsets.UTF_8);
-
- // update the solr.in.sh file to contain the necessary authentication
lines
- updateIncludeFileEnableAuth(includeFile, basicAuthConfFile);
- final String successMessage =
- String.format(
- Locale.ROOT, "Successfully enabled basic auth with username
[%s].", username);
- echo(successMessage);
- return;
case "disable":
- clearSecurityJson(cli, updateIncludeFileOnly);
-
- solrIncludeFilename = cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION);
- includeFile = Path.of(solrIncludeFilename);
- if (Files.notExists(includeFile) || !Files.isWritable(includeFile)) {
- CLIO.out(
- "Solr include file " + solrIncludeFilename + " doesn't exist or
is not writeable.");
- CLIO.out(
- "Security has been disabled. Please remove any SOLR_AUTH_TYPE or
SOLR_AUTHENTICATION_OPTS configuration from solr.in.sh/solr.in.cmd.\n");
- runtime.exit(0);
- }
+ {
+ clearSecurityJson(cli, updateIncludeFileOnly);
+
+ String solrIncludeFilename =
cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION);
+ Path includeFile = Path.of(solrIncludeFilename);
+ if (Files.notExists(includeFile) || !Files.isWritable(includeFile)) {
+ CLIO.out(
+ "Solr include file " + solrIncludeFilename + " doesn't exist
or is not writeable.");
+ CLIO.out(
+ "Security has been disabled. Please remove any SOLR_AUTH_TYPE
or SOLR_AUTHENTICATION_OPTS configuration from solr.in.sh/solr.in.cmd.\n");
+ runtime.exit(0);
+ }
- // update the solr.in.sh file to comment out the necessary
authentication lines
- updateIncludeFileDisableAuth(includeFile);
- return;
+ // update the solr.in.sh file to comment out the necessary
authentication lines
+ updateIncludeFileDisableAuth(includeFile);
+ return;
+ }
default:
CLIO.out("Valid auth commands are: enable, disable.");
runtime.exit(1);
@@ -438,12 +446,10 @@ public class AuthTool extends ToolBase {
String type = cli.getOptionValue(TYPE_OPTION, "basicAuth");
// switch structure is here to support future auth options like oAuth
- switch (type) {
- case "basicAuth":
- handleBasicAuth(cli);
- break;
- default:
- throw new IllegalStateException("Only type=basicAuth supported at the
moment.");
+ if (type.equals("basicAuth")) {
+ handleBasicAuth(cli);
+ } else {
+ throw new IllegalStateException("Only type=basicAuth supported at the
moment.");
}
}
}
diff --git a/solr/core/src/java/org/apache/solr/cli/CLIUtils.java
b/solr/core/src/java/org/apache/solr/cli/CLIUtils.java
index 36baeb8357f..1c05377e889 100644
--- a/solr/core/src/java/org/apache/solr/cli/CLIUtils.java
+++ b/solr/core/src/java/org/apache/solr/cli/CLIUtils.java
@@ -198,7 +198,6 @@ public final class CLIUtils {
+ ".");
} else {
try (CloudSolrClient cloudSolrClient = getCloudSolrClient(zkHost)) {
- cloudSolrClient.connect();
Set<String> liveNodes =
cloudSolrClient.getClusterState().getLiveNodes();
if (liveNodes.isEmpty())
throw new IllegalStateException(
@@ -262,7 +261,7 @@ public final class CLIUtils {
return zkHost;
}
- public static SolrZkClient getSolrZkClient(CommandLine cli, String zkHost)
throws Exception {
+ public static SolrZkClient getSolrZkClient(CommandLine cli, String zkHost) {
if (zkHost == null) {
throw new IllegalStateException(
"Solr at "
@@ -322,7 +321,6 @@ public final class CLIUtils {
return exists;
}
- @SuppressWarnings("unchecked")
public static boolean safeCheckCoreExists(String solrUrl, String coreName,
String credentials) {
boolean exists = false;
try (var solrClient = getSolrClient(solrUrl, credentials)) {
@@ -330,8 +328,13 @@ public final class CLIUtils {
final long startWaitAt = System.nanoTime();
do {
if (wait) {
- final int clamPeriodForStatusPollMs = 1000;
- Thread.sleep(clamPeriodForStatusPollMs);
+ final int pollIntervalMs = 1000;
+ try {
+ TimeUnit.MILLISECONDS.sleep(pollIntervalMs);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ break;
+ }
}
final var coreStatusReq = new CoresApi.GetCoreStatus(coreName);
final var coreStatusRsp = coreStatusReq.process(solrClient);
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 7f0a5bbb586..54626e2b7db 100644
--- a/solr/core/src/java/org/apache/solr/cli/ClusterTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ClusterTool.java
@@ -42,7 +42,7 @@ public class ClusterTool extends ToolBase {
.argName("PROPERTY")
.required()
.desc("Name of the Cluster property to apply the action to, such as:
'urlScheme'.")
- .build();
+ .get();
private static final Option VALUE_OPTION =
Option.builder()
@@ -50,7 +50,7 @@ public class ClusterTool extends ToolBase {
.hasArg()
.argName("VALUE")
.desc("Set the property to this value.")
- .build();
+ .get();
public ClusterTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/CommonCLIOptions.java
b/solr/core/src/java/org/apache/solr/cli/CommonCLIOptions.java
index e6425abe1f3..d0b77403071 100644
--- a/solr/core/src/java/org/apache/solr/cli/CommonCLIOptions.java
+++ b/solr/core/src/java/org/apache/solr/cli/CommonCLIOptions.java
@@ -24,10 +24,10 @@ public final class CommonCLIOptions {
private CommonCLIOptions() {}
public static final Option VERBOSE_OPTION =
- Option.builder("v").longOpt("verbose").desc("Enable verbose command
output.").build();
+ Option.builder("v").longOpt("verbose").desc("Enable verbose command
output.").get();
public static final Option HELP_OPTION =
- Option.builder("h").longOpt("help").desc("Print this message.").build();
+ Option.builder("h").longOpt("help").desc("Print this message.").get();
public static final Option ZK_HOST_OPTION =
Option.builder("z")
@@ -38,7 +38,7 @@ public final class CommonCLIOptions {
"Zookeeper connection string; unnecessary if ZK_HOST is defined
in solr.in.sh; otherwise, defaults to "
+ DefaultValues.ZK_HOST
+ '.')
- .build();
+ .get();
public static final Option SOLR_URL_OPTION =
Option.builder("s")
@@ -49,10 +49,10 @@ public final class CommonCLIOptions {
"Base Solr URL, which can be used to determine the zk-host if
that's not known; defaults to: "
+ CLIUtils.getDefaultSolrUrl()
+ '.')
- .build();
+ .get();
public static final Option RECURSIVE_OPTION =
- Option.builder("r").longOpt("recursive").desc("Apply the command
recursively.").build();
+ Option.builder("r").longOpt("recursive").desc("Apply the command
recursively.").get();
public static final Option CREDENTIALS_OPTION =
Option.builder("u")
@@ -61,7 +61,7 @@ public final class CommonCLIOptions {
.argName("credentials")
.desc(
"Credentials in the format username:password. Example:
--credentials solr:SolrRocks")
- .build();
+ .get();
public static final class DefaultValues {
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
b/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
index 7810d974586..5623794626c 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigSetDownloadTool.java
@@ -37,7 +37,7 @@ public class ConfigSetDownloadTool extends ToolBase {
.argName("NAME")
.required()
.desc("Configset name in ZooKeeper.")
- .build();
+ .get();
private static final Option CONF_DIR_OPTION =
Option.builder("d")
@@ -46,7 +46,7 @@ public class ConfigSetDownloadTool extends ToolBase {
.argName("DIR")
.required()
.desc("Local directory with configs.")
- .build();
+ .get();
public ConfigSetDownloadTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
b/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
index 7088e8919bf..fdd2380f3a1 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigSetUploadTool.java
@@ -39,7 +39,7 @@ public class ConfigSetUploadTool extends ToolBase {
.argName("NAME")
.required()
.desc("Configset name in ZooKeeper.")
- .build();
+ .get();
private static final Option CONF_DIR_OPTION =
Option.builder("d")
@@ -48,7 +48,7 @@ public class ConfigSetUploadTool extends ToolBase {
.argName("DIR")
.required()
.desc("Local directory with configs.")
- .build();
+ .get();
public ConfigSetUploadTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
b/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
index ce7b644c457..a4145168165 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
@@ -43,7 +43,7 @@ public class ConfigTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the collection.")
- .build();
+ .get();
private static final Option ACTION_OPTION =
Option.builder("a")
@@ -52,7 +52,7 @@ public class ConfigTool extends ToolBase {
.argName("ACTION")
.desc(
"Config API action, one of: set-property, unset-property,
set-user-property, unset-user-property; default is 'set-property'.")
- .build();
+ .get();
private static final Option PROPERTY_OPTION =
Option.builder()
@@ -62,7 +62,7 @@ public class ConfigTool extends ToolBase {
.required()
.desc(
"Name of the Config API property to apply the action to, such
as: 'updateHandler.autoSoftCommit.maxTime'.")
- .build();
+ .get();
private static final Option VALUE_OPTION =
Option.builder("v")
@@ -70,7 +70,7 @@ public class ConfigTool extends ToolBase {
.hasArg()
.argName("VALUE")
.desc("Set the property to this value; accepts JSON objects and
strings.")
- .build();
+ .get();
public ConfigTool(ToolRuntime runtime) {
super(runtime);
@@ -100,7 +100,7 @@ public class ConfigTool extends ToolBase {
String property = cli.getOptionValue(PROPERTY_OPTION);
String value = cli.getOptionValue(VALUE_OPTION);
- // value is required unless the property is one of the unset- type.
+ // value is required unless the property is one of the "unset-" type.
if (!action.contains("unset-") && value == null) {
throw new MissingArgumentException("'value' is a required option.");
}
diff --git a/solr/core/src/java/org/apache/solr/cli/CreateTool.java
b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
index 0226471cd13..33ab28ef383 100644
--- a/solr/core/src/java/org/apache/solr/cli/CreateTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
@@ -55,7 +55,7 @@ public class CreateTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of collection or core to create.")
- .build();
+ .get();
private static final Option SHARDS_OPTION =
Option.builder("sh")
@@ -64,7 +64,7 @@ public class CreateTool extends ToolBase {
.argName("#")
.type(Integer.class)
.desc("Number of shards; default is 1.")
- .build();
+ .get();
private static final Option REPLICATION_FACTOR_OPTION =
Option.builder("rf")
@@ -74,7 +74,7 @@ public class CreateTool extends ToolBase {
.type(Integer.class)
.desc(
"Number of copies of each document across the collection
(replicas per shard); default is 1.")
- .build();
+ .get();
private static final Option CONF_DIR_OPTION =
Option.builder("d")
@@ -85,7 +85,7 @@ public class CreateTool extends ToolBase {
"Configuration directory to copy when creating the new
collection; default is "
+ DefaultValues.DEFAULT_CONFIG_SET
+ '.')
- .build();
+ .get();
private static final Option CONF_NAME_OPTION =
Option.builder("n")
@@ -93,7 +93,7 @@ public class CreateTool extends ToolBase {
.hasArg()
.argName("NAME")
.desc("Configuration name; default is the collection name.")
- .build();
+ .get();
public CreateTool(ToolRuntime runtime) {
super(runtime);
@@ -106,25 +106,23 @@ public class CreateTool extends ToolBase {
@Override
public String getHeader() {
- return "Creates a core or collection depending on whether Solr is running
in standalone (core) or SolrCloud mode (collection).\n"
- + "If you are using standalone mode you must run this command on the
Solr server itself.\n"
- + "\n"
- + "List of options:";
+ return """
+ Creates a core or collection depending on whether Solr is running in
standalone (core) or SolrCloud mode (collection).
+ If you are using standalone mode you must run this command on the Solr
server itself.
+
+ List of options:""";
}
@Override
public Options getOptions() {
- Options opts =
- super.getOptions()
- .addOption(COLLECTION_NAME_OPTION)
- .addOption(SHARDS_OPTION)
- .addOption(REPLICATION_FACTOR_OPTION)
- .addOption(CONF_DIR_OPTION)
- .addOption(CONF_NAME_OPTION)
- .addOption(CommonCLIOptions.CREDENTIALS_OPTION)
- .addOptionGroup(getConnectionOptions());
-
- return opts;
+ return super.getOptions()
+ .addOption(COLLECTION_NAME_OPTION)
+ .addOption(SHARDS_OPTION)
+ .addOption(REPLICATION_FACTOR_OPTION)
+ .addOption(CONF_DIR_OPTION)
+ .addOption(CONF_NAME_OPTION)
+ .addOption(CommonCLIOptions.CREDENTIALS_OPTION)
+ .addOptionGroup(getConnectionOptions());
}
@Override
@@ -212,7 +210,6 @@ public class CreateTool extends ToolBase {
String zkHost = CLIUtils.getZkHost(cli);
echoIfVerbose("Connecting to ZooKeeper at " + zkHost);
try (CloudSolrClient cloudSolrClient = CLIUtils.getCloudSolrClient(zkHost,
builder)) {
- cloudSolrClient.connect();
createCollection(cloudSolrClient, cli);
}
}
@@ -340,7 +337,7 @@ public class CreateTool extends ToolBase {
final String confName = cli.getOptionValue(CONF_NAME_OPTION, "");
if (confDirectoryName.equals("_default")
- && (confName.equals("") || confName.equals("_default"))) {
+ && (confName.isEmpty() || confName.equals("_default"))) {
final String collectionName = cli.getOptionValue(COLLECTION_NAME_OPTION);
final String solrUrl =
cli.getOptionValue(CommonCLIOptions.SOLR_URL_OPTION,
CLIUtils.getDefaultSolrUrl());
diff --git a/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
b/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
index 3675098f8ee..2610e2af18d 100644
--- a/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
@@ -50,21 +50,21 @@ public class DeleteTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the core / collection to delete.")
- .build();
+ .get();
private static final Option DELETE_CONFIG_OPTION =
Option.builder()
.longOpt("delete-config")
.desc(
"Flag to indicate if the underlying configuration directory for
a collection should also be deleted; default is true.")
- .build();
+ .get();
private static final Option FORCE_OPTION =
Option.builder("f")
.longOpt("force")
.desc(
"Skip safety checks when deleting the configuration directory
used by a collection.")
- .build();
+ .get();
public DeleteTool(ToolRuntime runtime) {
super(runtime);
@@ -77,10 +77,11 @@ public class DeleteTool extends ToolBase {
@Override
public String getHeader() {
- return "Deletes a collection or core depending on whether Solr is running
in SolrCloud or standalone mode. "
- + "Deleting a collection does not delete it's configuration unless you
pass in the --delete-config flag.\n"
- + "\n"
- + "List of options:";
+ return """
+ Deletes a collection or core depending on whether Solr is running in
SolrCloud or standalone mode. \
+ Deleting a collection does not delete it's configuration unless you
pass in the --delete-config flag.
+
+ List of options:""";
}
@Override
@@ -116,7 +117,6 @@ public class DeleteTool extends ToolBase {
String zkHost = CLIUtils.getZkHost(cli);
try (CloudSolrClient cloudSolrClient = CLIUtils.getCloudSolrClient(zkHost,
builder)) {
echoIfVerbose("Connecting to ZooKeeper at " + zkHost);
- cloudSolrClient.connect();
deleteCollection(cloudSolrClient, cli);
}
}
diff --git a/solr/core/src/java/org/apache/solr/cli/ExportTool.java
b/solr/core/src/java/org/apache/solr/cli/ExportTool.java
index 57336d2f7f9..6fd43b52a1c 100644
--- a/solr/core/src/java/org/apache/solr/cli/ExportTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ExportTool.java
@@ -93,7 +93,7 @@ public class ExportTool extends ToolBase {
.hasArg()
.argName("NAME")
.desc("Name of the collection.")
- .build();
+ .get();
private static final Option OUTPUT_OPTION =
Option.builder()
@@ -102,7 +102,7 @@ public class ExportTool extends ToolBase {
.argName("PATH")
.desc(
"Path to output the exported data, and optionally the file name,
defaults to 'collection-name'.")
- .build();
+ .get();
private static final Option FORMAT_OPTION =
Option.builder()
@@ -110,10 +110,10 @@ public class ExportTool extends ToolBase {
.hasArg()
.argName("FORMAT")
.desc("Output format for exported docs (json, jsonl or javabin),
defaulting to json.")
- .build();
+ .get();
private static final Option COMPRESS_OPTION =
- Option.builder().longOpt("compress").desc("Compress the output. Defaults
to false.").build();
+ Option.builder().longOpt("compress").desc("Compress the output. Defaults
to false.").get();
private static final Option LIMIT_OPTION =
Option.builder()
@@ -121,7 +121,7 @@ public class ExportTool extends ToolBase {
.hasArg()
.argName("#")
.desc("Maximum number of docs to download. Default is 100, use -1
for all docs.")
- .build();
+ .get();
private static final Option QUERY_OPTION =
Option.builder()
@@ -129,7 +129,7 @@ public class ExportTool extends ToolBase {
.hasArg()
.argName("QUERY")
.desc("A custom query, default is '*:*'.")
- .build();
+ .get();
private static final Option FIELDS_OPTION =
Option.builder()
@@ -137,7 +137,7 @@ public class ExportTool extends ToolBase {
.hasArg()
.argName("FIELDA,FIELDB")
.desc("Comma separated list of fields to export. By default all
fields are fetched.")
- .build();
+ .get();
public ExportTool(ToolRuntime runtime) {
super(runtime);
@@ -233,19 +233,12 @@ public class ExportTool extends ToolBase {
}
DocsSink getSink() {
- DocsSink docSink = null;
- switch (format) {
- case JAVABIN:
- docSink = new JavabinSink(this);
- break;
- case JSON:
- docSink = new JsonSink(this);
- break;
- case "jsonl":
- docSink = new JsonWithLinesSink(this);
- break;
- }
- return docSink;
+ return switch (format) {
+ case JAVABIN -> new JavabinSink(this);
+ case JSON -> new JsonSink(this);
+ case "jsonl" -> new JsonWithLinesSink(this);
+ default -> null;
+ };
}
abstract void exportDocs() throws Exception;
@@ -290,7 +283,7 @@ public class ExportTool extends ToolBase {
@Override
public void runImpl(CommandLine cli) throws Exception {
- String url = null;
+ String url;
if (cli.hasOption(CommonCLIOptions.SOLR_URL_OPTION)) {
if (!cli.hasOption(COLLECTION_NAME_OPTION)) {
throw new IllegalArgumentException(
@@ -327,7 +320,7 @@ public class ExportTool extends ToolBase {
if (s.equals("_version_") || s.equals("_roor_")) return;
if (field instanceof List) {
if (((List<?>) field).size() == 1) {
- field = ((List<?>) field).get(0);
+ field = ((List<?>) field).getFirst();
}
}
field = constructDateStr(field);
@@ -640,7 +633,7 @@ public class ExportTool extends ToolBase {
this.replica = replica;
}
- boolean exportDocsFromCore() throws IOException, SolrServerException {
+ void exportDocsFromCore() throws IOException, SolrServerException {
// reference the replica's node URL, not the baseUrl in scope, which
could be anywhere
try (SolrClient client = CLIUtils.getSolrClient(replica.getBaseUrl(),
credentials)) {
expectedDocs = getDocCount(replica.getCoreName(), client, query);
@@ -665,8 +658,8 @@ public class ExportTool extends ToolBase {
StreamingJavaBinResponseParser responseParser =
new StreamingJavaBinResponseParser(getStreamer(wrapper));
while (true) {
- if (failed) return false;
- if (docsWritten.get() > limit) return true;
+ if (failed) return;
+ if (docsWritten.get() > limit) return;
params.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
request = new QueryRequest(params);
request.setResponseParser(responseParser);
@@ -683,9 +676,9 @@ public class ExportTool extends ToolBase {
StrUtils.formatString(
"Could not download all docs from core {0}, docs
expected: {1}, received: {2}",
replica.getCoreName(), expectedDocs,
receivedDocs.get()));
- return false;
+ return;
}
- return true;
+ return;
}
cursorMark = nextCursorMark;
runtime.print(".");
@@ -696,7 +689,7 @@ public class ExportTool extends ToolBase {
+ "/"
+ replica.getCoreName());
failed = true;
- return false;
+ return;
}
}
}
diff --git a/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
b/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
index 8745941cff3..670bb0eb656 100644
--- a/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
@@ -56,7 +56,7 @@ public class HealthcheckTool extends ToolBase {
.argName("COLLECTION")
.required()
.desc("Name of the collection to check.")
- .build();
+ .get();
@Override
public Options getOptions() {
@@ -87,7 +87,6 @@ public class HealthcheckTool extends ToolBase {
}
try (var cloudSolrClient = CLIUtils.getCloudSolrClient(zkHost)) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...");
- cloudSolrClient.connect();
runCloudTool(cloudSolrClient, cli);
}
}
@@ -194,7 +193,7 @@ public class HealthcheckTool extends ToolBase {
ShardHealth shardHealth = new ShardHealth(shardName, replicaList);
if (ShardState.healthy != shardHealth.getShardState()) {
- collectionIsHealthy = false; // at least one shard is un-healthy
+ collectionIsHealthy = false; // at least one shard is unhealthy
}
shardList.add(shardHealth.asMap());
@@ -280,10 +279,8 @@ class ReplicaHealth implements Comparable<ReplicaHealth> {
@Override
public int compareTo(ReplicaHealth other) {
if (this == other) return 0;
- if (other == null) return 1;
int myShardIndex =
Integer.parseInt(this.shard.substring("shard".length()));
-
int otherShardIndex =
Integer.parseInt(other.shard.substring("shard".length()));
if (myShardIndex == otherShardIndex) {
diff --git a/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
b/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
index afc14edea83..cb46c6e8193 100644
--- a/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/LinkConfigTool.java
@@ -35,7 +35,7 @@ public class LinkConfigTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the collection to link.")
- .build();
+ .get();
private static final Option CONF_NAME_OPTION =
Option.builder("n")
@@ -44,7 +44,7 @@ public class LinkConfigTool extends ToolBase {
.argName("NAME")
.required()
.desc("Configset name in ZooKeeper.")
- .build();
+ .get();
public LinkConfigTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/PackageTool.java
b/solr/core/src/java/org/apache/solr/cli/PackageTool.java
index f715a20cd13..aaa3649d1be 100644
--- a/solr/core/src/java/org/apache/solr/cli/PackageTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/PackageTool.java
@@ -57,13 +57,13 @@ public class PackageTool extends ToolBase {
.argName("COLLECTIONS")
.desc(
"Specifies that this action should affect plugins for the given
collections only, excluding cluster level plugins.")
- .build();
+ .get();
private static final Option CLUSTER_OPTION =
Option.builder()
.longOpt("cluster")
.desc("Specifies that this action should affect cluster-level
plugins only.")
- .build();
+ .get();
private static final Option PARAM_OPTION =
Option.builder()
@@ -71,13 +71,13 @@ public class PackageTool extends ToolBase {
.hasArgs()
.argName("PARAMS")
.desc("List of parameters to be used with deploy command.")
- .build();
+ .get();
private static final Option UPDATE_OPTION =
Option.builder()
.longOpt("update")
.desc("If a deployment is an update over a previous deployment.")
- .build();
+ .get();
private static final Option COLLECTION_OPTION =
Option.builder("c")
@@ -85,13 +85,13 @@ public class PackageTool extends ToolBase {
.hasArg()
.argName("COLLECTION")
.desc("The collection to apply the package to, not required.")
- .build();
+ .get();
private static final Option NO_PROMPT_OPTION =
Option.builder("y")
.longOpt("no-prompt")
.desc("Don't prompt for input; accept all default choices, defaults
to false.")
- .build();
+ .get();
public PackageTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java
b/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java
index 0cf5e95a943..82dccf53742 100644
--- a/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java
@@ -32,7 +32,6 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
@@ -55,7 +54,7 @@ public class PostLogsTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the collection.")
- .build();
+ .get();
private static final Option ROOT_DIR_OPTION =
Option.builder()
@@ -64,7 +63,7 @@ public class PostLogsTool extends ToolBase {
.argName("DIRECTORY")
.required()
.desc("All files found at or below the root directory will be
indexed.")
- .build();
+ .get();
public PostLogsTool(ToolRuntime runtime) {
super(runtime);
@@ -86,7 +85,7 @@ public class PostLogsTool extends ToolBase {
@Override
public void runImpl(CommandLine cli) throws Exception {
- String url = null;
+ String url;
if (cli.hasOption(CommonCLIOptions.SOLR_URL_OPTION)) {
url = CLIUtils.normalizeSolrUrl(cli) + "/solr/" +
cli.getOptionValue(COLLECTION_NAME_OPTION);
@@ -118,7 +117,7 @@ public class PostLogsTool extends ToolBase {
List<Path> files;
try (Stream<Path> stream = Files.walk(Path.of(root), Integer.MAX_VALUE))
{
- files =
stream.filter(Files::isRegularFile).collect(Collectors.toList());
+ files = stream.filter(Files::isRegularFile).toList();
}
for (Path file : files) {
@@ -186,24 +185,24 @@ public class PostLogsTool extends ToolBase {
public static class LogRecordReader {
- private BufferedReader bufferedReader;
+ private final BufferedReader bufferedReader;
private String pushedBack = null;
private boolean finished = false;
private String cause;
- private Pattern p =
+ private final Pattern p =
Pattern.compile("^(\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d[\\s|T]\\d\\d:\\d\\d\\:\\d\\d.\\d\\d\\d)");
- private Pattern minute =
+ private final Pattern minute =
Pattern.compile("^(\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d[\\s|T]\\d\\d:\\d\\d)");
- private Pattern tenSecond =
+ private final Pattern tenSecond =
Pattern.compile("^(\\d\\d\\d\\d\\-\\d\\d\\-\\d\\d[\\s|T]\\d\\d:\\d\\d:\\d)");
- public LogRecordReader(BufferedReader bufferedReader) throws IOException {
+ public LogRecordReader(BufferedReader bufferedReader) {
this.bufferedReader = bufferedReader;
}
public SolrInputDocument readRecord() throws IOException {
while (true) {
- String line = null;
+ String line;
if (finished) {
return null;
diff --git a/solr/core/src/java/org/apache/solr/cli/PostTool.java
b/solr/core/src/java/org/apache/solr/cli/PostTool.java
index f4a6dc4085b..97751490e3f 100644
--- a/solr/core/src/java/org/apache/solr/cli/PostTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/PostTool.java
@@ -103,19 +103,19 @@ public class PostTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the collection.")
- .build();
+ .get();
private static final Option SKIP_COMMIT_OPTION =
Option.builder()
.longOpt("skip-commit")
.desc("Do not 'commit', and thus changes won't be visible till a
commit occurs.")
- .build();
+ .get();
private static final Option OPTIMIZE_OPTION =
Option.builder("o")
.longOpt("optimize")
.desc("Issue an optimize at end of posting documents.")
- .build();
+ .get();
private static final Option MODE_OPTION =
Option.builder()
@@ -124,7 +124,7 @@ public class PostTool extends ToolBase {
.argName("mode")
.desc(
"Which mode the Post tool is running in, 'files' crawls local
directory, 'web' crawls website, 'args' processes input args, and 'stdin' reads
a command from standard in. default: files.")
- .build();
+ .get();
private static final Option RECURSIVE_OPTION =
Option.builder("r")
@@ -133,7 +133,7 @@ public class PostTool extends ToolBase {
.argName("recursive")
.type(Integer.class)
.desc("For web crawl, how deep to go. default: 1")
- .build();
+ .get();
private static final Option DELAY_OPTION =
Option.builder("d")
@@ -143,7 +143,7 @@ public class PostTool extends ToolBase {
.type(Integer.class)
.desc(
"If recursive then delay will be the wait time between posts.
default: 10 for web, 0 for files")
- .build();
+ .get();
private static final Option TYPE_OPTION =
Option.builder("t")
@@ -151,7 +151,7 @@ public class PostTool extends ToolBase {
.hasArg()
.argName("content-type")
.desc("Specify a specific mimetype to use, such as
application/json.")
- .build();
+ .get();
private static final Option FILE_TYPES_OPTION =
Option.builder("ft")
@@ -159,7 +159,7 @@ public class PostTool extends ToolBase {
.hasArg()
.argName("<type>[,<type>,...]")
.desc("default: " + DEFAULT_FILE_TYPES)
- .build();
+ .get();
private static final Option PARAMS_OPTION =
Option.builder()
@@ -167,21 +167,21 @@ public class PostTool extends ToolBase {
.hasArg()
.argName("<key>=<value>[&<key>=<value>...]")
.desc("Values must be URL-encoded; these pass through to Solr update
request.")
- .build();
+ .get();
private static final Option FORMAT_OPTION =
Option.builder()
.longOpt("format")
.desc(
"sends application/json content as Solr commands to /update
instead of /update/json/docs.")
- .build();
+ .get();
private static final Option DRY_RUN_OPTION =
Option.builder()
.longOpt("dry-run")
.desc(
"Performs a dry run of the posting process without actually
sending documents to Solr. Only works with files mode.")
- .build();
+ .get();
// Input args
int recursive = 0;
@@ -326,16 +326,17 @@ public class PostTool extends ToolBase {
*/
public void execute(String mode) throws SolrServerException, IOException {
final RTimer timer = new RTimer();
- if (PostTool.DATA_MODE_FILES.equals(mode)) {
- doFilesMode();
- } else if (DATA_MODE_ARGS.equals(mode)) {
- doArgsMode(args);
- } else if (PostTool.DATA_MODE_WEB.equals(mode)) {
- doWebMode();
- } else if (DATA_MODE_STDIN.equals(mode)) {
- doStdinMode();
- } else {
- return;
+ switch (mode) {
+ case PostTool.DATA_MODE_FILES -> doFilesMode();
+ case DATA_MODE_ARGS -> doArgsMode(args);
+ case PostTool.DATA_MODE_WEB -> doWebMode();
+ case DATA_MODE_STDIN -> doStdinMode();
+ case null -> {
+ return;
+ }
+ default -> {
+ return;
+ }
}
if (optimize) {
@@ -710,7 +711,7 @@ public class PostTool extends ToolBase {
*/
protected static String computeFullUrl(URL baseUrl, String link)
throws MalformedURLException, URISyntaxException {
- if (link == null || link.length() == 0) {
+ if (link == null || link.isEmpty()) {
return null;
}
if (!link.startsWith("http")) {
@@ -799,7 +800,7 @@ public class PostTool extends ToolBase {
String[] pa = param.split("&");
StringBuilder urlBuilder = new StringBuilder(url);
for (String p : pa) {
- if (p.trim().length() == 0) {
+ if (p.trim().isEmpty()) {
continue;
}
String[] kv = p.split("=");
@@ -1285,7 +1286,9 @@ public class PostTool extends ToolBase {
l = arr[0].trim();
if (l.startsWith(DISALLOW)) {
l = l.substring(DISALLOW.length()).trim();
- if (l.length() == 0) continue;
+ if (l.isEmpty()) {
+ continue;
+ }
disallows.add(l);
}
}
diff --git a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
index b5b21f6450f..b0f5959902f 100644
--- a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
@@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
+import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -71,7 +72,7 @@ public class RunExampleTool extends ToolBase {
.longOpt("no-prompt")
.desc(
"Don't prompt for input; accept all defaults when running
examples that accept user input.")
- .build();
+ .get();
private static final Option PROMPT_INPUTS_OPTION =
Option.builder()
@@ -90,7 +91,7 @@ public class RunExampleTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the example to launch, one of: cloud, techproducts,
schemaless, films.")
- .build();
+ .get();
private static final Option SCRIPT_OPTION =
Option.builder()
@@ -98,7 +99,7 @@ public class RunExampleTool extends ToolBase {
.hasArg()
.argName("PATH")
.desc("Path to the bin/solr script.")
- .build();
+ .get();
private static final Option SERVER_DIR_OPTION =
Option.builder("d")
@@ -107,14 +108,14 @@ public class RunExampleTool extends ToolBase {
.argName("DIR")
.required()
.desc("Path to the Solr server directory.")
- .build();
+ .get();
private static final Option FORCE_OPTION =
Option.builder("f")
.longOpt("force")
.argName("FORCE")
.desc("Force option in case Solr is run as root.")
- .build();
+ .get();
private static final Option EXAMPLE_DIR_OPTION =
Option.builder()
@@ -123,7 +124,7 @@ public class RunExampleTool extends ToolBase {
.argName("DIR")
.desc(
"Path to the Solr example directory; if not provided,
${serverDir}/../example is expected to exist.")
- .build();
+ .get();
private static final Option SOLR_HOME_OPTION =
Option.builder()
@@ -133,7 +134,7 @@ public class RunExampleTool extends ToolBase {
.required(false)
.desc(
"Path to the Solr home directory; if not provided,
${serverDir}/solr is expected to exist.")
- .build();
+ .get();
private static final Option URL_SCHEME_OPTION =
Option.builder()
@@ -141,7 +142,7 @@ public class RunExampleTool extends ToolBase {
.hasArg()
.argName("SCHEME")
.desc("Solr URL scheme: http or https, defaults to http if not
specified.")
- .build();
+ .get();
private static final Option PORT_OPTION =
Option.builder("p")
@@ -149,7 +150,7 @@ public class RunExampleTool extends ToolBase {
.hasArg()
.argName("PORT")
.desc("Specify the port to start the Solr HTTP listener on; default
is 8983.")
- .build();
+ .get();
private static final Option HOST_OPTION =
Option.builder()
@@ -157,10 +158,10 @@ public class RunExampleTool extends ToolBase {
.hasArg()
.argName("HOSTNAME")
.desc("Specify the hostname for this Solr instance.")
- .build();
+ .get();
private static final Option USER_MANAGED_OPTION =
- Option.builder().longOpt("user-managed").desc("Start Solr in User
Managed mode.").build();
+ Option.builder().longOpt("user-managed").desc("Start Solr in User
Managed mode.").get();
private static final Option MEMORY_OPTION =
Option.builder("m")
@@ -169,7 +170,7 @@ public class RunExampleTool extends ToolBase {
.argName("MEM")
.desc(
"Sets the min (-Xms) and max (-Xmx) heap size for the JVM, such
as: -m 4g results in: -Xms4g -Xmx4g; by default, this script sets the heap size
to 512m.")
- .build();
+ .get();
private static final Option JVM_OPTS_OPTION =
Option.builder()
@@ -177,7 +178,7 @@ public class RunExampleTool extends ToolBase {
.hasArg()
.argName("OPTS")
.desc("Additional options to be passed to the JVM when starting
example Solr server(s).")
- .build();
+ .get();
protected InputStream userInput;
protected Executor executor;
@@ -195,7 +196,7 @@ public class RunExampleTool extends ToolBase {
public RunExampleTool(Executor executor, InputStream userInput, ToolRuntime
runtime) {
super(runtime);
- this.executor = (executor != null) ? executor : new DefaultExecutor();
+ this.executor = (executor != null) ? executor : new
DefaultExecutor.Builder<>().get();
this.userInput = userInput;
}
@@ -421,85 +422,90 @@ public class RunExampleTool extends ToolBase {
SolrCLI.postJsonToSolr(
solrClient,
"/" + collectionName + "/schema",
- "{\n"
- + " \"add-field-type\" : {\n"
- + " \"name\":\"knn_vector_10\",\n"
- + " \"class\":\"solr.DenseVectorField\",\n"
- + " \"vectorDimension\":10,\n"
- + " \"similarityFunction\":cosine\n"
- + " \"knnAlgorithm\":hnsw\n"
- + " }\n"
- + " }");
+ """
+ {
+ "add-field-type" : {
+ "name":"knn_vector_10",
+ "class":"solr.DenseVectorField",
+ "vectorDimension":10,
+ "similarityFunction":"cosine",
+ "knnAlgorithm":"hnsw"
+ }
+ }
+ """);
echo(
"Adding name, genre, directed_by, initial_release_date, and
film_vector fields to films schema");
SolrCLI.postJsonToSolr(
solrClient,
"/" + collectionName + "/schema",
- "{\n"
- + " \"add-field\" : {\n"
- + " \"name\":\"name\",\n"
- + " \"type\":\"text_general\",\n"
- + " \"multiValued\":false,\n"
- + " \"stored\":true\n"
- + " },\n"
- + " \"add-field\" : {\n"
- + " \"name\":\"genre\",\n"
- + " \"type\":\"text_general\",\n"
- + " \"multiValued\":true,\n"
- + " \"stored\":true\n"
- + " },\n"
- + " \"add-field\" : {\n"
- + " \"name\":\"directed_by\",\n"
- + " \"type\":\"text_general\",\n"
- + " \"multiValued\":true,\n"
- + " \"stored\":true\n"
- + " },\n"
- + " \"add-field\" : {\n"
- + " \"name\":\"initial_release_date\",\n"
- + " \"type\":\"pdate\",\n"
- + " \"stored\":true\n"
- + " },\n"
- + " \"add-field\" : {\n"
- + " \"name\":\"film_vector\",\n"
- + " \"type\":\"knn_vector_10\",\n"
- + " \"indexed\":true\n"
- + " \"stored\":true\n"
- + " },\n"
- + " \"add-copy-field\" : {\n"
- + " \"source\":\"genre\",\n"
- + " \"dest\":\"_text_\"\n"
- + " },\n"
- + " \"add-copy-field\" : {\n"
- + " \"source\":\"name\",\n"
- + " \"dest\":\"_text_\"\n"
- + " },\n"
- + " \"add-copy-field\" : {\n"
- + " \"source\":\"directed_by\",\n"
- + " \"dest\":\"_text_\"\n"
- + " }\n"
- + " }");
+ """
+ {
+ "add-field" : {
+ "name":"name",
+ "type":"text_general",
+ "multiValued":false,
+ "stored":true
+ },
+ "add-field" : {
+ "name":"genre",
+ "type":"text_general",
+ "multiValued":true,
+ "stored":true
+ },
+ "add-field" : {
+ "name":"directed_by",
+ "type":"text_general",
+ "multiValued":true,
+ "stored":true
+ },
+ "add-field" : {
+ "name":"initial_release_date",
+ "type":"pdate",
+ "stored":true
+ },
+ "add-field" : {
+ "name":"film_vector",
+ "type":"knn_vector_10",
+ "indexed":true,
+ "stored":true
+ },
+ "add-copy-field" : {
+ "source":"genre",
+ "dest":"_text_"
+ },
+ "add-copy-field" : {
+ "source":"name",
+ "dest":"_text_"
+ },
+ "add-copy-field" : {
+ "source":"directed_by",
+ "dest":"_text_"
+ }
+ }""");
echo(
"Adding paramsets \"algo\" and \"algo_b\" to films configuration
for relevancy tuning");
SolrCLI.postJsonToSolr(
solrClient,
"/" + collectionName + "/config/params",
- "{\n"
- + " \"set\": {\n"
- + " \"algo_a\":{\n"
- + " \"defType\":\"dismax\",\n"
- + " \"qf\":\"name\"\n"
- + " }\n"
- + " },\n"
- + " \"set\": {\n"
- + " \"algo_b\":{\n"
- + " \"defType\":\"dismax\",\n"
- + " \"qf\":\"name\",\n"
- + " \"mm\":\"100%\"\n"
- + " }\n"
- + " }\n"
- + " }\n");
+ """
+ {
+ "set": {
+ "algo_a":{
+ "defType":"dismax",
+ "qf":"name"
+ }
+ },
+ "set": {
+ "algo_b":{
+ "defType":"dismax",
+ "qf":"name",
+ "mm":"100%"
+ }
+ }
+ }
+ """);
Path filmsJsonFile =
this.exampleDir.resolve("films").resolve("films.json");
echo("Indexing films example docs from " +
filmsJsonFile.toAbsolutePath());
@@ -668,22 +674,26 @@ public class RunExampleTool extends ToolBase {
protected void waitToSeeLiveNodes(String zkHost, int numNodes) {
try (CloudSolrClient cloudClient =
new CloudSolrClient.Builder(Collections.singletonList(zkHost),
Optional.empty()).build()) {
- cloudClient.connect();
Set<String> liveNodes = cloudClient.getClusterState().getLiveNodes();
int numLiveNodes = (liveNodes != null) ? liveNodes.size() : 0;
- long timeout = System.nanoTime() + TimeUnit.NANOSECONDS.convert(10,
TimeUnit.SECONDS);
- while (System.nanoTime() < timeout && numLiveNodes < numNodes) {
+ long timeoutNanos = System.nanoTime() + TimeUnit.NANOSECONDS.convert(10,
TimeUnit.SECONDS);
+ long pollIntervalMs = 2000;
+
+ while (System.nanoTime() < timeoutNanos && numLiveNodes < numNodes) {
echo(
"\nWaiting up to "
+ 10
+ " seconds to see "
+ (numNodes - numLiveNodes)
+ " more nodes join the SolrCloud cluster ...");
+
try {
- Thread.sleep(2000);
+ TimeUnit.MILLISECONDS.sleep(pollIntervalMs);
} catch (InterruptedException ie) {
- Thread.interrupted();
+ Thread.currentThread().interrupt();
+ break;
}
+
liveNodes = cloudClient.getClusterState().getLiveNodes();
numLiveNodes = (liveNodes != null) ? liveNodes.size() : 0;
}
@@ -770,13 +780,13 @@ public class RunExampleTool extends ToolBase {
String.format(
Locale.ROOT, "%s://%s:%d/solr", urlScheme, (host != null ? host :
"localhost"), port);
- String credentials = null; // for now we don't need it for example tool.
But we should.
+ String credentials = null; // for now, we don't need it for example tool.
But we should.
Map<String, Object> nodeStatus = checkPortConflict(solrUrl, credentials,
solrHomeDir, port);
if (nodeStatus != null)
return nodeStatus; // the server they are trying to start is already
running
- int code = 0;
+ int code;
if (isWindows) {
// On Windows, the execution doesn't return, so we have to execute async
// and when calling the script, it seems to be inheriting the
environment that launched this
@@ -810,10 +820,10 @@ public class RunExampleTool extends ToolBase {
executor.execute(startCmd, startEnv, handler);
// wait for execution.
try {
- handler.waitFor(3000);
+ handler.waitFor(Duration.ofSeconds(3));
} catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
// safe to ignore ...
- Thread.interrupted();
}
if (handler.hasResult() && handler.getExitValue() != 0) {
startCmdStr += jvmOptsArg;
@@ -1070,7 +1080,7 @@ public class RunExampleTool extends ToolBase {
protected boolean isPortAvailable(int port) {
try (Socket s = new Socket("localhost", port)) {
- assert s != null; // To allow compilation..
+ assert s != null; // To allow compilation.
return false;
} catch (IOException e) {
return true;
diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java
b/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java
index 30e8b27c3d6..dfc39bf7cb2 100644
--- a/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/SnapshotCreateTool.java
@@ -33,7 +33,7 @@ public class SnapshotCreateTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of collection to be snapshot.")
- .build();
+ .get();
private static final Option SNAPSHOT_NAME_OPTION =
Option.builder()
@@ -42,7 +42,7 @@ public class SnapshotCreateTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the snapshot to produce")
- .build();
+ .get();
public SnapshotCreateTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java
b/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java
index bd9e6aeeb05..00b5c3c0197 100644
--- a/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/SnapshotDeleteTool.java
@@ -33,7 +33,7 @@ public class SnapshotDeleteTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of collection to manage.")
- .build();
+ .get();
private static final Option SNAPSHOT_NAME_OPTION =
Option.builder()
@@ -42,7 +42,7 @@ public class SnapshotDeleteTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the snapshot to delete")
- .build();
+ .get();
public SnapshotDeleteTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java
b/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java
index 6e6fef8f0e8..477ad265e7d 100644
--- a/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/SnapshotDescribeTool.java
@@ -43,7 +43,7 @@ public class SnapshotDescribeTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of collection to be snapshot.")
- .build();
+ .get();
private static final Option SNAPSHOT_NAME_OPTION =
Option.builder()
@@ -52,7 +52,7 @@ public class SnapshotDescribeTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the snapshot to describe")
- .build();
+ .get();
public SnapshotDescribeTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java
b/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java
index ea47d1b2a31..d71b8df8b1a 100644
--- a/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/SnapshotExportTool.java
@@ -16,7 +16,6 @@
*/
package org.apache.solr.cli;
-import java.util.Optional;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
@@ -34,7 +33,7 @@ public class SnapshotExportTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of collection to be snapshot.")
- .build();
+ .get();
private static final Option SNAPSHOT_NAME_OPTION =
Option.builder()
@@ -43,7 +42,7 @@ public class SnapshotExportTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of the snapshot to be exported.")
- .build();
+ .get();
private static final Option DEST_DIR_OPTION =
Option.builder()
@@ -52,7 +51,7 @@ public class SnapshotExportTool extends ToolBase {
.argName("DIR")
.required()
.desc("Path of a temporary directory on local filesystem during
snapshot export command.")
- .build();
+ .get();
private static final Option BACKUP_REPO_NAME_OPTION =
Option.builder()
@@ -61,7 +60,7 @@ public class SnapshotExportTool extends ToolBase {
.argName("DIR")
.desc(
"Specifies name of the backup repository to be used during
snapshot export preparation.")
- .build();
+ .get();
private static final Option ASYNC_ID_OPTION =
Option.builder()
@@ -70,7 +69,7 @@ public class SnapshotExportTool extends ToolBase {
.argName("ID")
.desc(
"Specifies the async request identifier to be used during
snapshot export preparation.")
- .build();
+ .get();
public SnapshotExportTool(ToolRuntime runtime) {
super(runtime);
@@ -98,8 +97,8 @@ public class SnapshotExportTool extends ToolBase {
String snapshotName = cli.getOptionValue(SNAPSHOT_NAME_OPTION);
String collectionName = cli.getOptionValue(COLLECTION_NAME_OPTION);
String destDir = cli.getOptionValue(DEST_DIR_OPTION);
- Optional<String> backupRepo =
Optional.ofNullable(cli.getOptionValue(BACKUP_REPO_NAME_OPTION));
- Optional<String> asyncReqId =
Optional.ofNullable(cli.getOptionValue(ASYNC_ID_OPTION));
+ String backupRepo = cli.getOptionValue(BACKUP_REPO_NAME_OPTION);
+ String asyncReqId = cli.getOptionValue(ASYNC_ID_OPTION);
try (var solrClient = CLIUtils.getSolrClient(cli)) {
exportSnapshot(solrClient, collectionName, snapshotName, destDir,
backupRepo, asyncReqId);
@@ -111,19 +110,19 @@ public class SnapshotExportTool extends ToolBase {
String collectionName,
String snapshotName,
String destPath,
- Optional<String> backupRepo,
- Optional<String> asyncReqId) {
+ String backupRepo,
+ String asyncReqId) {
try {
CollectionAdminRequest.Backup backup =
new CollectionAdminRequest.Backup(collectionName, snapshotName);
backup.setCommitName(snapshotName);
backup.setIndexBackupStrategy(CollectionAdminParams.COPY_FILES_STRATEGY);
backup.setLocation(destPath);
- if (backupRepo.isPresent()) {
- backup.setRepositoryName(backupRepo.get());
+ if (backupRepo != null) {
+ backup.setRepositoryName(backupRepo);
}
// if asyncId is null, processAsync will block and throw an Exception
with any error
- backup.processAsync(asyncReqId.orElse(null), solrClient);
+ backup.processAsync(asyncReqId, solrClient);
} catch (Exception e) {
throw new IllegalStateException(
"Failed to backup collection meta-data for collection "
diff --git a/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java
b/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java
index be40d0361f6..4501fddc839 100644
--- a/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/SnapshotListTool.java
@@ -35,7 +35,7 @@ public class SnapshotListTool extends ToolBase {
.argName("NAME")
.required()
.desc("Name of collection to list snapshots for.")
- .build();
+ .get();
public SnapshotListTool(ToolRuntime runtime) {
super(runtime);
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 e6a16b3a6e9..2db5bee9263 100755
--- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
@@ -17,6 +17,7 @@
package org.apache.solr.cli;
import com.google.common.annotations.VisibleForTesting;
+import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.net.URI;
import java.net.URL;
@@ -34,14 +35,16 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.help.HelpFormatter;
+import org.apache.commons.cli.help.TextHelpAppendable;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.common.util.ContentStreamBase;
import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SuppressForbidden;
import org.apache.solr.util.configuration.SSLConfigurationsFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,7 +59,7 @@ public class SolrCLI implements CLIO {
ToolRuntime runtime = new DefaultToolRuntime();
final boolean hasNoCommand =
- args == null || args.length == 0 || args[0] == null ||
args[0].trim().length() == 0;
+ args == null || args.length == 0 || args[0] == null ||
args[0].trim().isEmpty();
final boolean isHelpCommand = !hasNoCommand && Arrays.asList("-h",
"--help").contains(args[0]);
if (hasNoCommand || isHelpCommand) {
@@ -118,7 +121,7 @@ public class SolrCLI implements CLIO {
return newTool(toolType, runtime);
}
- public static CommandLine parseCmdLine(Tool tool, String[] args) {
+ public static CommandLine parseCmdLine(Tool tool, String[] args) throws
IOException {
// the parser doesn't like -D props
List<String> toolArgList = new ArrayList<>();
List<String> dashDList = new ArrayList<>();
@@ -249,7 +252,7 @@ public class SolrCLI implements CLIO {
}
/** Parses the command-line arguments passed by the user. */
- public static CommandLine processCommandLineArgs(Tool tool, String[] args) {
+ public static CommandLine processCommandLineArgs(Tool tool, String[] args)
throws IOException {
Options options = tool.getOptions();
ToolRuntime runtime = tool.getRuntime();
@@ -258,7 +261,7 @@ public class SolrCLI implements CLIO {
cli =
DefaultParser.builder()
.setDeprecatedHandler(SolrCLI::deprecatedHandlerStdErr)
- .build()
+ .get()
.parse(options, args);
} catch (ParseException exp) {
// Check if we passed in a help argument with a non parsing set of
arguments.
@@ -290,7 +293,7 @@ public class SolrCLI implements CLIO {
}
/** Prints tool help for a given tool */
- public static void printToolHelp(Tool tool) {
+ public static void printToolHelp(Tool tool) throws IOException {
HelpFormatter formatter = getFormatter();
Options nonDeprecatedOptions = new Options();
@@ -308,10 +311,38 @@ public class SolrCLI implements CLIO {
autoGenerateUsage);
}
+ @SuppressForbidden(reason = "System.out for formatting")
public static HelpFormatter getFormatter() {
- HelpFormatter formatter = HelpFormatter.builder().get();
- formatter.setWidth(120);
- return formatter;
+ TextHelpAppendable helpAppendable =
+ new TextHelpAppendable(System.out) {
+ @Override
+ public void appendTable(org.apache.commons.cli.help.TableDefinition
table)
+ throws IOException {
+ if (table == null) {
+ return;
+ }
+ // Create a new TableDefinition with empty headers to suppress the
header row
+ java.util.List<String> emptyHeaders =
+ java.util.Collections.nCopies(table.headers().size(), "");
+ org.apache.commons.cli.help.TableDefinition noHeaderTable =
+ org.apache.commons.cli.help.TableDefinition.from(
+ table.caption(), table.columnTextStyles(), emptyHeaders,
table.rows());
+ super.appendTable(noHeaderTable);
+ }
+
+ @Override
+ public void appendParagraph(CharSequence paragraph) throws
IOException {
+ String text = paragraph.toString().stripTrailing();
+ if (!text.isEmpty()) {
+ super.append(text);
+ super.append("\n");
+ }
+ }
+ };
+ helpAppendable.setMaxWidth(120);
+ helpAppendable.setIndent(0);
+ helpAppendable.setLeftPad(0);
+ return
HelpFormatter.builder().setHelpAppendable(helpAppendable).setShowSince(false).get();
}
/** Scans Jar files on the classpath for Tool implementations to activate. */
diff --git a/solr/core/src/java/org/apache/solr/cli/SolrProcessManager.java
b/solr/core/src/java/org/apache/solr/cli/SolrProcessManager.java
index 5dfdad3a5f8..67146509da5 100644
--- a/solr/core/src/java/org/apache/solr/cli/SolrProcessManager.java
+++ b/solr/core/src/java/org/apache/solr/cli/SolrProcessManager.java
@@ -117,15 +117,15 @@ public class SolrProcessManager {
try (Stream<Path> pidFiles =
Files.list(pidDir)
.filter(p ->
pidFilePattern.matcher(p.getFileName().toString()).matches())) {
- for (Path p : pidFiles.collect(Collectors.toList())) {
+ for (Path p : pidFiles.toList()) {
Optional<SolrProcess> process;
if (p.toString().endsWith(".port")) {
// On Windows, the file is a 'PORT' file containing the port number.
- Integer port = Integer.valueOf(Files.readAllLines(p).get(0));
+ Integer port = Integer.valueOf(Files.readAllLines(p).getFirst());
process = processForPort(port);
} else {
// On Linux, the file is a 'PID' file containing the process ID.
- Long pid = Long.valueOf(Files.readAllLines(p).get(0));
+ Long pid = Long.valueOf(Files.readAllLines(p).getFirst());
process = getProcessForPid(pid);
}
if (process.isPresent()) {
@@ -159,7 +159,7 @@ public class SolrProcessManager {
}
/**
- * Gets the command line of a process as a string. For Windows we need to
fetch command lines
+ * Gets the command line of a process as a string. For Windows, we need to
fetch command lines
* using a PowerShell command.
*
* @param ph the process handle
@@ -238,28 +238,7 @@ public class SolrProcessManager {
}
/** Represents a running Solr process */
- public static class SolrProcess {
- private final long pid;
- private final int port;
- private final boolean isHttps;
-
- public SolrProcess(long pid, int port, boolean isHttps) {
- this.pid = pid;
- this.port = port;
- this.isHttps = isHttps;
- }
-
- public long getPid() {
- return pid;
- }
-
- public int getPort() {
- return port;
- }
-
- public boolean isHttps() {
- return isHttps;
- }
+ public record SolrProcess(long pid, int port, boolean isHttps) {
public String getLocalUrl() {
return String.format(Locale.ROOT, "%s://localhost:%s/solr", isHttps ?
"https" : "http", port);
diff --git a/solr/core/src/java/org/apache/solr/cli/StatusTool.java
b/solr/core/src/java/org/apache/solr/cli/StatusTool.java
index 9fee5940a17..1783e1bef1d 100644
--- a/solr/core/src/java/org/apache/solr/cli/StatusTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/StatusTool.java
@@ -54,7 +54,7 @@ public class StatusTool extends ToolBase {
.type(Integer.class)
.deprecated() // Will make it a stealth option, not printed or
complained about
.desc("Wait up to the specified number of seconds to see Solr
running.")
- .build();
+ .get();
public static final Option PORT_OPTION =
Option.builder("p")
@@ -63,14 +63,14 @@ public class StatusTool extends ToolBase {
.argName("PORT")
.type(Integer.class)
.desc("Port on localhost to check status for")
- .build();
+ .get();
public static final Option SHORT_OPTION =
Option.builder()
.longOpt("short")
.argName("SHORT")
.desc("Short format. Prints one URL per line for running instances")
- .build();
+ .get();
private final SolrProcessManager processMgr;
@@ -172,8 +172,8 @@ public class StatusTool extends ToolBase {
String.format(
Locale.ROOT,
"\nSolr process %s running on port %s",
- process.getPid(),
- process.getPort()));
+ process.pid(),
+ process.port()));
printStatusFromRunningSolr(pidUrl, cli);
}
}
@@ -291,8 +291,7 @@ public class StatusTool extends ToolBase {
public Map<String, Object> getStatus(String solrUrl, String credentials)
throws Exception {
try (var solrClient = CLIUtils.getSolrClient(solrUrl, credentials)) {
- Map<String, Object> status = reportStatus(solrClient);
- return status;
+ return reportStatus(solrClient);
}
}
diff --git a/solr/core/src/java/org/apache/solr/cli/StreamTool.java
b/solr/core/src/java/org/apache/solr/cli/StreamTool.java
index 651eee6cc7b..61d95c79d41 100644
--- a/solr/core/src/java/org/apache/solr/cli/StreamTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/StreamTool.java
@@ -72,8 +72,10 @@ public class StreamTool extends ToolBase {
@Override
public String getUsage() {
// Specify that the last argument is the streaming expression
- return "bin/solr stream [--array-delimiter <CHARACTER>] [-c <NAME>]
[--delimiter <CHARACTER>] [--execution <ENVIRONMENT>] [--fields\n"
- + " <FIELDS>] [-h] [--header] [-s <HOST>] [-u <credentials>]
[-v] [-z <HOST>] <streaming expression OR stream_file.expr>\n";
+ return """
+ bin/solr stream [--array-delimiter <CHARACTER>] [-c <NAME>]
[--delimiter <CHARACTER>] [--execution <ENVIRONMENT>] [--fields
+ <FIELDS>] [-h] [--header] [-s <HOST>] [-u <credentials>] [-v]
[-z <HOST>] <streaming expression OR stream_file.expr>
+ """;
}
private static final Option EXECUTION_OPTION =
@@ -83,7 +85,7 @@ public class StreamTool extends ToolBase {
.argName("ENVIRONMENT")
.desc(
"Execution environment is either 'local' (i.e CLI process) or
via a 'remote' Solr server. Default environment is 'remote'.")
- .build();
+ .get();
private static final Option COLLECTION_OPTION =
Option.builder("c")
@@ -92,7 +94,7 @@ public class StreamTool extends ToolBase {
.hasArg()
.desc(
"Name of the specific collection to execute expression on if the
execution is set to 'remote'. Required for 'remote' execution environment.")
- .build();
+ .get();
private static final Option FIELDS_OPTION =
Option.builder()
@@ -101,10 +103,10 @@ public class StreamTool extends ToolBase {
.hasArg()
.desc(
"The fields in the tuples to output. Defaults to fields in the
first tuple of result set.")
- .build();
+ .get();
private static final Option HEADER_OPTION =
- Option.builder().longOpt("header").desc("Specify to include a header
line.").build();
+ Option.builder().longOpt("header").desc("Specify to include a header
line.").get();
private static final Option DELIMITER_OPTION =
Option.builder()
@@ -112,14 +114,14 @@ public class StreamTool extends ToolBase {
.argName("CHARACTER")
.hasArg()
.desc("The output delimiter. Default to using three spaces.")
- .build();
+ .get();
private static final Option ARRAY_DELIMITER_OPTION =
Option.builder()
.longOpt("array-delimiter")
.argName("CHARACTER")
.hasArg()
.desc("The delimiter multi-valued fields. Default to using a pipe
(|) delimiter.")
- .build();
+ .get();
@Override
public Options getOptions() {
@@ -268,6 +270,7 @@ public class StreamTool extends ToolBase {
Lang.register(streamFactory);
+ assert streamExpression != null;
stream = streamFactory.constructStream(streamExpression);
pushBackStream = new PushBackStream(stream);
@@ -467,7 +470,7 @@ public class StreamTool extends ToolBase {
static String listToString(List values, String internalDelim) {
StringBuilder buf = new StringBuilder();
for (Object value : values) {
- if (buf.length() > 0) {
+ if (!buf.isEmpty()) {
buf.append(internalDelim);
}
@@ -504,7 +507,7 @@ public class StreamTool extends ToolBase {
// Substitute parameters
- if (line.length() > 0) {
+ if (!line.isEmpty()) {
for (int i = 1; i < args.length; i++) {
String arg = args[i];
line = line.replace("$" + i, arg);
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
index 09ebe88cf94..4bf9a266315 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkCpTool.java
@@ -48,7 +48,7 @@ public class ZkCpTool extends ToolBase {
.hasArg()
.argName("DIR")
.desc("Required to look up configuration for compressing
state.json.")
- .build();
+ .get();
public ZkCpTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
index dc0a4076e59..2a644f2a136 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkMkrootTool.java
@@ -35,7 +35,7 @@ public class ZkMkrootTool extends ToolBase {
.longOpt("fail-on-exists")
.hasArg()
.desc("Raise an error if the root exists. Defaults to false.")
- .build();
+ .get();
public ZkMkrootTool(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
b/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
index 64155413e0a..92e6b4daaa4 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkRmTool.java
@@ -67,7 +67,7 @@ public class ZkRmTool extends ToolBase {
}
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ...");
try (SolrZkClient zkClient = CLIUtils.getSolrZkClient(cli, zkHost)) {
- if (!recursive && zkClient.getChildren(znode, null).size() != 0) {
+ if (!recursive && !zkClient.getChildren(znode, null).isEmpty()) {
throw new SolrServerException(
"ZooKeeper node " + znode + " has children and recursive has NOT
been specified.");
}
diff --git a/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
b/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
index 93c1672de48..84f0040ae23 100644
--- a/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
+++ b/solr/core/src/java/org/apache/solr/cli/ZkToolHelp.java
@@ -29,13 +29,13 @@ public class ZkToolHelp extends ToolBase {
Option.builder()
.longOpt("print-zk-subcommand-usage")
.desc("Reminds user to prepend zk to invoke the command.")
- .build();
+ .get();
private static final Option PRINT_LONG_ZK_USAGE_OPTION =
Option.builder()
.longOpt("print-long-zk-usage")
.desc("Invokes the detailed help for zk commands.")
- .build();
+ .get();
public ZkToolHelp(ToolRuntime runtime) {
super(runtime);
diff --git a/solr/core/src/test/org/apache/solr/cli/ApiToolTest.java
b/solr/core/src/test/org/apache/solr/cli/ApiToolTest.java
index c1ebe13af0e..6893e51dc22 100644
--- a/solr/core/src/test/org/apache/solr/cli/ApiToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/ApiToolTest.java
@@ -102,7 +102,7 @@ public class ApiToolTest extends SolrCloudTestCase {
}
@Test
- public void testSolrUrlParsing() throws Exception {
+ public void testSolrUrlParsing() {
assertEquals(
"https://test-host.solr:8983/solr",
ApiTool.getSolrUrlFromUri(URI.create("https://test-host.solr:8983/solr")));
diff --git a/solr/core/src/test/org/apache/solr/cli/CLITestHelper.java
b/solr/core/src/test/org/apache/solr/cli/CLITestHelper.java
index f1701ef9c2a..9c2cd4afb2f 100644
--- a/solr/core/src/test/org/apache/solr/cli/CLITestHelper.java
+++ b/solr/core/src/test/org/apache/solr/cli/CLITestHelper.java
@@ -108,6 +108,7 @@ public class CLITestHelper {
}
printer.flush();
+ assert writer != null;
writer.getBuffer().setLength(0);
}
@@ -117,6 +118,7 @@ public class CLITestHelper {
}
printer.flush();
+ assert writer != null;
return writer.toString();
}
@@ -125,6 +127,7 @@ public class CLITestHelper {
fail("TestingRuntime was created without capturing output");
}
+ assert writer != null;
return new StringReader(writer.toString());
}
diff --git a/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
b/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
index 268c532f71b..dc9e7226dfb 100644
--- a/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
@@ -76,9 +76,10 @@ public class PostToolTest extends SolrCloudTestCase {
Path jsonDoc = Files.createTempFile("temp", ".json");
- BufferedWriter fw = Files.newBufferedWriter(jsonDoc,
StandardCharsets.UTF_8);
- Utils.writeJson(Map.of("id", "1", "title_s", "mytitle"), fw, true);
- fw.flush();
+ try (BufferedWriter fw = Files.newBufferedWriter(jsonDoc,
StandardCharsets.UTF_8)) {
+ Utils.writeJson(Map.of("id", "1", "title_s", "mytitle"), fw, true);
+ fw.flush();
+ }
String[] args = {
"post",
@@ -120,9 +121,10 @@ public class PostToolTest extends SolrCloudTestCase {
Path jsonDoc = Files.createTempFile("temp", ".json");
- BufferedWriter fw = Files.newBufferedWriter(jsonDoc,
StandardCharsets.UTF_8);
- Utils.writeJson(Map.of("id", "1", "title_s", "mytitle"), fw, true);
- fw.flush();
+ try (BufferedWriter fw = Files.newBufferedWriter(jsonDoc,
StandardCharsets.UTF_8)) {
+ Utils.writeJson(Map.of("id", "1", "title_s", "mytitle"), fw, true);
+ fw.flush();
+ }
String[] args = {
"post", "-c", collection, "--credentials", SecurityJson.USER_PASS,
jsonDoc.toString(),
@@ -403,11 +405,13 @@ public class PostToolTest extends SolrCloudTestCase {
// Simulate a robots.txt file with comments and a few disallows
String sb =
- "# Comments appear after the \"#\" symbol at the start of a line, or
after a directive\n"
- + "User-agent: * # match all bots\n"
- + "Disallow: # This is void\n"
- + "Disallow: /disallow # Disallow this path\n"
- + "Disallow: /nonexistentpath # Disallow this path\n";
+ """
+ # Comments appear after the "#" symbol at the start of a line,
or after a directive
+ User-agent: * # match all bots
+ Disallow: # This is void
+ Disallow: /disallow # Disallow this path
+ Disallow: /nonexistentpath # Disallow this path
+ """;
this.robotsCache.put(
"[ff01::114]",
super.parseRobotsTxt(new
ByteArrayInputStream(sb.getBytes(StandardCharsets.UTF_8))));
diff --git a/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
b/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
index 9124fd2b16a..bd8f8a8a151 100644
--- a/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/SolrCLIZkToolsTest.java
@@ -576,7 +576,7 @@ public class SolrCLIZkToolsTest extends SolrCloudTestCase {
assertNotEquals("Should fail when trying to remove /.", 0, res);
}
- // Check that all children of fileRoot are children of zkRoot and vice-versa
+ // Check that all children of fileRoot are children of zkRoot and vice versa
private void verifyZkLocalPathsMatch(Path fileRoot, String zkRoot)
throws IOException, KeeperException, InterruptedException {
verifyAllFilesAreZNodes(fileRoot, zkRoot);
diff --git a/solr/core/src/test/org/apache/solr/cli/SolrProcessManagerTest.java
b/solr/core/src/test/org/apache/solr/cli/SolrProcessManagerTest.java
index e1bb9d51cd0..2102e1e3d75 100644
--- a/solr/core/src/test/org/apache/solr/cli/SolrProcessManagerTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/SolrProcessManagerTest.java
@@ -79,13 +79,15 @@ public class SolrProcessManagerTest extends SolrTestCase {
}
}
+ @SuppressWarnings("SystemGetProperty")
private static Pair<Integer, Process> createProcess(int port, boolean https)
throws IOException {
// Get the path to the java executable from the current JVM
+
+ String pathSeparator = System.getProperty("path.separator");
String classPath =
- Arrays.stream(
-
System.getProperty("java.class.path").split(System.getProperty("path.separator")))
+
Arrays.stream(System.getProperty("java.class.path").split(pathSeparator))
.filter(p -> p.contains("solr") && p.contains("core") &&
p.contains("build"))
- .collect(Collectors.joining(System.getProperty("path.separator")));
+ .collect(Collectors.joining(pathSeparator));
ProcessBuilder processBuilder =
new ProcessBuilder(
@@ -115,7 +117,7 @@ public class SolrProcessManagerTest extends SolrTestCase {
.forEach(
p ->
assertEquals(
- (p.isHttps() ? "https" : "http") + "://localhost:" +
p.getPort() + "/solr",
+ (p.isHttps() ? "https" : "http") + "://localhost:" +
p.port() + "/solr",
p.getLocalUrl()));
}
@@ -134,22 +136,19 @@ public class SolrProcessManagerTest extends SolrTestCase {
public void testProcessForPort() {
assertEquals(
processHttp.getKey().intValue(),
-
(solrProcessManager.processForPort(processHttp.getKey()).orElseThrow().getPort()));
+
(solrProcessManager.processForPort(processHttp.getKey()).orElseThrow().port()));
assertEquals(
processHttps.getKey().intValue(),
-
(solrProcessManager.processForPort(processHttps.getKey()).orElseThrow().getPort()));
+
(solrProcessManager.processForPort(processHttps.getKey()).orElseThrow().port()));
}
public void testGetProcessForPid() {
assertEquals(
processHttp.getValue().pid(),
-
(solrProcessManager.getProcessForPid(processHttp.getValue().pid()).orElseThrow().getPid()));
+
(solrProcessManager.getProcessForPid(processHttp.getValue().pid()).orElseThrow().pid()));
assertEquals(
processHttps.getValue().pid(),
- (solrProcessManager
- .getProcessForPid(processHttps.getValue().pid())
- .orElseThrow()
- .getPid()));
+
(solrProcessManager.getProcessForPid(processHttps.getValue().pid()).orElseThrow().pid()));
}
public void testScanSolrPidFiles() throws IOException {
@@ -164,14 +163,14 @@ public class SolrProcessManagerTest extends SolrTestCase {
public void testSolrProcessMethods() {
SolrProcess http =
solrProcessManager.processForPort(processHttp.getKey()).orElseThrow();
- assertEquals(processHttp.getValue().pid(), http.getPid());
- assertEquals(processHttp.getKey().intValue(), http.getPort());
+ assertEquals(processHttp.getValue().pid(), http.pid());
+ assertEquals(processHttp.getKey().intValue(), http.port());
assertFalse(http.isHttps());
assertEquals("http://localhost:" + processHttp.getKey() + "/solr",
http.getLocalUrl());
SolrProcess https =
solrProcessManager.processForPort(processHttps.getKey()).orElseThrow();
- assertEquals(processHttps.getValue().pid(), https.getPid());
- assertEquals(processHttps.getKey().intValue(), https.getPort());
+ assertEquals(processHttps.getValue().pid(), https.pid());
+ assertEquals(processHttps.getKey().intValue(), https.port());
assertTrue(https.isHttps());
assertEquals("https://localhost:" + processHttps.getKey() + "/solr",
https.getLocalUrl());
}
@@ -187,7 +186,7 @@ public class SolrProcessManagerTest extends SolrTestCase {
/**
* This class is started as new java process by {@link
SolrProcessManagerTest#createProcess}, and
- * it listens to a HTTP(s) port to simulate a real Solr process.
+ * it listens to an HTTP(s) port to simulate a real Solr process.
*/
@SuppressWarnings("NewClassNamingConvention")
public static class MockSolrProcess {
diff --git a/solr/core/src/test/org/apache/solr/cli/StreamToolTest.java
b/solr/core/src/test/org/apache/solr/cli/StreamToolTest.java
index 497b005ad71..5d60662189e 100644
--- a/solr/core/src/test/org/apache/solr/cli/StreamToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/StreamToolTest.java
@@ -19,6 +19,7 @@ package org.apache.solr.cli;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.StringReader;
@@ -69,7 +70,7 @@ public class StreamToolTest extends SolrCloudTestCase {
}
@Test
- public void testGetOutputFields() {
+ public void testGetOutputFields() throws IOException {
String[] args =
new String[] {
"--fields", "field9, field2, field3, field4",
diff --git a/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
b/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
index 8a2d605640b..ef6b20853d7 100644
--- a/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
+++ b/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
@@ -292,7 +292,7 @@ public class TestExportTool extends SolrCloudTestCase {
private void assertJavabinDocsCount(ExportTool.Info info, int expected)
throws IOException {
assertTrue(
- "" + info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
+ info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
try (FileInputStream fis = new FileInputStream(info.out)) {
int[] count = new int[] {0};
FastInputStream in = FastInputStream.wrap(fis);
@@ -309,14 +309,14 @@ public class TestExportTool extends SolrCloudTestCase {
private void assertJsonDocsCount(ExportTool.Info info, int expected) {
assertTrue(
- "" + info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
+ info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
}
private void assertJsonDocsCount(
ExportTool.Info info, int expected, Predicate<Map<String, Object>>
predicate)
throws IOException {
assertTrue(
- "" + info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
+ info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
JsonRecordReader jsonReader;
Reader rdr;
@@ -342,7 +342,7 @@ public class TestExportTool extends SolrCloudTestCase {
ExportTool.Info info, int expected, Predicate<Map<String, Object>>
predicate)
throws IOException {
assertTrue(
- "" + info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
+ info.docsWritten.get() + " expected " + expected,
info.docsWritten.get() >= expected);
JsonRecordReader jsonReader;
Reader rdr;
diff --git a/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
b/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
index 298bbfb0644..4e6c0fecf4c 100644
--- a/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
+++ b/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
@@ -32,6 +32,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteResultHandler;
@@ -71,6 +72,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
* Overrides the call to exec bin/solr to start Solr nodes to start them
using the Solr
* test-framework instead of the script, since the script depends on a full
build.
*/
+ @SuppressWarnings("deprecation") // Using DefaultExecutor for test mocking
purposes
private static class RunExampleExecutor extends DefaultExecutor implements
Closeable {
private final List<CommandLine> commandsExecuted = new ArrayList<>();
@@ -212,20 +214,18 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4
{
standaloneSolr = new JettySolrRunner(solrHomeDir.toString(), port);
Thread bg =
- new Thread() {
- @Override
- public void run() {
- try {
- standaloneSolr.start();
- } catch (Exception e) {
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- } else {
- throw new RuntimeException(e);
+ new Thread(
+ () -> {
+ try {
+ standaloneSolr.start();
+ } catch (Exception e) {
+ if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ } else {
+ throw new RuntimeException(e);
+ }
}
- }
- }
- };
+ });
bg.start();
return 0;
@@ -245,7 +245,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
"Missing required arg "
+ arg
+ " needed to execute command: "
- + commandsExecuted.get(commandsExecuted.size() - 1));
+ + commandsExecuted.getLast());
}
protected boolean hasFlag(String flag, String[] args) {
@@ -323,7 +323,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
for (int pass = 0; pass < 2; pass++) {
// need a port to start the example server on
- int bindPort = -1;
+ int bindPort;
try (ServerSocket socket = new ServerSocket(0)) {
bindPort = socket.getLocalPort();
}
@@ -386,11 +386,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
// brief wait in case of timing issue in getting the new docs
committed
log.warn(
"Going to wait for 1 second before re-trying query for
techproduct example docs ...");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ignore) {
- Thread.interrupted();
- }
+ TimeUnit.MILLISECONDS.sleep(1000);
numFound = solrClient.query(query).getResults().getNumFound();
}
assertEquals(
@@ -433,7 +429,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
"--example-dir", solrExampleDir.toString()
};
- int bindPort = -1;
+ int bindPort;
try (ServerSocket socket = new ServerSocket(0)) {
bindPort = socket.getLocalPort();
}
@@ -481,7 +477,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
// index some docs - to verify all is good for both shards
try (CloudSolrClient cloudClient =
- new RandomizingCloudSolrClientBuilder(
+ new RandomizingCloudHttp2SolrClientBuilder(
Collections.singletonList(executor.solrCloudCluster.getZkServer().getZkAddress()),
Optional.empty())
.withDefaultCollection(collectionName)
@@ -645,7 +641,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
Path solrServerDir = solrHomeDir.getParent();
// need a port to start the example server on
- int bindPort = -1;
+ int bindPort;
try (ServerSocket socket = new ServerSocket(0)) {
bindPort = socket.getLocalPort();
}
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 14c286862b0..5ddd4f4048b 100644
--- a/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/ZkSubcommandsTest.java
@@ -18,7 +18,6 @@ package org.apache.solr.cli;
import java.io.BufferedWriter;
import java.io.IOException;
-import java.io.PrintStream;
import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -34,8 +33,8 @@ import org.apache.solr.cloud.ZkConfigSetService;
import org.apache.solr.cloud.ZkTestServer;
import org.apache.solr.common.cloud.ClusterProperties;
import org.apache.solr.common.cloud.DigestZkACLProvider;
+import org.apache.solr.common.cloud.DigestZkCredentialsProvider;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider;
import org.apache.solr.common.cloud.VMParamsZkCredentialsInjector;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -56,8 +55,6 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
private SolrZkClient zkClient;
- private PrintStream originalSystemOut;
-
protected static final Path SOLR_HOME = SolrTestCaseJ4.TEST_HOME();
@BeforeClass
@@ -75,14 +72,12 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
String solrHome = createTempDir().toString();
System.setProperty("solr.home", solrHome);
- originalSystemOut = System.out;
-
Path zkDir = createTempDir().resolve("zookeeper/server1/data");
+
log.info("ZooKeeper dataDir:{}", zkDir);
zkServer = new ZkTestServer(zkDir);
zkServer.run();
System.setProperty("zkHost", zkServer.getZkAddress());
- // zkClient.close();
zkClient =
new SolrZkClient.Builder()
@@ -162,8 +157,8 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
dataBytes = data.getBytes(StandardCharsets.UTF_8);
expected = zLibCompressor.compressBytes(dataBytes);
- byte[] fromLoca = new
ZLibCompressor().compressBytes(Files.readAllBytes(localFile));
- assertArrayEquals("Should get back what we put in ZK", fromLoca, expected);
+ byte[] fromLocal = new
ZLibCompressor().compressBytes(Files.readAllBytes(localFile));
+ assertArrayEquals("Should get back what we put in ZK", fromLocal,
expected);
args =
new String[] {"cp", "-z", zkServer.getZkAddress(),
localFile.toString(), "zk:/state.json"};
@@ -258,7 +253,7 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
assertArrayEquals(
"Should get back an uncompressed version what we put in ZK",
fileBytes, fromZk);
- // Lets do it again
+ // Let's do it again
assertEquals(0, CLITestHelper.runTool(args, ZkCpTool.class));
locFile = SOLR_HOME.resolve("solr-stress-new.xml");
@@ -552,21 +547,18 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
@Test
public void testUpdateAcls() throws Exception {
+ System.setProperty(
+ SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME,
+ DigestZkCredentialsProvider.class.getName());
System.setProperty(
SolrZkClient.ZK_ACL_PROVIDER_CLASS_NAME_VM_PARAM_NAME,
DigestZkACLProvider.class.getName());
+ System.setProperty(
+ SolrZkClient.ZK_CREDENTIALS_INJECTOR_CLASS_NAME_VM_PARAM_NAME,
+ VMParamsZkCredentialsInjector.class.getName());
System.setProperty(
VMParamsZkCredentialsInjector.DEFAULT_DIGEST_READONLY_USERNAME_VM_PARAM_NAME,
"user");
System.setProperty(
VMParamsZkCredentialsInjector.DEFAULT_DIGEST_READONLY_PASSWORD_VM_PARAM_NAME,
"pass");
- System.setProperty(
- SolrZkClient.ZK_ACL_PROVIDER_CLASS_NAME_VM_PARAM_NAME,
- VMParamsAllAndReadonlyDigestZkACLProvider.class.getName());
- System.setProperty(
-
VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_USERNAME_VM_PARAM_NAME,
- "user");
- System.setProperty(
-
VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_PASSWORD_VM_PARAM_NAME,
- "pass");
String[] args = new String[] {"updateacls", "/", "-z",
zkServer.getZkAddress()};
assertEquals(0, CLITestHelper.runTool(args, UpdateACLTool.class));
@@ -593,7 +585,6 @@ public class ZkSubcommandsTest extends SolrTestCaseJ4 {
if (zkServer != null) {
zkServer.shutdown();
}
- System.setOut(originalSystemOut);
super.tearDown();
}
}