You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2013/05/02 18:47:45 UTC

git commit: check outputstream for broken pipe patch by Pawel Mirski; reviewed by jbellis for CASSANDRA-5150

Updated Branches:
  refs/heads/trunk bcd80487a -> b6be6835d


check outputstream for broken pipe
patch by Pawel Mirski; reviewed by jbellis for CASSANDRA-5150


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/b6be6835
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/b6be6835
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/b6be6835

Branch: refs/heads/trunk
Commit: b6be6835d15c1c709d503d7f03aad2355ea60f40
Parents: bcd8048
Author: Jonathan Ellis <jb...@apache.org>
Authored: Thu May 2 11:47:34 2013 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Thu May 2 11:47:45 2013 -0500

----------------------------------------------------------------------
 .../org/apache/cassandra/tools/SSTableExport.java  |   74 +++++++++------
 .../apache/cassandra/tools/SSTableExportTest.java  |   63 ++++++++++++-
 2 files changed, 105 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/b6be6835/src/java/org/apache/cassandra/tools/SSTableExport.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/SSTableExport.java b/src/java/org/apache/cassandra/tools/SSTableExport.java
index e6a06bc..e86b733 100644
--- a/src/java/org/apache/cassandra/tools/SSTableExport.java
+++ b/src/java/org/apache/cassandra/tools/SSTableExport.java
@@ -74,9 +74,20 @@ public class SSTableExport
     }
 
     /**
+     * Checks if PrintStream error and throw exception
+     *
+     * @param out The PrintStream to be check
+     */
+    private static void checkStream(PrintStream out) throws IOException
+    {
+        if (out.checkError())
+            throw new IOException("Error writing output stream");
+    }
+
+    /**
      * JSON Hash Key serializer
      *
-     * @param out The output steam to write data
+     * @param out   The output steam to write data
      * @param value value to set as a key
      */
     private static void writeKey(PrintStream out, String value)
@@ -91,10 +102,8 @@ public class SSTableExport
      * <li>column family deletion info (if present)</li>
      * </ul>
      *
