You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2013/02/06 16:02:41 UTC

svn commit: r1442999 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/converter/stream/ test/java/org/apache/camel/converter/stream/

Author: ningjiang
Date: Wed Feb  6 15:02:41 2013
New Revision: 1442999

URL: http://svn.apache.org/viewvc?rev=1442999&view=rev
Log:
CAMEL-6040  Add an option to encrypt tmp files generated by Camel's CachedOutputStream  with thanks to Aki

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/CachedOutputStream.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/FileInputStreamCache.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/CachedOutputStream.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/CachedOutputStream.java?rev=1442999&r1=1442998&r2=1442999&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/CachedOutputStream.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/CachedOutputStream.java Wed Feb  6 15:02:41 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.converter.stream;
 
+import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -24,12 +25,17 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.StreamCache;
 import org.apache.camel.support.SynchronizationAdapter;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,6 +52,7 @@ public class CachedOutputStream extends 
     public static final String THRESHOLD = "CamelCachedOutputStreamThreshold";
     public static final String BUFFER_SIZE = "CamelCachedOutputStreamBufferSize";
     public static final String TEMP_DIR = "CamelCachedOutputStreamOutputDirectory";
+    public static final String CIPHER_TRANSFORMATION = "CamelCachedOutputStreamCipherTransformation";
     private static final transient Logger LOG = LoggerFactory.getLogger(CachedOutputStream.class);
     
     private OutputStream currentStream;
@@ -57,6 +64,9 @@ public class CachedOutputStream extends 
     private long threshold = 64 * 1024;
     private int bufferSize = 2 * 1024;
     private File outputDir;
