From 6d167b1b2fcff15800b6f9ffc39172f67d8bc87c Mon Sep 17 00:00:00 2001 From: Andrey Bozhko Date: Tue, 26 Nov 2024 12:32:19 -0600 Subject: [PATCH] SOLR-16903: Update CLI tools to use java.nio.file.Path instead of java.io.File (#2883) --- solr/CHANGES.txt | 2 + .../java/org/apache/solr/cli/AuthTool.java | 33 ++-- .../java/org/apache/solr/cli/ExportTool.java | 3 +- .../java/org/apache/solr/cli/PostTool.java | 134 ++++++++------- .../org/apache/solr/cli/RunExampleTool.java | 156 +++++++++--------- .../src/java/org/apache/solr/cli/SolrCLI.java | 13 +- .../org/apache/solr/cli/PostToolTest.java | 10 +- 7 files changed, 187 insertions(+), 164 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 28660398656..840de727b00 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -128,6 +128,8 @@ Other Changes * SOLR-17321: Minimum Java version for Apache Solr is now 21, and for SolrJ, it is 17. (Sanjay Dutt, David Smiley) +* SOLR-16903: Update CLI tools to use java.nio.file.Path instead of java.io.File (Andrey Bozhko) + ================== 9.8.0 ================== New Features --------------------- 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 45b609a2943..d5cc2c69b22 100644 --- a/solr/core/src/java/org/apache/solr/cli/AuthTool.java +++ b/solr/core/src/java/org/apache/solr/cli/AuthTool.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.Console; -import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.net.URL; @@ -250,8 +249,8 @@ private void handleKerberos(CommandLine cli) throws Exception { config = config.replace("\n", "").replace("\r", ""); String solrIncludeFilename = cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION); - File includeFile = new File(solrIncludeFilename); - if (!includeFile.exists() || !includeFile.canWrite()) { + 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(config); @@ -259,7 +258,7 @@ private void handleKerberos(CommandLine cli) throws Exception { } // update the solr.in.sh file to contain the necessary authentication lines - updateIncludeFileEnableAuth(includeFile.toPath(), null, config); + updateIncludeFileEnableAuth(includeFile, null, config); echo( "Successfully enabled Kerberos authentication; please restart any running Solr nodes."); return; @@ -267,8 +266,8 @@ private void handleKerberos(CommandLine cli) throws Exception { clearSecurityJson(cli, updateIncludeFileOnly); solrIncludeFilename = cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION); - includeFile = new File(solrIncludeFilename); - if (!includeFile.exists() || !includeFile.canWrite()) { + 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( @@ -277,7 +276,7 @@ private void handleKerberos(CommandLine cli) throws Exception { } // update the solr.in.sh file to comment out the necessary authentication lines - updateIncludeFileDisableAuth(includeFile.toPath()); + updateIncludeFileDisableAuth(includeFile); return; default: CLIO.out("Valid auth commands are: enable, disable."); @@ -387,30 +386,30 @@ private void handleBasicAuth(CommandLine cli) throws Exception { } String solrIncludeFilename = cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION); - File includeFile = new File(solrIncludeFilename); - if (!includeFile.exists() || !includeFile.canWrite()) { + 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); System.exit(0); } String authConfDir = cli.getOptionValue(AUTH_CONF_DIR_OPTION); - File basicAuthConfFile = new File(authConfDir + File.separator + "basicAuth.conf"); + Path basicAuthConfFile = Path.of(authConfDir, "basicAuth.conf"); - if (!basicAuthConfFile.getParentFile().canWrite()) { - CLIO.out("Cannot write to file: " + basicAuthConfFile.getAbsolutePath()); + if (!Files.isWritable(basicAuthConfFile.getParent())) { + CLIO.out("Cannot write to file: " + basicAuthConfFile.toAbsolutePath()); printAuthEnablingInstructions(username, password); System.exit(0); } Files.writeString( - basicAuthConfFile.toPath(), + basicAuthConfFile, "httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" + password, StandardCharsets.UTF_8); // update the solr.in.sh file to contain the necessary authentication lines updateIncludeFileEnableAuth( - includeFile.toPath(), basicAuthConfFile.getAbsolutePath(), null); + includeFile, basicAuthConfFile.toAbsolutePath().toString(), null); final String successMessage = String.format( Locale.ROOT, @@ -423,8 +422,8 @@ private void handleBasicAuth(CommandLine cli) throws Exception { clearSecurityJson(cli, updateIncludeFileOnly); solrIncludeFilename = cli.getOptionValue(SOLR_INCLUDE_FILE_OPTION); - includeFile = new File(solrIncludeFilename); - if (!includeFile.exists() || !includeFile.canWrite()) { + 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( @@ -433,7 +432,7 @@ private void handleBasicAuth(CommandLine cli) throws Exception { } // update the solr.in.sh file to comment out the necessary authentication lines - updateIncludeFileDisableAuth(includeFile.toPath()); + updateIncludeFileDisableAuth(includeFile); return; default: CLIO.out("Valid auth commands are: enable, disable."); 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 24e7ee15ce0..59bca949dc1 100644 --- a/solr/core/src/java/org/apache/solr/cli/ExportTool.java +++ b/solr/core/src/java/org/apache/solr/cli/ExportTool.java @@ -25,7 +25,6 @@ import static org.apache.solr.common.util.JavaBinCodec.SOLRINPUTDOC; import java.io.BufferedOutputStream; -import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -599,7 +598,7 @@ void exportDocs() throws Exception { consumerThreadpool.shutdownNow(); if (failed) { try { - Files.delete(new File(out).toPath()); + Files.delete(Path.of(out)); } catch (IOException e) { // ignore } 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 f6bc4b811f0..5ec8eb3eb7e 100644 --- a/solr/core/src/java/org/apache/solr/cli/PostTool.java +++ b/solr/core/src/java/org/apache/solr/cli/PostTool.java @@ -22,9 +22,6 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -41,10 +38,12 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.security.GeneralSecurityException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Base64; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -54,8 +53,11 @@ import java.util.Map; import java.util.Set; import java.util.TimeZone; +import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.GZIPInputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; @@ -202,7 +204,7 @@ public class PostTool extends ToolBase { private int currentDepth; static HashMap mimeMap; - FileFilter fileFilter; + Predicate fileFilter; // Backlog for crawling List> backlog = new ArrayList<>(); Set visited = new HashSet<>(); @@ -350,7 +352,7 @@ public void execute(String mode) throws SolrServerException, IOException { displayTiming((long) timer.getTime()); } - private void doFilesMode() { + private void doFilesMode() throws IOException { currentDepth = 0; info( @@ -434,8 +436,16 @@ private void displayTiming(long millis) { CLIO.out("Time spent: " + df.format(new Date(millis))); } - private boolean checkIsValidPath(File srcFile) { - return Files.exists(srcFile.toPath()); + private boolean checkIsValidPath(Path srcFile) { + return Files.exists(srcFile); + } + + private static Collection listFiles(Path directory, Predicate fileFilter) + throws IOException { + Predicate filter = fileFilter != null ? fileFilter : p -> true; + try (Stream directoryFiles = Files.list(directory)) { + return directoryFiles.filter(filter).collect(Collectors.toList()); + } } /** @@ -448,8 +458,8 @@ private boolean checkIsValidPath(File srcFile) { boolean recursionPossible(String[] args) { boolean recursionPossible = false; for (String arg : args) { - File f = new File(arg); - if (f.isDirectory()) { + Path f = Path.of(arg); + if (Files.isDirectory(f)) { recursionPossible = true; } } @@ -464,26 +474,29 @@ boolean recursionPossible(String[] args) { * @param out output stream to post data to * @param type default content-type to use when posting (this may be overridden in auto mode) * @return number of files posted + * @throws IOException if an I/O error occurs */ - public int postFiles(String[] args, int startIndexInArgs, OutputStream out, String type) { + public int postFiles(String[] args, int startIndexInArgs, OutputStream out, String type) + throws IOException { reset(); int filesPosted = 0; for (int j = startIndexInArgs; j < args.length; j++) { - File srcFile = new File(args[j]); - filesPosted = getFilesPosted(out, type, srcFile); + filesPosted = getFilesPosted(out, type, args[j]); } return filesPosted; } - private int getFilesPosted(final OutputStream out, final String type, final File srcFile) { + private int getFilesPosted(final OutputStream out, final String type, final String src) + throws IOException { int filesPosted = 0; + Path srcFile = Path.of(src).toAbsolutePath(); boolean isValidPath = checkIsValidPath(srcFile); - if (isValidPath && srcFile.isDirectory() && srcFile.canRead()) { + if (isValidPath && Files.isDirectory(srcFile) && Files.isReadable(srcFile)) { filesPosted += postDirectory(srcFile, out, type); - } else if (isValidPath && srcFile.isFile() && srcFile.canRead()) { - filesPosted += postFiles(new File[] {srcFile}, out, type); + } else if (isValidPath && Files.isRegularFile(srcFile) && Files.isReadable(srcFile)) { + filesPosted += postFiles(List.of(srcFile), out, type); } else { - filesPosted += handleGlob(srcFile, out, type); + filesPosted += handleGlob(src, out, type); } return filesPosted; } @@ -493,42 +506,40 @@ private int getFilesPosted(final OutputStream out, final String type, final File * * @return number of files posted total */ - private int postDirectory(File dir, OutputStream out, String type) { - if (dir.isHidden() && !dir.getName().equals(".")) { - return (0); + private int postDirectory(Path dir, OutputStream out, String type) throws IOException { + if (Files.isHidden(dir) && !dir.getFileName().toString().equals(".")) { + return 0; } info( "Indexing directory " - + dir.getPath() + + dir + " (" - + dir.listFiles(fileFilter).length + + listFiles(dir, fileFilter).size() + " files, depth=" + currentDepth + ")"); int posted = 0; - posted += postFiles(dir.listFiles(fileFilter), out, type); + posted += postFiles(listFiles(dir, fileFilter), out, type); if (recursive > currentDepth) { - for (File d : dir.listFiles()) { - if (d.isDirectory()) { - currentDepth++; - posted += postDirectory(d, out, type); - currentDepth--; - } + for (Path d : listFiles(dir, Files::isDirectory)) { + currentDepth++; + posted += postDirectory(d, out, type); + currentDepth--; } } return posted; } /** - * Posts a list of file names + * Posts a collection of files identified by their paths * * @return number of files posted */ - int postFiles(File[] files, OutputStream out, String type) { + int postFiles(Collection files, OutputStream out, String type) throws IOException { int filesPosted = 0; - for (File srcFile : files) { + for (Path srcFile : files) { try { - if (!srcFile.isFile() || srcFile.isHidden()) { + if (!Files.isRegularFile(srcFile) || Files.isHidden(srcFile)) { continue; } postFile(srcFile, out, type); @@ -544,22 +555,24 @@ int postFiles(File[] files, OutputStream out, String type) { /** * This only handles file globs not full path globbing. * - * @param globFile file holding glob path + * @param globPathPattern glob pattern * @param out outputStream to write results to * @param type default content-type to use when posting (this may be overridden in auto mode) * @return number of files posted + * @throws IOException if an I/O error occurs */ - int handleGlob(File globFile, OutputStream out, String type) { + int handleGlob(String globPathPattern, OutputStream out, String type) throws IOException { int filesPosted = 0; - File parent = globFile.getParentFile(); + Path globPath = Path.of(globPathPattern); + Path parent = globPath.getParent(); if (parent == null) { - parent = new File("."); + parent = Path.of("."); } - String fileGlob = globFile.getName(); - PostTool.GlobFileFilter ff = new PostTool.GlobFileFilter(fileGlob, false); - File[] fileList = parent.listFiles(ff); - if (fileList == null || fileList.length == 0) { - warn("No files or directories matching " + globFile); + String fileGlob = globPath.getFileName().toString(); + GlobFilter ff = new GlobFilter(fileGlob, false); + Collection fileList = listFiles(parent, ff); + if (fileList.isEmpty()) { + warn("No files or directories matching " + globPath); } else { filesPosted = postFiles(fileList, out, type); } @@ -810,7 +823,7 @@ public static String appendParam(String url, String param) { } /** Opens the file and posts its contents to the solrUrl, writes to response to output. */ - public void postFile(File file, OutputStream output, String type) + public void postFile(Path file, OutputStream output, String type) throws MalformedURLException, URISyntaxException { InputStream is = null; @@ -838,11 +851,14 @@ public void postFile(File file, OutputStream output, String type) if (!urlStr.contains("resource.name")) { urlStr = appendParam( - urlStr, "resource.name=" + URLEncoder.encode(file.getAbsolutePath(), UTF_8)); + urlStr, + "resource.name=" + URLEncoder.encode(file.toAbsolutePath().toString(), UTF_8)); } if (!urlStr.contains("literal.id")) { urlStr = - appendParam(urlStr, "literal.id=" + URLEncoder.encode(file.getAbsolutePath(), UTF_8)); + appendParam( + urlStr, + "literal.id=" + URLEncoder.encode(file.toAbsolutePath().toString(), UTF_8)); } uri = new URI(urlStr); } @@ -854,7 +870,7 @@ public void postFile(File file, OutputStream output, String type) if (dryRun) { info( "DRY RUN of POSTing file " - + file.getName() + + file.getFileName() + (auto ? " (" + type + ")" : "") + " to [base]" + suffix); @@ -862,12 +878,12 @@ public void postFile(File file, OutputStream output, String type) try { info( "POSTing file " - + file.getName() + + file.getFileName() + (auto ? " (" + type + ")" : "") + " to [base]" + suffix); - is = new FileInputStream(file); - postData(is, file.length(), output, type, uri); + is = Files.newInputStream(file); + postData(is, Files.size(file), output, type, uri); } catch (IOException e) { warn("Can't open/read file: " + file); } finally { @@ -909,11 +925,11 @@ protected static URI appendUrlPath(URI uri, String append) { * Guesses the type of file, based on file name suffix Returns "application/octet-stream" if no * corresponding mimeMap type. * - * @param file the file + * @param path path to the file * @return the content-type guessed */ - protected static String guessType(File file) { - String name = file.getName(); + protected static String guessType(Path path) { + String name = path.getFileName().toString(); String suffix = name.substring(name.lastIndexOf('.') + 1); String type = mimeMap.get(suffix.toLowerCase(Locale.ROOT)); return (type != null) ? type : "application/octet-stream"; @@ -930,7 +946,7 @@ public boolean postData( return true; } - if (params.length() > 0) { + if (!params.isEmpty()) { try { uri = new URI(appendParam(uri.toString(), params)); } catch (URISyntaxException e) { @@ -1078,14 +1094,14 @@ private static void pipe(InputStream source, OutputStream dest) throws IOExcepti dest.flush(); } - public FileFilter getFileFilterFromFileTypes(String fileTypes) { + public Predicate getFileFilterFromFileTypes(String fileTypes) { String glob; if (fileTypes.equals("*")) { glob = ".*"; } else { glob = "^.*\\.(" + fileTypes.replace(",", "|") + ")$"; } - return new PostTool.GlobFileFilter(glob, true); + return new GlobFilter(glob, true); } // @@ -1131,10 +1147,10 @@ public static Document makeDom(byte[] in) } /** Inner class to filter files based on glob wildcards */ - static class GlobFileFilter implements FileFilter { + static class GlobFilter implements Predicate { private final Pattern p; - public GlobFileFilter(String pattern, boolean isRegex) { + public GlobFilter(String pattern, boolean isRegex) { String _pattern = pattern; if (!isRegex) { _pattern = @@ -1159,8 +1175,8 @@ public GlobFileFilter(String pattern, boolean isRegex) { } @Override - public boolean accept(File file) { - return p.matcher(file.getName()).find(); + public boolean test(Path path) { + return p.matcher(path.getFileName().toString()).find(); } } 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 4f0346c6079..783d58e0a57 100644 --- a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java +++ b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java @@ -17,7 +17,6 @@ package org.apache.solr.cli; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; @@ -25,6 +24,8 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -43,7 +44,7 @@ import org.apache.commons.exec.Executor; import org.apache.commons.exec.OS; import org.apache.commons.exec.environment.EnvironmentUtils; -import org.apache.commons.io.FileUtils; +import org.apache.commons.io.file.PathUtils; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.common.SolrException; @@ -162,8 +163,8 @@ public class RunExampleTool extends ToolBase { protected InputStream userInput; protected Executor executor; protected String script; - protected File serverDir; - protected File exampleDir; + protected Path serverDir; + protected Path exampleDir; protected String urlScheme; /** Default constructor used by the framework when running as a command-line application. */ @@ -204,26 +205,26 @@ public Options getOptions() { public void runImpl(CommandLine cli) throws Exception { this.urlScheme = cli.getOptionValue(URL_SCHEME_OPTION, "http"); - serverDir = new File(cli.getOptionValue(SERVER_DIR_OPTION)); - if (!serverDir.isDirectory()) + serverDir = Path.of(cli.getOptionValue(SERVER_DIR_OPTION)); + if (!Files.isDirectory(serverDir)) throw new IllegalArgumentException( "Value of --server-dir option is invalid! " - + serverDir.getAbsolutePath() + + serverDir.toAbsolutePath() + " is not a directory!"); script = cli.getOptionValue(SCRIPT_OPTION); if (script != null) { - if (!(new File(script)).isFile()) + if (!Files.isRegularFile(Path.of(script))) throw new IllegalArgumentException( "Value of --script option is invalid! " + script + " not found"); } else { - File scriptFile = new File(serverDir.getParentFile(), "bin/solr"); - if (scriptFile.isFile()) { - script = scriptFile.getAbsolutePath(); + Path scriptFile = serverDir.getParent().resolve("bin").resolve("solr"); + if (Files.isRegularFile(scriptFile)) { + script = scriptFile.toAbsolutePath().toString(); } else { - scriptFile = new File(serverDir.getParentFile(), "bin/solr.cmd"); - if (scriptFile.isFile()) { - script = scriptFile.getAbsolutePath(); + scriptFile = serverDir.getParent().resolve("bin").resolve("solr.cmd"); + if (Files.isRegularFile(scriptFile)) { + script = scriptFile.toAbsolutePath().toString(); } else { throw new IllegalArgumentException( "Cannot locate the bin/solr script! Please pass --script to this application."); @@ -233,19 +234,19 @@ public void runImpl(CommandLine cli) throws Exception { exampleDir = (cli.hasOption(EXAMPLE_DIR_OPTION)) - ? new File(cli.getOptionValue(EXAMPLE_DIR_OPTION)) - : new File(serverDir.getParent(), "example"); - if (!exampleDir.isDirectory()) + ? Path.of(cli.getOptionValue(EXAMPLE_DIR_OPTION)) + : serverDir.getParent().resolve("example"); + if (!Files.isDirectory(exampleDir)) throw new IllegalArgumentException( "Value of --example-dir option is invalid! " - + exampleDir.getAbsolutePath() + + exampleDir.toAbsolutePath() + " is not a directory!"); echoIfVerbose( "Running with\nserverDir=" - + serverDir.getAbsolutePath() + + serverDir.toAbsolutePath() + ",\nexampleDir=" - + exampleDir.getAbsolutePath() + + exampleDir.toAbsolutePath() + "\nscript=" + script); @@ -275,7 +276,7 @@ protected void runExample(CommandLine cli, String exampleName) throws Exception Integer.parseInt( cli.getOptionValue(PORT_OPTION, System.getenv().getOrDefault("SOLR_PORT", "8983"))); Map nodeStatus = - startSolr(new File(serverDir, "solr"), isCloudMode, cli, port, zkHost, 30); + startSolr(serverDir.resolve("solr"), isCloudMode, cli, port, zkHost, 30); String solrUrl = CLIUtils.normalizeSolrUrl((String) nodeStatus.get("baseUrl")); @@ -331,16 +332,16 @@ protected void runExample(CommandLine cli, String exampleName) throws Exception if ("techproducts".equals(exampleName) && !alreadyExists) { - File exampledocsDir = new File(this.exampleDir, "exampledocs"); - if (!exampledocsDir.isDirectory()) { - File readOnlyExampleDir = new File(serverDir.getParentFile(), "example"); - if (readOnlyExampleDir.isDirectory()) { - exampledocsDir = new File(readOnlyExampleDir, "exampledocs"); + Path exampledocsDir = this.exampleDir.resolve("exampledocs"); + if (!Files.isDirectory(exampledocsDir)) { + Path readOnlyExampleDir = serverDir.resolveSibling("example"); + if (Files.isDirectory(readOnlyExampleDir)) { + exampledocsDir = readOnlyExampleDir.resolve("exampledocs"); } } - if (exampledocsDir.isDirectory()) { - echo("Indexing tech product example docs from " + exampledocsDir.getAbsolutePath()); + if (Files.isDirectory(exampledocsDir)) { + echo("Indexing tech product example docs from " + exampledocsDir.toAbsolutePath()); String[] args = new String[] { @@ -351,7 +352,7 @@ protected void runExample(CommandLine cli, String exampleName) throws Exception collectionName, "--type", "application/xml", - exampledocsDir.getAbsolutePath() + "/*.xml" + exampledocsDir.toAbsolutePath() + "/*.xml" }; PostTool postTool = new PostTool(); CommandLine postToolCli = SolrCLI.parseCmdLine(postTool, args); @@ -424,8 +425,8 @@ protected void runExample(CommandLine cli, String exampleName) throws Exception + " }\n" + " }\n"); - File filmsJsonFile = new File(this.exampleDir, "films/films.json"); - echo("Indexing films example docs from " + filmsJsonFile.getAbsolutePath()); + Path filmsJsonFile = this.exampleDir.resolve("films").resolve("films.json"); + echo("Indexing films example docs from " + filmsJsonFile.toAbsolutePath()); String[] args = new String[] { "post", @@ -435,7 +436,7 @@ protected void runExample(CommandLine cli, String exampleName) throws Exception collectionName, "--type", "application/json", - filmsJsonFile.getAbsolutePath() + filmsJsonFile.toAbsolutePath().toString() }; PostTool postTool = new PostTool(); CommandLine postToolCli = SolrCLI.parseCmdLine(postTool, args); @@ -466,12 +467,12 @@ protected void runCloudExample(CommandLine cli) throws Exception { // Override the old default port numbers if user has started the example overriding SOLR_PORT cloudPorts = new int[] {defaultPort, defaultPort + 1, defaultPort + 2, defaultPort + 3}; } - File cloudDir = new File(exampleDir, "cloud"); - if (!cloudDir.isDirectory()) cloudDir.mkdir(); + Path cloudDir = exampleDir.resolve("cloud"); + if (!Files.isDirectory(cloudDir)) Files.createDirectory(cloudDir); echo("\nWelcome to the SolrCloud example!\n"); - Scanner readInput = prompt ? new Scanner(userInput, StandardCharsets.UTF_8.name()) : null; + Scanner readInput = prompt ? new Scanner(userInput, StandardCharsets.UTF_8) : null; if (prompt) { echo( "This interactive session will help you launch a SolrCloud cluster on your local workstation."); @@ -513,14 +514,14 @@ protected void runCloudExample(CommandLine cli) throws Exception { } // setup a unique solr.solr.home directory for each node - File node1Dir = setupExampleDir(serverDir, cloudDir, "node1"); + Path node1Dir = setupExampleDir(serverDir, cloudDir, "node1"); for (int n = 2; n <= numNodes; n++) { - File nodeNDir = new File(cloudDir, "node" + n); - if (!nodeNDir.isDirectory()) { - echo("Cloning " + node1Dir.getAbsolutePath() + " into\n " + nodeNDir.getAbsolutePath()); - FileUtils.copyDirectory(node1Dir, nodeNDir); + Path nodeNDir = cloudDir.resolve("node" + n); + if (!Files.isDirectory(nodeNDir)) { + echo("Cloning " + node1Dir.toAbsolutePath() + " into\n " + nodeNDir.toAbsolutePath()); + PathUtils.copyDirectory(node1Dir, nodeNDir, StandardCopyOption.REPLACE_EXISTING); } else { - echo(nodeNDir.getAbsolutePath() + " already exists."); + echo(nodeNDir.toAbsolutePath() + " already exists."); } } @@ -529,7 +530,7 @@ protected void runCloudExample(CommandLine cli) throws Exception { // start the first node (most likely with embedded ZK) Map nodeStatus = - startSolr(new File(node1Dir, "solr"), true, cli, cloudPorts[0], zkHost, 30); + startSolr(node1Dir.resolve("solr"), true, cli, cloudPorts[0], zkHost, 30); if (zkHost == null) { @SuppressWarnings("unchecked") @@ -546,7 +547,12 @@ protected void runCloudExample(CommandLine cli) throws Exception { // start the other nodes for (int n = 1; n < numNodes; n++) startSolr( - new File(cloudDir, "node" + (n + 1) + "/solr"), true, cli, cloudPorts[n], zkHost, 30); + cloudDir.resolve("node" + (n + 1)).resolve("solr"), + true, + cli, + cloudPorts[n], + zkHost, + 30); } String solrUrl = CLIUtils.normalizeSolrUrl((String) nodeStatus.get("baseUrl"), false); @@ -605,7 +611,7 @@ protected void waitToSeeLiveNodes(String zkHost, int numNodes) { } protected Map startSolr( - File solrHomeDir, + Path solrHomeDir, boolean cloudMode, CommandLine cli, int port, @@ -628,14 +634,14 @@ protected Map startSolr( String jvmOpts = cli.getOptionValue(JVM_OPTS_OPTION); String jvmOptsArg = (jvmOpts != null) ? " --jvm-opts \"" + jvmOpts + "\"" : ""; - File cwd = new File(System.getProperty("user.dir")); - File binDir = (new File(script)).getParentFile(); + Path cwd = Path.of(System.getProperty("user.dir")); + Path binDir = Path.of(script).getParent(); boolean isWindows = (OS.isFamilyDOS() || OS.isFamilyWin9x() || OS.isFamilyWindows()); - String callScript = (!isWindows && cwd.equals(binDir.getParentFile())) ? "bin/solr" : script; + String callScript = (!isWindows && cwd.equals(binDir.getParent())) ? "bin/solr" : script; - String cwdPath = cwd.getAbsolutePath(); - String solrHome = solrHomeDir.getAbsolutePath(); + String cwdPath = cwd.toAbsolutePath().toString(); + String solrHome = solrHomeDir.toAbsolutePath().toString(); // don't display a huge path for solr home if it is relative to the cwd if (!isWindows && cwdPath.length() > 1 && solrHome.startsWith(cwdPath)) @@ -719,7 +725,7 @@ protected Map startSolr( } protected Map checkPortConflict( - String solrUrl, String credentials, File solrHomeDir, int port) { + String solrUrl, String credentials, Path solrHomeDir, int port) { // quickly check if the port is in use if (isPortAvailable(port)) return null; // not in use ... try to start @@ -733,7 +739,7 @@ protected Map checkPortConflict( if (nodeStatus != null) { String solr_home = (String) nodeStatus.get("solr_home"); if (solr_home != null) { - String solrHomePath = solrHomeDir.getAbsolutePath(); + String solrHomePath = solrHomeDir.toAbsolutePath().toString(); if (!solrHomePath.endsWith("/")) solrHomePath += "/"; if (!solr_home.endsWith("/")) solr_home += "/"; @@ -782,7 +788,7 @@ protected String createCloudExampleCollection( String cloudConfig = "_default"; String collectionName = "gettingstarted"; - File configsetsDir = new File(serverDir, "solr/configsets"); + Path configsetsDir = serverDir.resolve("solr").resolve("configsets"); if (prompt) { echo( @@ -885,13 +891,13 @@ protected String createCloudExampleCollection( return collectionName; } - protected boolean isValidConfig(File configsetsDir, String config) { - File configDir = new File(configsetsDir, config); - if (configDir.isDirectory()) return true; + protected boolean isValidConfig(Path configsetsDir, String config) { + Path configDir = configsetsDir.resolve(config); + if (Files.isDirectory(configDir)) return true; // not a built-in configset ... maybe it's a custom directory? - configDir = new File(config); - return configDir.isDirectory(); + configDir = Path.of(config); + return Files.isDirectory(configDir); } protected Map getNodeStatus(String solrUrl, String credentials, int maxWaitSecs) @@ -913,37 +919,37 @@ protected Map getNodeStatus(String solrUrl, String credentials, return nodeStatus; } - protected File setupExampleDir(File serverDir, File exampleParentDir, String dirName) + protected Path setupExampleDir(Path serverDir, Path exampleParentDir, String dirName) throws IOException { - File solrXml = new File(serverDir, "solr/solr.xml"); - if (!solrXml.isFile()) + Path solrXml = serverDir.resolve("solr").resolve("solr.xml"); + if (!Files.isRegularFile(solrXml)) throw new IllegalArgumentException( - "Value of --server-dir option is invalid! " + solrXml.getAbsolutePath() + " not found!"); + "Value of --server-dir option is invalid! " + solrXml.toAbsolutePath() + " not found!"); - File zooCfg = new File(serverDir, "solr/zoo.cfg"); - if (!zooCfg.isFile()) + Path zooCfg = serverDir.resolve("solr").resolve("zoo.cfg"); + if (!Files.isRegularFile(zooCfg)) throw new IllegalArgumentException( - "Value of --server-dir option is invalid! " + zooCfg.getAbsolutePath() + " not found!"); + "Value of --server-dir option is invalid! " + zooCfg.toAbsolutePath() + " not found!"); - File solrHomeDir = new File(exampleParentDir, dirName + "/solr"); - if (!solrHomeDir.isDirectory()) { + Path solrHomeDir = exampleParentDir.resolve(dirName).resolve("solr"); + if (!Files.isDirectory(solrHomeDir)) { echo("Creating Solr home directory " + solrHomeDir); - solrHomeDir.mkdirs(); + Files.createDirectories(solrHomeDir); } else { - echo("Solr home directory " + solrHomeDir.getAbsolutePath() + " already exists."); + echo("Solr home directory " + solrHomeDir.toAbsolutePath() + " already exists."); } - copyIfNeeded(solrXml, new File(solrHomeDir, "solr.xml")); - copyIfNeeded(zooCfg, new File(solrHomeDir, "zoo.cfg")); + copyIfNeeded(solrXml, solrHomeDir.resolve("solr.xml")); + copyIfNeeded(zooCfg, solrHomeDir.resolve("zoo.cfg")); - return solrHomeDir.getParentFile(); + return solrHomeDir.getParent(); } - protected void copyIfNeeded(File src, File dest) throws IOException { - if (!dest.isFile()) Files.copy(src.toPath(), dest.toPath()); + protected void copyIfNeeded(Path src, Path dest) throws IOException { + if (!Files.isRegularFile(dest)) Files.copy(src, dest); - if (!dest.isFile()) - throw new IllegalStateException("Required file " + dest.getAbsolutePath() + " not found!"); + if (!Files.isRegularFile(dest)) + throw new IllegalStateException("Required file " + dest.toAbsolutePath() + " not found!"); } protected boolean isPortAvailable(int port) { 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 15e26ce49c7..e88b0dada7f 100755 --- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java +++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java @@ -17,10 +17,11 @@ package org.apache.solr.cli; import com.google.common.annotations.VisibleForTesting; -import java.io.File; import java.lang.invoke.MethodHandles; import java.net.URI; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; @@ -159,12 +160,12 @@ protected static void checkSslStoreSysProp(String solrInstallDir, String key) { String keyStore = System.getProperty(sysProp); if (keyStore == null) return; - File keyStoreFile = new File(keyStore); - if (keyStoreFile.isFile()) return; // configured setting is OK + Path keyStoreFile = Path.of(keyStore); + if (Files.isRegularFile(keyStoreFile)) return; // configured setting is OK - keyStoreFile = new File(solrInstallDir, "server/" + keyStore); - if (keyStoreFile.isFile()) { - System.setProperty(sysProp, keyStoreFile.getAbsolutePath()); + keyStoreFile = Path.of(solrInstallDir, "server", keyStore); + if (Files.isRegularFile(keyStoreFile)) { + System.setProperty(sysProp, keyStoreFile.toAbsolutePath().toString()); } else { CLIO.err( "WARNING: " 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 ad37f73c318..425c9f495dd 100644 --- a/solr/core/src/test/org/apache/solr/cli/PostToolTest.java +++ b/solr/core/src/test/org/apache/solr/cli/PostToolTest.java @@ -281,15 +281,15 @@ public void testAppendUrlPath() { @Test public void testGuessType() { File f = new File("foo.doc"); - assertEquals("application/msword", PostTool.guessType(f)); + assertEquals("application/msword", PostTool.guessType(f.toPath())); f = new File("foobar"); - assertEquals("application/octet-stream", PostTool.guessType(f)); + assertEquals("application/octet-stream", PostTool.guessType(f.toPath())); f = new File("foo.json"); - assertEquals("application/json", PostTool.guessType(f)); + assertEquals("application/json", PostTool.guessType(f.toPath())); } @Test - public void testDoFilesMode() { + public void testDoFilesMode() throws IOException { PostTool postTool = new PostTool(); postTool.recursive = 0; postTool.dryRun = true; @@ -311,7 +311,7 @@ public void testDetectingIfRecursionPossibleInFilesMode() throws IOException { } @Test - public void testRecursionAppliesToFilesMode() { + public void testRecursionAppliesToFilesMode() throws IOException { PostTool postTool = new PostTool(); postTool.recursive = 1; // This is the default postTool.dryRun = true;