This is an automated email from the ASF dual-hosted git repository.

cshannon pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/2.1 by this push:
     new 87031e9ac7 Support writing cluster config parser output to a file 
(#3205)
87031e9ac7 is described below

commit 87031e9ac7c1cca75aeda285a2df152fabc75ed8
Author: Christopher L. Shannon <christopher.l.shan...@gmail.com>
AuthorDate: Wed Mar 1 18:20:12 2023 -0500

    Support writing cluster config parser output to a file (#3205)
    
    * This commit adds support to provide an optional argument to
    ClusterConfigParser to write the output to a file instead of System.out
    so that only the output we want is captured and not everything that's
    written to standard out.
    
    * The accumulo-cluster script has also been updated to
    to provide the temp file as an output file argument instead of
    capturing System.out so that there are not parsing errors by the script if
    other output is written to the standard out stream.
---
 assemble/bin/accumulo-cluster                      |  2 +-
 .../core/conf/cluster/ClusterConfigParser.java     | 18 +++++-
 .../core/conf/cluster/ClusterConfigParserTest.java | 68 +++++++++++++++-------
 3 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/assemble/bin/accumulo-cluster b/assemble/bin/accumulo-cluster
index 5bf904b091..3e511dfea2 100755
--- a/assemble/bin/accumulo-cluster
+++ b/assemble/bin/accumulo-cluster
@@ -66,7 +66,7 @@ function parse_config {
 
   trap 'rm -f "$CONFIG_FILE"' EXIT
   CONFIG_FILE=$(mktemp) || exit 1
-  ${accumulo_cmd} org.apache.accumulo.core.conf.cluster.ClusterConfigParser 
"${conf}"/cluster.yaml >"$CONFIG_FILE" || parse_fail
+  ${accumulo_cmd} org.apache.accumulo.core.conf.cluster.ClusterConfigParser 
"${conf}"/cluster.yaml "$CONFIG_FILE" || parse_fail
   #shellcheck source=/dev/null
   . "$CONFIG_FILE"
   rm -f "$CONFIG_FILE"
diff --git 
a/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java
 
b/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java
index ec75fd0e06..de43584de0 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParser.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.conf.cluster;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -135,12 +136,23 @@ public class ClusterConfigParser {
     out.flush();
   }
 
+  @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN",
+      justification = "Path provided for output file is intentional")
   public static void main(String[] args) throws IOException {
-    if (args == null || args.length != 1) {
-      System.err.println("Usage: ClusterConfigParser <configFile>");
+    if (args == null || args.length < 1 || args.length > 2) {
+      System.err.println("Usage: ClusterConfigParser <configFile> 
[<outputFile>]");
       System.exit(1);
     }
-    outputShellVariables(parseConfiguration(args[0]), System.out);
+
+    if (args.length == 2) {
+      // Write to a file instead of System.out if provided as an argument
+      try (OutputStream os = Files.newOutputStream(Paths.get(args[1]), 
StandardOpenOption.CREATE);
+          PrintStream out = new PrintStream(os)) {
+        outputShellVariables(parseConfiguration(args[0]), new 
PrintStream(out));
+      }
+    } else {
+      outputShellVariables(parseConfiguration(args[0]), System.out);
+    }
   }
 
 }
diff --git 
a/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java
 
b/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java
index 8ea7e5a49f..82ca8a41d0 100644
--- 
a/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java
+++ 
b/core/src/test/java/org/apache/accumulo/core/conf/cluster/ClusterConfigParserTest.java
@@ -26,20 +26,26 @@ import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Function;
 
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "paths 
provided by test")
 public class ClusterConfigParserTest {
 
+  @TempDir
+  private static File tempDir;
+
   @Test
   public void testParse() throws Exception {
     URL configFile = ClusterConfigParserTest.class
@@ -109,31 +115,51 @@ public class ClusterConfigParserTest {
   @Test
   public void testShellOutput() throws Exception {
 
-    String userDir = System.getProperty("user.dir");
-    String targetDir = "target";
-    File dir = new File(userDir, targetDir);
-    if (!dir.exists()) {
-      if (!dir.mkdirs()) {
-        fail("Unable to make directory ${user.dir}/target");
+    testShellOutput(configFile -> {
+      try {
+        final Map<String,String> contents =
+            ClusterConfigParser.parseConfiguration(new 
File(configFile.toURI()).getAbsolutePath());
+
+        final File outputFile = new File(tempDir, 
"ClusterConfigParserTest_testShellOutput");
+        if (!outputFile.createNewFile()) {
+          fail("Unable to create file in " + tempDir);
+        }
+        outputFile.deleteOnExit();
+
+        final PrintStream ps = new PrintStream(outputFile);
+        ClusterConfigParser.outputShellVariables(contents, ps);
+        ps.close();
+
+        return outputFile;
+      } catch (Exception e) {
+        throw new RuntimeException(e.getMessage(), e);
       }
-    }
-    File f = new File(dir, "ClusterConfigParserTest_testShellOutput");
-    if (!f.createNewFile()) {
-      fail("Unable to create file in ${user.dir}/target");
-    }
-    f.deleteOnExit();
+    });
+  }
 
-    PrintStream ps = new PrintStream(f);
+  @Test
+  public void testShellOutputMain() throws Exception {
+
+    // Test that the main method in ClusterConfigParser properly parses the 
configuration
+    // and outputs to a given file instead of System.out when provided
+    testShellOutput(configFile -> {
+      try {
+        File outputFile = new File(tempDir, 
"ClusterConfigParserTest_testShellOutputMain");
+        ClusterConfigParser.main(new String[] {configFile.getFile(), 
outputFile.getAbsolutePath()});
+
+        return outputFile;
+      } catch (IOException e) {
+        throw new RuntimeException(e.getMessage(), e);
+      }
+    });
+  }
 
-    URL configFile = ClusterConfigParserTest.class
+  private void testShellOutput(Function<URL,File> outputConfigFunction) throws 
Exception {
+    final URL configFile = ClusterConfigParserTest.class
         .getResource("/org/apache/accumulo/core/conf/cluster/cluster.yaml");
     assertNotNull(configFile);
 
-    Map<String,String> contents =
-        ClusterConfigParser.parseConfiguration(new 
File(configFile.toURI()).getAbsolutePath());
-
-    ClusterConfigParser.outputShellVariables(contents, ps);
-    ps.close();
+    final File f = outputConfigFunction.apply(configFile);
 
     Map<String,String> expected = new HashMap<>();
     expected.put("MANAGER_HOSTS", "localhost1 localhost2");
@@ -143,9 +169,7 @@ public class ClusterConfigParserTest {
     expected.put("NUM_TSERVERS", "${NUM_TSERVERS:=1}");
     expected.put("NUM_SSERVERS", "${NUM_SSERVERS:=1}");
 
-    expected.replaceAll((k, v) -> {
-      return '"' + v + '"';
-    });
+    expected.replaceAll((k, v) -> '"' + v + '"');
 
     Map<String,String> actual = new HashMap<>();
     try (BufferedReader rdr = Files.newBufferedReader(Paths.get(f.toURI()))) {

Reply via email to