+    private String cipherTransformation;
+    private CipherPair ciphers;
+
     
     public CachedOutputStream(Exchange exchange) {
         this(exchange, true);
@@ -76,6 +86,7 @@ public class CachedOutputStream extends 
         if (dir != null) {
             this.outputDir = exchange.getContext().getTypeConverter().convertTo(File.class, dir);
         }
+        this.cipherTransformation = exchange.getContext().getProperty(CIPHER_TRANSFORMATION);
        
         currentStream = new ByteArrayOutputStream(this.bufferSize);
         
@@ -159,7 +170,7 @@ public class CachedOutputStream extends 
         } else {
             try {
                 if (fileInputStreamCache == null) {
-                    fileInputStreamCache = new FileInputStreamCache(tempFile);
+                    fileInputStreamCache = new FileInputStreamCache(tempFile, ciphers);
                 }
                 return fileInputStreamCache;
             } catch (FileNotFoundException e) {
@@ -185,7 +196,7 @@ public class CachedOutputStream extends 
         } else {
             try {
                 if (fileInputStreamCache == null) {
-                    fileInputStreamCache = new FileInputStreamCache(tempFile);
+                    fileInputStreamCache = new FileInputStreamCache(tempFile, ciphers);
                 }
                 return fileInputStreamCache;
             } catch (FileNotFoundException e) {
@@ -215,7 +226,7 @@ public class CachedOutputStream extends 
         LOG.trace("Creating temporary stream cache file: {}", tempFile);
 
         try {
-            currentStream = IOHelper.buffered(new FileOutputStream(tempFile));
+            currentStream = createOutputStream(tempFile);
             bout.writeTo(currentStream);
         } finally {
             // ensure flag is flipped to file based
@@ -259,4 +270,26 @@ public class CachedOutputStream extends 
         }
     }
 
+    private OutputStream createOutputStream(File file) throws IOException {
+        OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+        if (ObjectHelper.isNotEmpty(cipherTransformation)) {
+            try {
+                if (ciphers == null) {
+                    ciphers = new CipherPair(cipherTransformation);
+                }
+            } catch (GeneralSecurityException e) {
+                throw new IOException(e.getMessage(), e);
+            }
+            out = new CipherOutputStream(out, ciphers.getEncryptor()) {
+                boolean closed;
+                public void close() throws IOException {
+                    if (!closed) {
+                        super.close();
+                        closed = true;
+                    }
+                }
+            };
+        }
+        return out;
+    }
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/FileInputStreamCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/FileInputStreamCache.java?rev=1442999&r1=1442998&r2=1442999&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/FileInputStreamCache.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/converter/stream/FileInputStreamCache.java Wed Feb  6 15:02:41 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.converter.stream;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -26,6 +27,8 @@ import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
 import java.nio.channels.WritableByteChannel;
 
+import javax.crypto.CipherInputStream;
+
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.StreamCache;
 import org.apache.camel.util.IOHelper;
@@ -33,10 +36,16 @@ import org.apache.camel.util.IOHelper;
 public class FileInputStreamCache extends InputStream implements StreamCache {
     private InputStream stream;
     private File file;
+    private CipherPair ciphers;
 
     public FileInputStreamCache(File file) throws FileNotFoundException {
+        this(file, null);
+    }
+    
+    FileInputStreamCache(File file, CipherPair ciphers) throws FileNotFoundException {
         this.file = file;
         this.stream = null;
+        this.ciphers = ciphers;
     }
     
     @Override
@@ -59,7 +68,7 @@ public class FileInputStreamCache extend
     }
 
     public void writeTo(OutputStream os) throws IOException {
-        if (stream == null) {
+        if (stream == null && ciphers == null) {
             FileInputStream s = new FileInputStream(file);
             long len = file.length();
             WritableByteChannel out;
@@ -92,8 +101,25 @@ public class FileInputStreamCache extend
 
     protected InputStream getInputStream() throws IOException {
         if (stream == null) {
-            stream = IOHelper.buffered(new FileInputStream(file));
+            stream = createInputStream(file);
         }
         return stream;
     }
+
+    private InputStream createInputStream(File file) throws IOException {
+        InputStream in = new BufferedInputStream(new FileInputStream(file));
+        if (ciphers != null) {
+            in = new CipherInputStream(in, ciphers.getDecryptor()) {
+                boolean closed;
+                public void close() throws IOException {
+                    if (!closed) {
+                        super.close();
+                        closed = true;
+                    }
+                }
+            };
+        }
+        return in;
+    }
+
 }

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java?rev=1442999&r1=1442998&r2=1442999&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java Wed Feb  6 15:02:41 2013
@@ -66,12 +66,12 @@ public class CachedOutputStreamTest exte
     public void testCacheStreamToFileAndCloseStream() throws IOException {       
         CachedOutputStream cos = new CachedOutputStream(exchange);
         cos.write(TEST_STRING.getBytes("UTF-8"));
-
+        
         File file = new File("target/cachedir");
         String[] files = file.list();
         assertEquals("we should have a temp file", files.length, 1);
         assertTrue("The file name should start with cos" , files[0].startsWith("cos"));
-        
+
         StreamCache cache = cos.getStreamCache();
         assertTrue("Should get the FileInputStreamCache", cache instanceof FileInputStreamCache);
         String temp = toString((InputStream)cache);
@@ -94,6 +94,45 @@ public class CachedOutputStreamTest exte
         assertEquals("we should have no temp file", files.length, 0);
     }
     
+    public void testCacheStreamToFileAndCloseStreamEncrypted() throws IOException {
+        // set some stream or 8-bit block cipher transformation name
+        exchange.getContext().getProperties().put(CachedOutputStream.CIPHER_TRANSFORMATION, "RC4");
+        CachedOutputStream cos = new CachedOutputStream(exchange);
+        cos.write(TEST_STRING.getBytes("UTF-8"));
+        cos.flush();
+        
+        File file = new File("target/cachedir");
+        String[] files = file.list();
+        assertEquals("we should have a temp file", files.length, 1);
+        assertTrue("The content is written" , new File(file, files[0]).length() > 10);
+        
+        java.io.FileInputStream tmpin = new java.io.FileInputStream(new File(file, files[0]));
+        String temp = toString(tmpin);
+        assertTrue("The content is not encrypted", temp.length() > 0 && temp.indexOf("aaa") < 0);
+        tmpin.close();
+        
+        StreamCache cache = cos.getStreamCache();
+        assertTrue("Should get the FileInputStreamCache", cache instanceof FileInputStreamCache);
+        temp = toString((InputStream)cache);
+
+        ((InputStream)cache).close();
+        assertEquals("we should have a temp file", files.length, 1);
+        assertEquals("Cached a wrong file", temp, TEST_STRING);
+        exchange.getUnitOfWork().done(exchange);
+
+        try {
+            cache.reset();
+            // The stream is closed, so the temp file is gone.
+            fail("we expect the exception here");
+        } catch (Exception exception) {
+            // do nothing
+        }
+
+
+        files = file.list();
+        assertEquals("we should have no temp file", files.length, 0);
+    }
+
     public void testCacheStreamToFileCloseStreamBeforeDone() throws IOException {
         CachedOutputStream cos = new CachedOutputStream(exchange);
         cos.write(TEST_STRING.getBytes("UTF-8"));