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

jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new ca1f72d  GEODE-5212: Ensure that MergeLogs closes its InputStreams 
(#2513)
ca1f72d is described below

commit ca1f72df06ea7987cdc13ed19b16ee55bafd21f7
Author: Jens Deppe <[email protected]>
AuthorDate: Thu Sep 27 08:30:17 2018 -0700

    GEODE-5212: Ensure that MergeLogs closes its InputStreams (#2513)
    
    - Other refactoring which converted a pair of linked structures (log 
filename
      and the associated InputStream) into a Map.
---
 .../internal/cli/util/MergeLogsDUnitTest.java      |  9 ++++
 .../internal/logging/MergeLogFilesJUnitTest.java   | 12 ++---
 .../apache/geode/admin/internal/LogCollator.java   | 10 ++--
 .../org/apache/geode/internal/SystemAdmin.java     | 56 ++++++++--------------
 .../geode/internal/logging/MergeLogFiles.java      | 56 ++++++++++------------
 .../management/internal/cli/util/MergeLogs.java    | 11 +++--
 6 files changed, 72 insertions(+), 82 deletions(-)

diff --git 
a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDUnitTest.java
 
b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDUnitTest.java
index e6cb601..67b40d3 100644
--- 
a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDUnitTest.java
+++ 
b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDUnitTest.java
@@ -26,8 +26,10 @@ import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Properties;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.io.FileUtils;
+import org.awaitility.Awaitility;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -59,12 +61,19 @@ public class MergeLogsDUnitTest {
     MemberVM server = lsRule.startServerVM(1, properties, locator.getPort());
     MemberVM server2 = lsRule.startServerVM(2, properties, locator.getPort());
 
+    // Especially on Windows, wait for time to pass otherwise all log messages 
may appear in the
+    // same millisecond.
     locator.invoke(() -> LogService.getLogger().info(MESSAGE_1));
+    Awaitility.await().atLeast(1, TimeUnit.MILLISECONDS).until(() -> true);
     server.invoke(() -> LogService.getLogger().info(MESSAGE_2));
+    Awaitility.await().atLeast(1, TimeUnit.MILLISECONDS).until(() -> true);
     server2.invoke(() -> LogService.getLogger().info(MESSAGE_3));
+    Awaitility.await().atLeast(1, TimeUnit.MILLISECONDS).until(() -> true);
 
     locator.invoke(() -> LogService.getLogger().info(MESSAGE_4));
+    Awaitility.await().atLeast(1, TimeUnit.MILLISECONDS).until(() -> true);
     server.invoke(() -> LogService.getLogger().info(MESSAGE_5));
+    Awaitility.await().atLeast(1, TimeUnit.MILLISECONDS).until(() -> true);
     server2.invoke(() -> LogService.getLogger().info(MESSAGE_6));
   }
 
diff --git 
a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesJUnitTest.java
 
b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesJUnitTest.java
index 0228ef3..bf99ea5 100644
--- 
a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesJUnitTest.java
+++ 
b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesJUnitTest.java
@@ -28,8 +28,10 @@ import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -81,20 +83,18 @@ public class MergeLogFilesJUnitTest {
     }
 
     // Merge the log files together
-    InputStream[] streams = new InputStream[workers.size()];
-    String[] names = new String[workers.size()];
+    Map<String, InputStream> logs = new HashMap<>();
     for (int i = 0; i < workers.size(); i++) {
       Worker worker = (Worker) workers.get(i);
-      streams[i] = worker.getInputStream();
-      names[i] = worker.getName();
+      logs.put(worker.getName(), worker.getInputStream());
     }
     StringWriter sw = new StringWriter();
     PrintWriter pw = new PrintWriter(sw, true);
-    MergeLogFiles.mergeLogFiles(streams, names, pw);
+    MergeLogFiles.mergeLogFiles(logs, pw);
 
     // System.out.println(sw.toString());
 
-    // Verfiy that the entries are sorted
+    // Verify that the entries are sorted
     BufferedReader br = new BufferedReader(new StringReader(sw.toString()));
     Pattern pattern = Pattern.compile("^Worker \\d+: .* VALUE: (\\d+)");
     int lastValue = -1;
diff --git 
a/geode-core/src/main/java/org/apache/geode/admin/internal/LogCollator.java 
b/geode-core/src/main/java/org/apache/geode/admin/internal/LogCollator.java
index 4fbf629..f446919 100755
--- a/geode-core/src/main/java/org/apache/geode/admin/internal/LogCollator.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/internal/LogCollator.java
@@ -20,7 +20,9 @@ import java.io.InputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.geode.internal.admin.ApplicationVM;
 import org.apache.geode.internal.admin.GemFireVM;
@@ -54,18 +56,16 @@ public class LogCollator {
 
   private String mergeLogs() {
     // combine logs...
-    InputStream[] logFiles = new InputStream[this.logTails.size()];
-    String[] logFileNames = new String[logFiles.length];
+    Map<String, InputStream> logFiles = new HashMap<>();
     for (int i = 0; i < this.logTails.size(); i++) {
       Loglet loglet = (Loglet) this.logTails.get(i);
-      logFiles[i] = new ByteArrayInputStream(loglet.tail.getBytes());
-      logFileNames[i] = loglet.name;
+      logFiles.put(loglet.name, new 
ByteArrayInputStream(loglet.tail.getBytes()));
     }
 
     // delegate to MergeLogFiles...
     StringWriter writer = new StringWriter();
     PrintWriter mergedLog = new PrintWriter(writer);
-    if (!MergeLogFiles.mergeLogFiles(logFiles, logFileNames, mergedLog)) {
+    if (!MergeLogFiles.mergeLogFiles(logFiles, mergedLog)) {
       return writer.toString();
     } else {
       return "";
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java 
b/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java
index c6d3738..f9d35a9 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java
@@ -26,6 +26,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
@@ -38,6 +39,7 @@ import java.net.SocketException;
 import java.net.URL;
 import java.net.URLDecoder;
 import java.net.UnknownHostException;
+import java.nio.file.Paths;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.ArrayList;
@@ -55,8 +57,11 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import java.util.zip.GZIPInputStream;
 
+import org.apache.commons.lang.StringUtils;
+
 import org.apache.geode.GemFireException;
 import org.apache.geode.GemFireIOException;
 import org.apache.geode.InternalGemFireException;
@@ -783,9 +788,8 @@ public class SystemAdmin {
     }
   }
 
-  public void mergeLogs(String outOption, List args) {
-    FileInputStream[] input = new FileInputStream[args.size()];
-    String[] inputNames = new String[args.size()]; // note we don't want any 
extra names printed.
+  public void mergeLogs(String outOption, List<String> args) {
+    Map<String, InputStream> inputs = new HashMap<>();
 
     PrintStream ps;
     if (outOption != null) {
@@ -801,17 +805,20 @@ public class SystemAdmin {
     }
     PrintWriter mergedFile = new PrintWriter(ps, true);
 
-    Iterator it = args.iterator();
-    int idx = 0;
+    List<String> normalizedFiles =
+        args.stream().map(f -> 
Paths.get(f).toAbsolutePath().toString()).collect(
+            Collectors.toList());
+    int prefixLength =
+        StringUtils.getCommonPrefix(normalizedFiles.toArray(new String[] 
{})).length();
+
     if (!quiet) {
       
ps.println(LocalizedStrings.SystemAdmin_MERGING_THE_FOLLOWING_LOG_FILES.toLocalizedString());
     }
-    while (it.hasNext()) {
-      String fileName = (String) it.next();
+
+    for (String fileName : normalizedFiles) {
       try {
-        input[idx] = new FileInputStream(fileName);
-        inputNames[idx] = (new File(fileName)).getAbsolutePath();
-        idx++;
+        String shortName = fileName.substring(prefixLength);
+        inputs.put(shortName, new FileInputStream(fileName));
       } catch (FileNotFoundException ex) {
         throw new GemFireIOException(
             
LocalizedStrings.SystemAdmin_COULD_NOT_OPEN_TO_0_FOR_READING_BECAUSE_1
@@ -822,31 +829,7 @@ public class SystemAdmin {
       }
     }
 
-    if (idx > 0) {
-      // strip off any common filename prefix
-      boolean strip = true;
-      do {
-        if (inputNames[0].length() == 0) {
-          break;
-        }
-        if (inputNames[0].indexOf('/') == -1 && inputNames[0].indexOf('\\') == 
-1) {
-          // no more directories to strip off
-          break;
-        }
-        char c = inputNames[0].charAt(0);
-        for (int i = 1; i < idx; i++) {
-          if (inputNames[i].charAt(0) != c) {
-            strip = false;
-            break;
-          }
-        }
-        for (int i = 0; i < idx; i++) {
-          inputNames[i] = inputNames[i].substring(1);
-        }
-      } while (strip);
-    }
-
-    if (MergeLogFiles.mergeLogFiles(input, inputNames, mergedFile)) {
+    if (MergeLogFiles.mergeLogFiles(inputs, mergedFile)) {
       throw new GemFireIOException(
           
LocalizedStrings.SystemAdmin_TROUBLE_MERGING_LOG_FILES.toLocalizedString());
     }
@@ -857,7 +840,8 @@ public class SystemAdmin {
     if (!quiet) {
       System.out
           
.println(LocalizedStrings.SystemAdmin_COMPLETED_MERGE_OF_0_LOGS_TO_1.toLocalizedString(
-              new Object[] {Integer.valueOf(idx), ((outOption != null) ? 
outOption : "stdout")}));
+              new Object[] {Integer.valueOf(args.size()),
+                  ((outOption != null) ? outOption : "stdout")}));
     }
   }
 
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/logging/MergeLogFiles.java 
b/geode-core/src/main/java/org/apache/geode/internal/logging/MergeLogFiles.java
index 8918a1d..5f2cdc7 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/logging/MergeLogFiles.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/logging/MergeLogFiles.java
@@ -27,9 +27,11 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.BlockingQueue;
@@ -102,7 +104,6 @@ public class MergeLogFiles {
    * <code>PrinWriter</code>.
    *
    * @param logFiles The log files to be merged
-   * @param logFileNames The names of the log files to be printed in the 
merged log
    * @param mergedFile Where the merged logs are printed to
    *
    * @return Whether or not problems occurred while merging the log files.
@@ -110,9 +111,8 @@ public class MergeLogFiles {
    * @throws IllegalArgumentException If the length of <code>logFiles</code> 
is not the same as the
    *         length of <code>logFileNames</code>
    */
-  public static boolean mergeLogFiles(InputStream[] logFiles, String[] 
logFileNames,
-      PrintWriter mergedFile) {
-    return mergeLogFiles(logFiles, logFileNames, mergedFile, false, false, 
false, new LinkedList());
+  public static boolean mergeLogFiles(Map<String, InputStream> logFiles, 
PrintWriter mergedFile) {
+    return mergeLogFiles(logFiles, mergedFile, false, false, false, new 
LinkedList());
   }
 
   /**
@@ -120,7 +120,6 @@ public class MergeLogFiles {
    * <code>PrinWriter</code>.
    *
    * @param logFiles The log files to be merged
-   * @param logFileNames The names of the log files to be printed in the 
merged log
    * @param mergedFile Where the merged logs are printed to
    * @param tabOut Whether to align non-timestamped lines with timestamped 
lines
    * @param suppressBlanks Whether to omit blank lines
@@ -130,10 +129,10 @@ public class MergeLogFiles {
    * @throws IllegalArgumentException If the length of <code>logFiles</code> 
is not the same as the
    *         length of <code>logFileNames</code>
    */
-  public static boolean mergeLogFiles(InputStream[] logFiles, String[] 
logFileNames,
+  public static boolean mergeLogFiles(Map<String, InputStream> logFiles,
       PrintWriter mergedFile, boolean tabOut, boolean suppressBlanks, boolean 
multithreaded,
       List<String> patterns) {
-    return Sorter.mergeLogFiles(logFiles, logFileNames, mergedFile, tabOut, 
suppressBlanks,
+    return Sorter.mergeLogFiles(logFiles, mergedFile, tabOut, suppressBlanks,
         multithreaded, patterns);
   }
 
@@ -307,17 +306,16 @@ public class MergeLogFiles {
       nickNames = findPIDs(files, mergedFile);
     }
 
-    InputStream[] logFiles = new InputStream[files.size()];
-    String[] logFileNames = new String[files.size()];
+    Map<String, InputStream> logFiles = new HashMap<>();
     for (int i = 0; i < files.size(); i++) {
       File file = (File) files.get(i);
-      logFiles[i] = new FileInputStream(file);
 
+      String logFileName;
       if (findPIDs && (nickNames.get(i) != null)) {
         if (file.getCanonicalPath().toLowerCase().endsWith("gz")) {
-          logFileNames[i] = (String) nickNames.get(i) + ".gz";
+          logFileName = nickNames.get(i) + ".gz";
         } else {
-          logFileNames[i] = (String) nickNames.get(i);
+          logFileName = (String) nickNames.get(i);
         }
       } else {
         StringBuffer sb = new StringBuffer();
@@ -334,11 +332,12 @@ public class MergeLogFiles {
         }
         sb.append(file.getName());
 
-        logFileNames[i] = sb.toString();
+        logFileName = sb.toString();
       }
+      logFiles.put(logFileName, new FileInputStream(file));
     }
 
-    mergeLogFiles(logFiles, logFileNames, mergedFile, tabOut, suppressBlanks, 
multithreaded,
+    mergeLogFiles(logFiles, mergedFile, tabOut, suppressBlanks, multithreaded,
         patterns);
 
     ExitCode.NORMAL.doSystemExit();
@@ -650,7 +649,8 @@ public class MergeLogFiles {
 
     /**
      * Creates a new <code>Reader</code> that reads from the given log file 
with the given name.
-     * Invoking this constructor will start this reader thread.
+     * Invoking this constructor will start this reader thread. The 
InputStream is closed at the
+     * end of processing.
      *
      * @param patterns TODO
      *
@@ -729,6 +729,12 @@ public class MergeLogFiles {
 
       } catch (InterruptedException ex) {
         Thread.currentThread().interrupt();
+      } finally {
+        try {
+          logFile.close();
+        } catch (IOException e) {
+          e.printStackTrace(System.err);
+        }
       }
     }
 
@@ -824,7 +830,6 @@ public class MergeLogFiles {
      * <code>PrintWriter</code>.
      *
      * @param logFiles The log files to be merged
-     * @param logFileNames The names of the log files to be printed in the 
merged log
      * @param mergedFile Where the merged logs are printed to
      * @param tabOut Whether to align non-timestamped lines with others
      * @param suppressBlanks Whether to suppress output of blank lines
@@ -834,16 +839,9 @@ public class MergeLogFiles {
      * @throws IllegalArgumentException If the length of <code>logFiles</code> 
is not the same as
      *         the length of <code>logFileNames</code>
      */
-    public static boolean mergeLogFiles(InputStream[] logFiles, String[] 
logFileNames,
+    public static boolean mergeLogFiles(Map<String, InputStream> logFiles,
         PrintWriter mergedFile, boolean tabOut, boolean suppressBlanks, 
boolean multithreaded,
         List<String> patterns) {
-      if (logFiles.length != logFileNames.length) {
-        throw new IllegalArgumentException(
-            
LocalizedStrings.MergeLogFiles_NUMBER_OF_LOG_FILES_0_IS_NOT_THE_SAME_AS_THE_NUMBER_OF_LOG_FILE_NAMES_1
-                .toLocalizedString(new Object[] 
{Integer.valueOf(logFiles.length),
-                    Integer.valueOf(logFileNames.length)}));
-      }
-
       List<Pattern> compiledPatterns = new LinkedList<Pattern>();
       for (String pattern : patterns) {
         compiledPatterns.add(Pattern.compile(pattern, 
Pattern.CASE_INSENSITIVE));
@@ -852,13 +850,13 @@ public class MergeLogFiles {
       // First start the Reader threads
       ReaderGroup group =
           new 
ReaderGroup(LocalizedStrings.MergeLogFiles_READER_THREADS.toLocalizedString());
-      Collection readers = new ArrayList(logFiles.length);
-      for (int i = 0; i < logFiles.length; i++) {
+      Collection readers = new ArrayList(logFiles.size());
+      for (Map.Entry<String, InputStream> e : logFiles.entrySet()) {
         if (multithreaded) {
-          readers.add(new ThreadedReader(logFiles[i], logFileNames[i], group, 
tabOut,
+          readers.add(new ThreadedReader(e.getValue(), e.getKey(), group, 
tabOut,
               suppressBlanks, compiledPatterns));
         } else {
-          readers.add(new NonThreadedReader(logFiles[i], logFileNames[i], 
group, tabOut,
+          readers.add(new NonThreadedReader(e.getValue(), e.getKey(), group, 
tabOut,
               suppressBlanks, compiledPatterns));
         }
       }
@@ -870,7 +868,6 @@ public class MergeLogFiles {
       Set sorted = sortReaders(readers);
 
       while (!readers.isEmpty()) {
-
         Reader oldest = null;
         Iterator sortedIt = sorted.iterator();
         if (!sortedIt.hasNext()) {
@@ -886,7 +883,6 @@ public class MergeLogFiles {
           nextReaderTimestamp = nextInLine.peek().getTimestamp();
         }
 
-
         // if we've switched to a different reader, emit a blank line
         // for readability
         if (oldest != lastOldest) {
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/MergeLogs.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/MergeLogs.java
index 496d6ed..cc1d838 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/MergeLogs.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/MergeLogs.java
@@ -27,7 +27,9 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.logging.log4j.Logger;
@@ -101,12 +103,11 @@ public class MergeLogs {
   static File mergeLogFile(String dirName) throws Exception {
     Path dir = Paths.get(dirName);
     List<File> logsToMerge = findLogFilesToMerge(dir.toFile());
-    InputStream[] logFiles = new FileInputStream[logsToMerge.size()];
-    String[] logFileNames = new String[logFiles.length];
+    Map<String, InputStream> logFiles = new HashMap<>();
     for (int i = 0; i < logsToMerge.size(); i++) {
       try {
-        logFiles[i] = new FileInputStream(logsToMerge.get(i));
-        logFileNames[i] = 
dir.relativize(logsToMerge.get(i).toPath()).toString();
+        logFiles.put(dir.relativize(logsToMerge.get(i).toPath()).toString(),
+            new FileInputStream(logsToMerge.get(i)));
       } catch (FileNotFoundException e) {
         throw new Exception(
             logsToMerge.get(i) + " " + 
CliStrings.EXPORT_LOGS__MSG__FILE_DOES_NOT_EXIST);
@@ -120,7 +121,7 @@ public class MergeLogs {
           + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new 
java.util.Date()) + ".log";
       mergedLogFile = new File(mergeLog);
       mergedLog = new PrintWriter(mergedLogFile);
-      MergeLogFiles.mergeLogFiles(logFiles, logFileNames, mergedLog);
+      MergeLogFiles.mergeLogFiles(logFiles, mergedLog);
     } catch (FileNotFoundException e) {
       throw new Exception(
           "FileNotFoundException in creating PrintWriter in MergeLogFiles" + 
e.getMessage());

Reply via email to