-     * @param out
-     *            The output steam to write data
-     * @param cf
-     *            to which the metadata belongs
+     * @param out The output steam to write data
+     * @param cf  to which the metadata belongs
      */
     private static void writeMeta(PrintStream out, ColumnFamily cf)
     {
@@ -119,8 +128,8 @@ public class SSTableExport
     /**
      * Serialize columns using given column iterator
      *
-     * @param atoms column iterator
-     * @param out output stream
+     * @param atoms      column iterator
+     * @param out        output stream
      * @param comparator columns comparator
      * @param cfMetaData Column Family metadata (to get validator)
      */
@@ -150,12 +159,12 @@ public class SSTableExport
     {
         if (atom instanceof Column)
         {
-            return serializeColumn((Column)atom, comparator, cfMetaData);
+            return serializeColumn((Column) atom, comparator, cfMetaData);
         }
         else
         {
             assert atom instanceof RangeTombstone;
-            RangeTombstone rt = (RangeTombstone)atom;
+            RangeTombstone rt = (RangeTombstone) atom;
             ArrayList<Object> serializedColumn = new ArrayList<Object>();
             serializedColumn.add(comparator.getString(rt.min));
             serializedColumn.add(comparator.getString(rt.max));
@@ -169,10 +178,9 @@ public class SSTableExport
     /**
      * Serialize a given column to the JSON format
      *
-     * @param column column presentation
+     * @param column     column presentation
      * @param comparator columns comparator
      * @param cfMetaData Column Family metadata (to get validator)
-     *
      * @return column as serialized list
      */
     private static List<Object> serializeColumn(Column column, AbstractType<?> comparator, CFMetaData cfMetaData)
@@ -215,6 +223,7 @@ public class SSTableExport
 
     /**
      * Get portion of the columns and serialize in loop while not more columns left in the row
+     *
      * @param row SSTableIdentityIterator row representation with Column Family
      * @param key Decorated Key for the required row
      * @param out output stream
@@ -258,21 +267,21 @@ public class SSTableExport
             DecoratedKey key = iter.next();
 
             // validate order of the keys in the sstable
-            if (lastKey != null && lastKey.compareTo(key) > 0 )
+            if (lastKey != null && lastKey.compareTo(key) > 0)
                 throw new IOException("Key out of order! " + lastKey + " > " + key);
             lastKey = key;
 
             outs.println(bytesToHex(key.key));
+            checkStream(outs); // flushes
         }
         iter.close();
-        outs.flush();
     }
 
     /**
      * Export specific rows from an SSTable and write the resulting JSON to a PrintStream.
      *
-     * @param desc the descriptor of the sstable table to read from
-     * @param outs PrintStream to write the output to
+     * @param desc     the descriptor of the sstable table to read from
+     * @param outs     PrintStream to write the output to
      * @param toExport the keys corresponding to the rows to export
      * @param excludes keys to exclude from export
      * @throws IOException on failure to read/write input/output
@@ -317,6 +326,7 @@ public class SSTableExport
             if (i != 0)
                 outs.println(",");
 
+            checkStream(outs);
             i++;
         }
 
@@ -356,6 +366,7 @@ public class SSTableExport
                 outs.println(",");
 
             serializeRow(row, row.getKey(), outs);
+            checkStream(outs);
 
             i++;
         }
@@ -369,10 +380,9 @@ public class SSTableExport
     /**
      * Export an SSTable and write the resulting JSON to a PrintStream.
      *
-     * @param desc the descriptor of the sstable table to read from
-     * @param outs PrintStream to write the output to
+     * @param desc     the descriptor of the sstable table to read from
+     * @param outs     PrintStream to write the output to
      * @param excludes keys to exclude from export
-     *
      * @throws IOException on failure to read/write input/output
      */
     public static void export(Descriptor desc, PrintStream outs, String[] excludes) throws IOException
@@ -383,9 +393,8 @@ public class SSTableExport
     /**
      * Export an SSTable and write the resulting JSON to standard out.
      *
-     * @param desc the descriptor of the sstable table to read from
+     * @param desc     the descriptor of the sstable table to read from
      * @param excludes keys to exclude from export
-     *
      * @throws IOException on failure to read/write SSTable/standard out
      */
     public static void export(Descriptor desc, String[] excludes) throws IOException
@@ -398,8 +407,7 @@ public class SSTableExport
      * export the contents of the SSTable to JSON.
      *
      * @param args command lines arguments
-     *
-     * @throws IOException on failure to open/read/write files or output streams
+     * @throws IOException            on failure to open/read/write files or output streams
      * @throws ConfigurationException on configuration failure (wrong params given)
      */
     public static void main(String[] args) throws IOException, ConfigurationException
@@ -440,16 +448,24 @@ public class SSTableExport
             System.exit(1);
         }
 
-        if (cmd.hasOption(ENUMERATEKEYS_OPTION))
+        try
         {
-            enumeratekeys(descriptor, System.out);
+            if (cmd.hasOption(ENUMERATEKEYS_OPTION))
+            {
+                enumeratekeys(descriptor, System.out);
+            }
+            else
+            {
+                if ((keys != null) && (keys.length > 0))
+                    export(descriptor, System.out, Arrays.asList(keys), excludes);
+                else
+                    export(descriptor, excludes);
+            }
         }
-        else
+        catch (IOException e)
         {
-            if ((keys != null) && (keys.length > 0))
-                export(descriptor, System.out, Arrays.asList(keys), excludes);
-            else
-                export(descriptor, excludes);
+            // throwing exception outside main with broken pipe causes windows cmd to hang
+            e.printStackTrace(System.err);
         }
 
         System.exit(0);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/b6be6835/test/unit/org/apache/cassandra/tools/SSTableExportTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/tools/SSTableExportTest.java b/test/unit/org/apache/cassandra/tools/SSTableExportTest.java
index acee881..975051f 100644
--- a/test/unit/org/apache/cassandra/tools/SSTableExportTest.java
+++ b/test/unit/org/apache/cassandra/tools/SSTableExportTest.java
@@ -28,14 +28,20 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 
-import org.junit.Test;
-
 import org.apache.cassandra.SchemaLoader;
 import org.apache.cassandra.Util;
-import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.Column;
+import org.apache.cassandra.db.ColumnFamily;
+import org.apache.cassandra.db.CounterColumn;
+import org.apache.cassandra.db.DeletionInfo;
+import org.apache.cassandra.db.ExpiringColumn;
+import org.apache.cassandra.db.TreeMapBackedSortedColumns;
 import org.apache.cassandra.db.filter.QueryFilter;
 import org.apache.cassandra.db.marshal.UTF8Type;
 import org.apache.cassandra.io.sstable.Descriptor;
@@ -46,6 +52,7 @@ import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
 import org.json.simple.JSONValue;
 import org.json.simple.parser.ParseException;
+import org.junit.Test;
 
 public class SSTableExportTest extends SchemaLoader
 {
@@ -53,6 +60,31 @@ public class SSTableExportTest extends SchemaLoader
     {
         return bytesToHex(ByteBufferUtil.bytes(str));
     }
+    
+    public SSTableWriter getDummyWriter() throws IOException
+    {
+        File tempSS = tempSSTableFile("Keyspace1", "Standard1");
+        ColumnFamily cfamily = TreeMapBackedSortedColumns.factory.create("Keyspace1", "Standard1");
+        SSTableWriter writer = new SSTableWriter(tempSS.getPath(), 2);
+
+        // Add rowA
+        cfamily.addColumn(ByteBufferUtil.bytes("colA"), ByteBufferUtil.bytes("valA"), System.currentTimeMillis());
+        writer.append(Util.dk("rowA"), cfamily);
+        cfamily.clear();
+        
+        cfamily.addColumn(ByteBufferUtil.bytes("colB"), ByteBufferUtil.bytes("valB"), System.currentTimeMillis());
+        writer.append(Util.dk("rowB"), cfamily);
+        cfamily.clear();
+        
+        
+        return writer;
+
+    }
+    
+    
+    public PrintStream dummyStream = new PrintStream(new OutputStream(){
+        public void write(int b) throws IOException { throw new IOException(); }
+    });
 
     @Test
     public void testEnumeratekeys() throws IOException
@@ -303,4 +335,29 @@ public class SSTableExportTest extends SchemaLoader
         assertEquals("column value did not match", ByteBufferUtil.bytes("val1"), hexToBytes((String) col2.get(1)));
 
     }
+    
+    @Test(expected=IOException.class)
+    public void testBrokenPipeEnumerateKeys() throws IOException
+    {
+    	SSTableWriter writer = getDummyWriter();
+    	writer.closeAndOpenReader();
+    	SSTableExport.enumeratekeys(Descriptor.fromFilename(writer.getFilename()), dummyStream);
+    }
+    
+    @Test(expected=IOException.class)
+    public void testBrokenPipeExport1() throws IOException
+    {
+    	SSTableWriter writer = getDummyWriter();
+        SSTableExport.export(writer.closeAndOpenReader(), dummyStream, new String[0]);
+    }
+    
+    @Test(expected=IOException.class)
+    public void testBrokenPipeExport2() throws IOException 
+    {
+    	SSTableWriter writer = getDummyWriter();
+    	writer.closeAndOpenReader();
+        SSTableExport.export(Descriptor.fromFilename(writer.getFilename()), dummyStream, 
+        		new ArrayList<String>(Arrays.asList("colA")), new String[]{"colA"});
+    }
+    
 }