You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2012/12/05 20:17:24 UTC

svn commit: r1417590 - in /qpid/proton/trunk/proton-j/proton/src: main/java/org/apache/qpid/proton/engine/impl/ test/java/org/apache/qpid/proton/engine/impl/

Author: rgodfrey
Date: Wed Dec  5 19:17:22 2012
New Revision: 1417590

URL: http://svn.apache.org/viewvc?rev=1417590&view=rev
Log:
PROTON-172 : Applied patch from Phil Harvey

Added:
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ByteHolder.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/BytePipeline.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteHolderTest.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/BytePipelineTest.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteTestHelper.java
Modified:
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapper.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CannedTransportOutput.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CapitalisingDummySslEngine.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/RememberingTransportInput.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapperTest.java
    qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SslHandshakeSniffingTransportWrapperTest.java

Added: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ByteHolder.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ByteHolder.java?rev=1417590&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ByteHolder.java (added)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/ByteHolder.java Wed Dec  5 19:17:22 2012
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.proton.engine.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.engine.TransportInput;
+import org.apache.qpid.proton.engine.TransportOutput;
+
+/**
+ * I thinly wrap a {@link ByteBuffer} to facilitate its usage e.g. in {@link SimpleSslTransportWrapper}.
+ * At a given moment I am either in a state that is ready to be written to, or read from.
+ * To switch between these states, call {@link #prepareToRead()} or {@link #prepareToWrite()}, each of which returns the {@link ByteBuffer}
+ * ready to be used.
+ */
+public class ByteHolder
+{
+    private final ByteBuffer _bytes;
+
+    /** Creates me, initially in a writeable state */
+    public ByteHolder(int capacity)
+    {
+        _bytes = ByteBuffer.allocate(capacity);
+    }
+
+    public boolean hasSpace()
+    {
+        return _bytes.remaining() > 0;
+    }
+
+    /**
+     * @return the total number of bytes I now contain
+     */
+    public int writeOutputFrom(TransportOutput transportOutput)
+    {
+        byte[] byteArray = _bytes.array();
+        int offset = _bytes.position();
+        int numberOfBytesToGet = _bytes.remaining();
+
+        int numberOfBytesGot = transportOutput.output(byteArray, offset, numberOfBytesToGet);
+
+        int newPosition = offset + numberOfBytesGot;
+        _bytes.position(newPosition);
+        return newPosition;
+    }
+
+    /**
+     * @return a ByteBuffer wrapping the stored bytes, intended to be read from
+     */
+    public ByteBuffer prepareToRead()
+    {
+        _bytes.flip();
+        return _bytes;
+    }
+
+    /**
+     * Read my bytes into the supplied destination
+     * @return the number of byte actually read (might be less than numberOfBytesRequested if I contain fewer bytes than that)
+     */
+    public int readInto(byte[] destination, int offset, int numberOfBytesRequested)
+    {
+        int numberOfBytesToRead = Math.min(numberOfBytesRequested, _bytes.remaining());
+        _bytes.get(destination, offset, numberOfBytesToRead);
+        return numberOfBytesToRead;
+    }
+
+    /**
+     * @return whether all my bytes were read into the {@link TransportInput} (i.e. returns false if transportInput didn't accept all the bytes)
+     */
+    public boolean readInto(TransportInput transportInput)
+    {
+        if(_bytes.hasRemaining())
+        {
+            int offset = _bytes.position();
+            int numberAccepted = transportInput.input(_bytes.array(), offset, _bytes.remaining());
+            int newPosition = offset + numberAccepted;
+            _bytes.position(newPosition);
+            return !_bytes.hasRemaining();
+        }
+        else
+        {
+            // nothing to do
+            return true;
+        }
+    }
+
+    /**
+     * prepare me to be written to again
+     * @return a ByteBuffer, ready to be written to.
+     */
+    public ByteBuffer prepareToWrite()
+    {
+        _bytes.compact();
+        return _bytes;
+    }
+
+    public int getCapacity()
+    {
+        return _bytes.capacity();
+    }
+
+}

Added: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/BytePipeline.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/BytePipeline.java?rev=1417590&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/BytePipeline.java (added)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/BytePipeline.java Wed Dec  5 19:17:22 2012
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.proton.engine.impl;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Thinly wraps a {@link ByteBuffer} to make it easy to be used for the following sequence of operations:
+ * <ol>
+ * <li>Append some more bytes (of any size) to me using {@link #appendAndClear(byte[], int, int)}</li>
+ * <li>Read some of my bytes</li>
+ * <li>Set my contents using {@link #set(ByteBuffer, int)}</li>
+ * </ol>
+ *
+ * @see SimpleSslTransportWrapper
+ */
+public class BytePipeline
+{
+    private static final ByteBuffer EMPTY = ByteBuffer.wrap(new byte[0]);
+
+    private ByteBuffer _bytes = EMPTY;
+
+    /**
+     * Append the new bytes to my existing not-yet-consumed ones.
+     *
+     * newBytes is copied, to guard against the caller subsequently modifying its contents.
+     *
+     * @return a read-only ByteBuffer containing the existiduplicateng contents plus the portion of newBytes implied by offset and size.
+     * The returned object is intentionally not a copy; this allows clients to "consume" bytes by calling the the get(..) methods on it.
+     */
+    public ByteBuffer appendAndClear(byte[] newBytes, int offset, int numberOfNewBytesToAppend)
+    {
+        byte[] oldBytes = _bytes.array();
+        int numberOfOldBytes = _bytes.remaining();
+        int sizeOfResult = numberOfOldBytes + numberOfNewBytesToAppend;
+        byte[] resultBytes = new byte[sizeOfResult];
+
+        System.arraycopy(oldBytes, _bytes.position(), resultBytes, 0, numberOfOldBytes);
+        System.arraycopy(newBytes, offset, resultBytes, numberOfOldBytes, numberOfNewBytesToAppend);
+
+        ByteBuffer retVal = ByteBuffer.wrap(resultBytes);
+        _bytes = EMPTY;
+
+        return retVal;
+    }
+
+    /**
+     * Stores the portion of newBytes implied by the offset. Does not take a copy of the provided buffer's content
+     * because we assume no further changes will be made to it.
+     */
+    public void set(ByteBuffer newBytes, int offset)
+    {
+        _bytes = newBytes.duplicate();
+        _bytes.clear();
+        _bytes.position(offset);
+    }
+
+    /**
+     * Get the number of bytes not yet consumed
+     */
+    public int getSize()
+    {
+        return _bytes.remaining();
+    }
+
+}

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapper.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapper.java?rev=1417590&r1=1417589&r2=1417590&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapper.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapper.java Wed Dec  5 19:17:22 2012
@@ -37,6 +37,7 @@ import org.apache.qpid.proton.engine.Tra
 /**
  * TODO close the SSLEngine when told to, and modify {@link #input(byte[], int, int)} and {@link #output(byte[], int, int)}
  * to respond appropriately thereafter.
+ * TODO move SSL and possible byte management classes into separate package
  */
 public class SimpleSslTransportWrapper implements SslTransportWrapper
 {
@@ -54,18 +55,17 @@ public class SimpleSslTransportWrapper i
 
     private SslEngineFacade _sslEngine;
 
-    private byte[] _clearOutputBuf;
-    private int _clearOutputBufOffset;
-    /** how many bytes of leftover clear output we've got */
-    private int _clearOutputBufSize;
-    private ByteBuffer _encodedOutputBuf;
-
-    private byte[] _encodedLeftovers = new byte[0];
-
-    private byte[] _clearLeftoverInput;
-    private int _clearLeftovertInputOffset;
-    private int _clearLeftoverInputSize;
+    /** Used by {@link #output(byte[], int, int)}. Acts as a buffer for the output from underlyingOutput */
+    private ByteHolder _clearOutputHolder;
 
+    /** Used by {@link #output(byte[], int, int)}. Caches the output from SSLEngine.wrap */
+    private ByteHolder _encodedOutputHolder;
+
+    /** Used by {@link #input(byte[], int, int)}. A buffer for the decoded bytes that will be passed to _underlyingInput */
+    private ByteHolder _decodedInputHolder;
+
+    /** used by {@link #input(byte[], int, int)} to cache the left over bytes not yet decoded due to buffer underflow. */
+    private final BytePipeline _encodedLeftoversPipeline = new BytePipeline();
 
     /** could change during the lifetime of the ssl connection owing to renegotiation. */
     private String _cipherName;
@@ -89,78 +89,68 @@ public class SimpleSslTransportWrapper i
         _underlyingOutput = underlyingOutput;
         _sslEngineFacadeFactory = sslEngineFacadeFactory;
         _sslEngine = _sslEngineFacadeFactory.createSslEngineFacade(sslConfiguration);
-        createBuffers(_sslEngine);
+        createByteHolders();
     }
 
-    private void createBuffers(SslEngineFacade sslEngine)
+    private void createByteHolders()
     {
-        int appBufferMax = sslEngine.getApplicationBufferSize();
-        int packetBufferMax = sslEngine.getPacketBufferSize();
+        int appBufferMax = _sslEngine.getApplicationBufferSize();
+        int packetBufferMax = _sslEngine.getPacketBufferSize();
 
-        _clearOutputBuf = new byte[appBufferMax + APPLICATION_BUFFER_EXTRA];
-        _clearLeftoverInput = new byte[appBufferMax + APPLICATION_BUFFER_EXTRA];
+        _clearOutputHolder = new ByteHolder(appBufferMax + APPLICATION_BUFFER_EXTRA);
+        _decodedInputHolder = new ByteHolder(appBufferMax + APPLICATION_BUFFER_EXTRA);
+        _decodedInputHolder.prepareToRead();
 
-        _encodedOutputBuf = ByteBuffer.allocate(packetBufferMax);
-        _encodedOutputBuf.limit(0);
+        _encodedOutputHolder = new ByteHolder(packetBufferMax);
+        _encodedOutputHolder.prepareToRead();
     }
 
     @Override
     public int input(byte[] encodedBytes, int offset, int size)
     {
-        final int initialSizeOfEncodedLeftovers = getSizeOfEncodedLeftovers();
-        final byte[] oldPlusNewEncodedBytes = buildLeftoversPlusNewEncodedBytes(encodedBytes, offset, size);
-        final ByteBuffer oldPlusNewEncodedByteBuffer = ByteBuffer.wrap(oldPlusNewEncodedBytes);
-        clearEncodedLeftovers();
+        final int initialSizeOfEncodedLeftovers =  _encodedLeftoversPipeline.getSize();
+        final ByteBuffer oldPlusNewEncodedByteBuffer = _encodedLeftoversPipeline.appendAndClear(encodedBytes, offset, size);
 
-        if (_clearLeftoverInputSize > 0)
+        if(!_decodedInputHolder.readInto(_underlyingInput))
         {
-            int numberAccepted = _underlyingInput.input(_clearLeftoverInput, _clearLeftovertInputOffset, _clearLeftoverInputSize);
-            if (numberAccepted < _clearLeftoverInputSize)
-            {
-                // underlying input couldn't accept all existing leftovers so we return without trying to decode any new data
-                _clearLeftoverInputSize -= numberAccepted;
-                _clearLeftovertInputOffset += numberAccepted;
-                return 0;
-            }
-            else
-            {
-                _clearLeftoverInputSize = 0;
-                _clearLeftovertInputOffset = 0;
-            }
+            // underlying input couldn't accept all existing leftovers so we return without trying to decode any new data
+            return 0;
         }
 
         try
         {
             boolean keepLooping = true;
-
-            byte[] clearBytes = new byte[_sslEngine.getApplicationBufferSize() + APPLICATION_BUFFER_EXTRA];
-            ByteBuffer clearByteBuffer = ByteBuffer.wrap(clearBytes);
-            int totalBytesConsumed = 0;
+            int totalBytesDecoded = 0;
 
             do
             {
-                SSLEngineResult result = _sslEngine.unwrap(oldPlusNewEncodedByteBuffer, clearByteBuffer);
+                SSLEngineResult result = _sslEngine.unwrap(oldPlusNewEncodedByteBuffer, _decodedInputHolder.prepareToWrite());
+                _decodedInputHolder.prepareToRead();
 
                 runDelegatedTasks(result);
                 updateCipherAndProtocolName(result);
 
-                System.out.println(_sslParams.getMode() + " input " + sslEngineResultToString(result));
+                System.out.println(_sslParams.getMode() + " input " + resultToString(result));
 
-                if(result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW)
+                Status sslResultStatus = result.getStatus();
+                HandshakeStatus handshakeStatus = result.getHandshakeStatus();
+
+                if(sslResultStatus == SSLEngineResult.Status.OK)
                 {
-                    cacheEncodedLeftovers(oldPlusNewEncodedBytes, totalBytesConsumed);
+                    totalBytesDecoded += result.bytesConsumed();
                 }
-                else if(result.getStatus() == SSLEngineResult.Status.OK)
+                else if(sslResultStatus == SSLEngineResult.Status.BUFFER_UNDERFLOW)
                 {
-                    totalBytesConsumed += result.bytesConsumed();
+                    // Not an error. We store the not-yet-decoded bytes which will hopefully be augmented by some more
+                    // in a subsequent invocation of this method, allowing decoding to be done.
+                    _encodedLeftoversPipeline.set(oldPlusNewEncodedByteBuffer, totalBytesDecoded);
                 }
                 else
                 {
-                    throw new IllegalStateException("Unexpected SSL Engine state " + result.getStatus());
+                    throw new IllegalStateException("Unexpected SSL Engine state " + sslResultStatus);
                 }
 
-                HandshakeStatus handshakeStatus = result.getHandshakeStatus();
-                int sizeOfClearLeftovers = 0;
+                boolean allAcceptedByUnderlyingInput = true;
                 if(result.bytesProduced() > 0)
                 {
                     if(handshakeStatus != HandshakeStatus.NOT_HANDSHAKING)
@@ -168,26 +158,17 @@ public class SimpleSslTransportWrapper i
                         System.out.println("WARN unexpectedly produced bytes for the underlying input when handshaking");
                     }
 
-                    int numberAccepted = _underlyingInput.input(clearBytes, 0, result.bytesProduced());
-                    sizeOfClearLeftovers = result.bytesProduced() - numberAccepted;
-                    if (sizeOfClearLeftovers > 0)
-                    {
-                        System.arraycopy(clearBytes, numberAccepted, _clearLeftoverInput, 0, sizeOfClearLeftovers);
-                        _clearLeftovertInputOffset = 0;
-                        _clearLeftoverInputSize = sizeOfClearLeftovers;
-                    }
-
-                    clearByteBuffer.clear();
+                    allAcceptedByUnderlyingInput = _decodedInputHolder.readInto(_underlyingInput);
                 }
 
                 keepLooping = handshakeStatus == HandshakeStatus.NOT_HANDSHAKING
-                            && result.getStatus() != Status.BUFFER_UNDERFLOW
-                            && sizeOfClearLeftovers == 0;
+                            && sslResultStatus != Status.BUFFER_UNDERFLOW
+                            && allAcceptedByUnderlyingInput;
             }
             while(keepLooping);
 
-            int newEncodedLeftovers = getSizeOfEncodedLeftovers();
-            int sizeToReportConsumed = totalBytesConsumed - initialSizeOfEncodedLeftovers + newEncodedLeftovers;
+            int newEncodedLeftovers = _encodedLeftoversPipeline.getSize();
+            int sizeToReportConsumed = totalBytesDecoded + newEncodedLeftovers - initialSizeOfEncodedLeftovers;
             return sizeToReportConsumed;
         }
         catch(SSLException e)
@@ -196,7 +177,7 @@ public class SimpleSslTransportWrapper i
         }
     }
 
-    private String sslEngineResultToString(SSLEngineResult result)
+    private String resultToString(SSLEngineResult result)
     {
         return new StringBuilder("[SSLEngineResult status = ").append(result.getStatus())
                 .append(" handshakeStatus = ").append(result.getHandshakeStatus())
@@ -205,157 +186,85 @@ public class SimpleSslTransportWrapper i
                 .append("]").toString();
     }
 
-    private void clearEncodedLeftovers()
-    {
-        _encodedLeftovers = new byte[0];
-    }
-
-    private int getSizeOfEncodedLeftovers()
-    {
-        return _encodedLeftovers.length;
-    }
-
-    private byte[] buildLeftoversPlusNewEncodedBytes(byte[] encodedBytes, int offset, int size)
-    {
-        // TODO revisit code below and consider avoiding the multiple byte array allocations.
-        int sizeOfResult = _encodedLeftovers.length + size;
-        byte[] resultBytes = new byte[sizeOfResult];
-
-        System.arraycopy(_encodedLeftovers, 0, resultBytes, 0, _encodedLeftovers.length);
-
-        int destPos = _encodedLeftovers.length;
-        System.arraycopy(encodedBytes, offset, resultBytes, destPos, size);
-
-        return resultBytes;
-    }
-
-
-    private void cacheEncodedLeftovers(byte[] encodedBytes, int numberAlreadyConsumed)
-    {
-        int leftoverSize = encodedBytes.length - numberAlreadyConsumed;
-        _encodedLeftovers = new byte[leftoverSize];
-        System.arraycopy(encodedBytes, numberAlreadyConsumed, _encodedLeftovers, 0, leftoverSize);
-    }
-
-    /*
-     * The state of _encodedOutputBuf is interesting.
+    /**
+     * Write encoded output to the supplied destination.
      *
-     * Pre-condition: it may contain stuff. It is ready for this stuff to be read into encodedBytesDestination
-     * Post-condition: it may contain stuff. It is ready for this stuff to be read into encodedBytesDestination
+     * The following conditions hold before and after this method call:
+     * {@link #_encodedOutputHolder} is readable.
+     * {@link #_clearOutputHolder} is writeable.
      */
     @Override
-    public int output(byte[] encodedBytesDestination, int offset, final int size)
+    public int output(byte[] destination, int offset, final int size)
     {
         try
         {
-            int numberOfEncodedLeftovers = 0;
-            if(_encodedOutputBuf.hasRemaining())
+            int totalBytesWrittenToDestination = _encodedOutputHolder.readInto(destination, offset, size);
+            if(totalBytesWrittenToDestination == size)
             {
-                // We already had some data ready encoded from the last call
-                numberOfEncodedLeftovers = _encodedOutputBuf.remaining();
-                if(numberOfEncodedLeftovers >= size)
-                {
-                    // our leftovers are sufficient to satisfy the "size" requested so fill the destination and return
-                    _encodedOutputBuf.get(encodedBytesDestination,offset,size);
-                    return size;
-                }
-                else
-                {
-                    // copy in the bytes we have leaving the byte buffer in a reading state
-                    _encodedOutputBuf.get(encodedBytesDestination,offset,numberOfEncodedLeftovers);
-                }
+                return size;
             }
 
-            int totalNumberOfBytesWrittenToEncodedBytesDestination = numberOfEncodedLeftovers;
             boolean keepLooping = true;
             do
             {
-                if(_clearOutputBufSize < _clearOutputBuf.length)
+                if (_clearOutputHolder.hasSpace())
                 {
-                    // Get some more clear bytes from the underlying output
-                    int outSize = _underlyingOutput.output(_clearOutputBuf, _clearOutputBufOffset, _clearOutputBuf.length - _clearOutputBufOffset);
-                    if(outSize > 0)
-                    {
-                        _clearOutputBufSize += outSize;
-                    }
-                    if (_clearOutputBufSize == 0)
+                    int numberOfBytesInClearOutputHolder = _clearOutputHolder.writeOutputFrom(_underlyingOutput);
+                    if (numberOfBytesInClearOutputHolder == 0)
                     {
-                        // No output to wrap.
-                        break;
+                        break; // no output to wrap
                     }
-
                 }
 
-                ByteBuffer src = ByteBuffer.wrap(_clearOutputBuf,_clearOutputBufOffset,_clearOutputBufSize);
-
-                final ByteBuffer dst;
-                int availableDestinationSize = size - totalNumberOfBytesWrittenToEncodedBytesDestination;
-                boolean wrappingIntoEncodedOutputBuf = availableDestinationSize < _sslEngine.getPacketBufferSize();
-                if (wrappingIntoEncodedOutputBuf)
+                int availableDestinationSize = size - totalBytesWrittenToDestination;
+                // SSLEngine will wrap directly into the provided destination byte[] if there is space, or into _encodedOutputHolder otherwise.
+                boolean wrappingIntoEncodedOutputHolder = availableDestinationSize < _sslEngine.getPacketBufferSize();
+                final ByteBuffer sslWrapDst;
+                if (wrappingIntoEncodedOutputHolder)
                 {
-                    dst = _encodedOutputBuf;
-                    _encodedOutputBuf.clear(); // get ready to write to it
+                    sslWrapDst = _encodedOutputHolder.prepareToWrite();
                 }
                 else
                 {
-                    dst = ByteBuffer.wrap(encodedBytesDestination, offset+totalNumberOfBytesWrittenToEncodedBytesDestination, availableDestinationSize);
+                    sslWrapDst = ByteBuffer.wrap(destination, offset+totalBytesWrittenToDestination, availableDestinationSize);
                 }
 
-                SSLEngineResult result = _sslEngine.wrap(src, dst);
-                _clearOutputBufOffset += _clearOutputBufSize - src.remaining();
+                SSLEngineResult result = _sslEngine.wrap(_clearOutputHolder.prepareToRead(), sslWrapDst);
+                _clearOutputHolder.prepareToWrite();
 
-                if(result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW)
+                Status sslResultStatus = result.getStatus();
+                if(sslResultStatus == SSLEngineResult.Status.BUFFER_OVERFLOW)
+                {
+                    throw new IllegalStateException("Insufficient space to perform wrap into encoded output buffer that has " + sslWrapDst.remaining() + " remaining bytes. wrappingIntoEncodedOutputHolder=" + wrappingIntoEncodedOutputHolder);
+                }
+                else if(sslResultStatus != SSLEngineResult.Status.OK)
                 {
-                    // Should not happen as _encodedOutputBuf is sized by getPacketBufferSize or
-                    // encodedBytesDestination has sufficient space for one packet
-                    throw new IllegalStateException("Insufficient space to perform wrap into encoded output buffer that has " + dst.remaining() + " remaining bytes");
+                    throw new RuntimeException("Unexpected SSLEngineResult status " + sslResultStatus);
                 }
 
-                System.out.println(_sslParams.getMode() + " output " + sslEngineResultToString(result) + " dst buf len " + _clearOutputBufSize);
                 runDelegatedTasks(result);
                 updateCipherAndProtocolName(result);
 
                 final int numberOfNewlyEncodedBytesWritten = Math.min(availableDestinationSize, result.bytesProduced());
-                if(wrappingIntoEncodedOutputBuf)
+                if(wrappingIntoEncodedOutputHolder)
                 {
-                    _encodedOutputBuf.flip(); // get ready to read from it
-
-                    // Now take as many bytes as we can into encodedBytesDestination (up to numberOfNewlyEncodedBytesWritten)
-                    // leaving the remainder to be read from _encodedOutputBuf on the next invocation
-                    _encodedOutputBuf.get(encodedBytesDestination, offset+totalNumberOfBytesWrittenToEncodedBytesDestination, numberOfNewlyEncodedBytesWritten);
-                }
-
-                if(result.getStatus() != SSLEngineResult.Status.OK)
-                {
-                    throw new RuntimeException("Output Uh Oh! " + result.getStatus());
+                    _encodedOutputHolder.prepareToRead();
+                    _encodedOutputHolder.readInto(destination, offset+totalBytesWrittenToDestination, numberOfNewlyEncodedBytesWritten);
                 }
 
+                totalBytesWrittenToDestination += numberOfNewlyEncodedBytesWritten;
 
-                if(_clearOutputBufOffset == _clearOutputBufSize)
-                {
-                    _clearOutputBufOffset = _clearOutputBufSize = 0;
-                }
-
-                totalNumberOfBytesWrittenToEncodedBytesDestination += numberOfNewlyEncodedBytesWritten;
-
-                HandshakeStatus handshakeStatus = result.getHandshakeStatus();
-
-                keepLooping = handshakeStatus == HandshakeStatus.NOT_HANDSHAKING
-                        && totalNumberOfBytesWrittenToEncodedBytesDestination < size;
+                keepLooping = result.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+                        && totalBytesWrittenToDestination < size;
             }
             while(keepLooping);
-            return totalNumberOfBytesWrittenToEncodedBytesDestination;
 
+            return totalBytesWrittenToDestination;
         }
         catch(SSLException e)
         {
             throw new TransportException("Mode " + _sslParams.getMode(), e);
         }
-
-        // first write remaining encoded output into passed buffers (bytes)
-        // if anything left in plain output, run through ssl engine into encoded output, then write into passed buffers (bytes)
-        // if still space in bytes, then call output on underlying transport to fill plain output, and repeat step above
-
     }
 
     /** @return the cipher name, which is null until the SSL handshaking is completed */

Added: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteHolderTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteHolderTest.java?rev=1417590&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteHolderTest.java (added)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteHolderTest.java Wed Dec  5 19:17:22 2012
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.proton.engine.impl;
+
+import static org.apache.qpid.proton.engine.impl.ByteTestHelper.assertArrayUntouchedExcept;
+import static org.apache.qpid.proton.engine.impl.ByteTestHelper.assertByteBufferContents;
+import static org.apache.qpid.proton.engine.impl.ByteTestHelper.createFilledBuffer;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.engine.impl.ByteHolder;
+import org.junit.Test;
+
+public class ByteHolderTest
+{
+    private ByteHolder _byteHolder = new ByteHolder(10);
+
+    @Test
+    public void testEmptyOutput()
+    {
+        _byteHolder.writeOutputFrom(new CannedTransportOutput(""));
+        assertByteBufferContents(_byteHolder.prepareToRead(), "");
+    }
+
+    @Test
+    public void testWriteOutputFromWithSmallOutputPartiallyFillsHolder()
+    {
+        String smallOutput = "1234";
+        assertTrue(smallOutput.length() < _byteHolder.getCapacity());
+
+        _byteHolder.writeOutputFrom(new CannedTransportOutput(smallOutput));
+
+        assertTrue(_byteHolder.hasSpace());
+        assertByteBufferContents(_byteHolder.prepareToRead(), smallOutput);
+    }
+
+    @Test
+    public void testWriteOutputFromWithOverflowingOutputCompletelyFillsHolder()
+    {
+        String bigOutput = "1234567890xxxxx";
+        assertTrue(bigOutput.length() > _byteHolder.getCapacity());
+
+        _byteHolder.writeOutputFrom(new CannedTransportOutput(bigOutput));
+        assertFalse(_byteHolder.hasSpace());
+        assertByteBufferContents(_byteHolder.prepareToRead(), "1234567890");
+    }
+
+    @Test
+    public void testWriteOutputFromWithOutputMatchingCapacityCompletelyFillsHolder()
+    {
+        String bigOutput = "1234567890";
+        assertTrue("Neither too big nor too small - the Goldilocks case", bigOutput.length() == _byteHolder.getCapacity());
+
+        _byteHolder.writeOutputFrom(new CannedTransportOutput(bigOutput));
+        assertFalse(_byteHolder.hasSpace());
+        assertByteBufferContents(_byteHolder.prepareToRead(), "1234567890");
+    }
+
+    /**
+     * Tests the expected usage of {@link ByteHolder}, i.e. repeatedly doing a
+     * write and then a (potentially partial) read.
+     */
+    @Test
+    public void testWriteOutputFromMultipleTimes()
+    {
+        // write and then partially read
+        {
+            _byteHolder.writeOutputFrom(new CannedTransportOutput("12345"));
+            ByteBuffer readableBytes = _byteHolder.prepareToRead();
+            readableBytes.get(new byte[2]); // chomp the first two bytes ('1' and '2')
+            _byteHolder.prepareToWrite();
+        }
+
+        // write enough to fill the holder and then completely read
+        {
+            _byteHolder.writeOutputFrom(new CannedTransportOutput("abcdefghijk"));
+            ByteBuffer readableBytes = _byteHolder.prepareToRead();
+            assertByteBufferContents(readableBytes, "345abcdefg", "Readable bytes should contain '345' left over from previouis partial read, plus as many of the new bytes 'abc...' as could fit");
+            _byteHolder.prepareToWrite();
+        }
+
+        // write and then read nothing
+        {
+            _byteHolder.writeOutputFrom(new CannedTransportOutput("xy"));
+            _byteHolder.prepareToRead();
+            _byteHolder.prepareToWrite();
+        }
+
+        // write nothing and then read
+        {
+            _byteHolder.writeOutputFrom(new CannedTransportOutput(""));
+            ByteBuffer readableBytes = _byteHolder.prepareToRead();
+            assertByteBufferContents(readableBytes, "xy", "Readable bytes should still contain 'xy' written in previous step");
+        }
+    }
+
+    @Test
+    public void testReadIntoWhenContainingFewerBytesThanRequested()
+    {
+        testReadInto("12345", 6, 2, "12345");
+    }
+
+    @Test
+    public void testReadIntoWhenContainingMoreBytesThanRequested()
+    {
+        testReadInto("12345", 2, 0, "12");
+    }
+
+    private void testReadInto(String contents, int numberOfBytesRequested, int offset, String expectedOutput)
+    {
+        _byteHolder.writeOutputFrom(new CannedTransportOutput(contents));
+        _byteHolder.prepareToRead();
+
+        byte[] destination = createFilledBuffer(10);
+
+        int numberOfBytesRead = _byteHolder.readInto(destination, offset, numberOfBytesRequested);
+        assertEquals("Unexpected number of bytes read", expectedOutput.length(), numberOfBytesRead);
+        assertArrayUntouchedExcept(expectedOutput, destination, offset);
+    }
+
+    @Test
+    public void testReadIntoTransportInputWhenAllBytesAreAccepted()
+    {
+        testReadIntoTransportInput("12345", "12345", null);
+    }
+
+    @Test
+    public void testReadIntoTransportInputWhenNotAllAccepted()
+    {
+        testReadIntoTransportInput("12345", "12", 2);
+    }
+
+    private void testReadIntoTransportInput(String contents, String expectedAcceptedInput, Integer acceptLimit)
+    {
+        String myString = contents;
+        _byteHolder.writeOutputFrom(new CannedTransportOutput(myString));
+        _byteHolder.prepareToRead();
+
+        RememberingTransportInput transportInput = new RememberingTransportInput();
+        if(acceptLimit != null)
+        {
+            transportInput.setAcceptLimit(acceptLimit);
+        }
+
+        boolean acceptedAllBytes = _byteHolder.readInto(transportInput);
+
+        boolean expectedAcceptedAllBytes = expectedAcceptedInput.length() == contents.length();
+
+        assertEquals("Return value should show whether all bytes were accepted", expectedAcceptedAllBytes, acceptedAllBytes);
+        assertEquals(expectedAcceptedInput, transportInput.getAcceptedInput());
+    }
+}

Added: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/BytePipelineTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/BytePipelineTest.java?rev=1417590&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/BytePipelineTest.java (added)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/BytePipelineTest.java Wed Dec  5 19:17:22 2012
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.proton.engine.impl;
+
+import static org.apache.qpid.proton.engine.impl.ByteTestHelper.assertByteBufferContents;
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.engine.impl.BytePipeline;
+import org.junit.Test;
+
+public class BytePipelineTest
+{
+    private BytePipeline _bytePipeline = new BytePipeline();
+
+    @Test
+    public void testApppendToNewPipeline()
+    {
+        ByteBuffer bytes = _bytePipeline.appendAndClear("123".getBytes(), 0, 3);
+        assertByteBufferContents(bytes, "123");
+    }
+
+    @Test
+    public void testApppend()
+    {
+        _bytePipeline.appendAndClear("123".getBytes(), 0, 3);
+        ByteBuffer bytes = _bytePipeline.appendAndClear("456".getBytes(), 0, 3);
+        assertByteBufferContents(bytes, "456");
+    }
+
+    @Test
+    public void testAppendWithOffsetAndSize()
+    {
+        ByteBuffer bytes = _bytePipeline.appendAndClear("xx123x".getBytes(), 2, 3);
+        assertByteBufferContents(bytes, "123");
+    }
+
+    @Test
+    public void testGetSize()
+    {
+        _bytePipeline.set(ByteBuffer.wrap("123".getBytes()), 0);
+        assertEquals(3, _bytePipeline.getSize());
+
+        _bytePipeline.set(ByteBuffer.wrap("456".getBytes()), 0);
+        assertEquals(3, _bytePipeline.getSize());
+    }
+
+    @Test
+    public void testSet()
+    {
+        ByteBuffer bytesToSet = ByteBuffer.wrap("123".getBytes());
+        _bytePipeline.set(bytesToSet, 0);
+        assertContents("123");
+    }
+
+    @Test
+    public void testSetWithOffset()
+    {
+        ByteBuffer bytesToSet = ByteBuffer.wrap("123".getBytes());
+        _bytePipeline.set(bytesToSet, 1);
+        assertContents("23");
+    }
+
+    @Test
+    public void testSetDisregardsWhetherProvidedBufferAlreadyRead()
+    {
+        ByteBuffer bytesToSet = ByteBuffer.wrap("123".getBytes());
+        bytesToSet.get(); // reading from the byte buffer should not affect the behaviour of set(..)
+        _bytePipeline.set(bytesToSet, 1);
+        assertContents("23");
+    }
+
+    private void assertContents(String expectedContents)
+    {
+        ByteBuffer bytes = _bytePipeline.appendAndClear("".getBytes(), 0, 0);
+        assertByteBufferContents(bytes, expectedContents);
+    }
+}

Added: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteTestHelper.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteTestHelper.java?rev=1417590&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteTestHelper.java (added)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/ByteTestHelper.java Wed Dec  5 19:17:22 2012
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.proton.engine.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.junit.Assert;
+
+public class ByteTestHelper
+{
+    public static void assertArrayUntouchedExcept(String expectedString, byte[] actualBytes)
+    {
+        assertArrayUntouchedExcept(expectedString, actualBytes, 0);
+    }
+
+    public static void assertArrayUntouchedExcept(String expectedString, byte[] actualBytes, int offset)
+    {
+        byte[] string = expectedString.getBytes();
+
+        byte[] expectedBytes = createFilledBuffer(actualBytes.length);
+        System.arraycopy(string, 0, expectedBytes, offset, string.length);
+
+        assertEquals(new String(expectedBytes), new String(actualBytes));
+    }
+
+    /**
+     * Intended to be used by tests to write into, allowing us to check that only the expected elements got overwritten.
+     * @return a byte array of the specified length containing @@@...
+     */
+    public static byte[] createFilledBuffer(int length)
+    {
+        byte[] expectedBytes = new byte[length];
+        Arrays.fill(expectedBytes, (byte)'@');
+        return expectedBytes;
+    }
+
+    public static void assertByteEquals(char expectedAsChar, byte actual)
+    {
+        Assert.assertEquals((byte)expectedAsChar, actual);
+    }
+
+    public static void assertByteBufferContents(ByteBuffer byteBuffer, String expectedContents)
+    {
+        assertByteBufferContents(byteBuffer, expectedContents, null);
+    }
+
+    public static void assertByteBufferContents(ByteBuffer byteBuffer, String expectedContents, String message)
+    {
+        int expectedLimit = expectedContents.length();
+
+        assertEquals("Position of readable byte buffer should initially be zero", 0, byteBuffer.position());
+        assertEquals("Limit of readable byte buffer should equal length of expected contents", expectedLimit, byteBuffer.limit());
+
+        byte[] bytes = new byte[expectedLimit];
+        byteBuffer.get(bytes);
+        if(message != null)
+        {
+            assertEquals(message, expectedContents, new String(bytes));
+        }
+        else
+        {
+            assertEquals("Unexpected contents", expectedContents, new String(bytes));
+        }
+    }
+}

Modified: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CannedTransportOutput.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CannedTransportOutput.java?rev=1417590&r1=1417589&r2=1417590&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CannedTransportOutput.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CannedTransportOutput.java Wed Dec  5 19:17:22 2012
@@ -30,6 +30,15 @@ public class CannedTransportOutput imple
 
     private ByteBuffer _cannedOutput;
 
+    public CannedTransportOutput()
+    {
+    }
+
+    public CannedTransportOutput(String output)
+    {
+        setOutput(output);
+    }
+
     @Override
     public int output(byte[] destination, int offset, int size)
     {

Modified: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CapitalisingDummySslEngine.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CapitalisingDummySslEngine.java?rev=1417590&r1=1417589&r2=1417590&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CapitalisingDummySslEngine.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/CapitalisingDummySslEngine.java Wed Dec  5 19:17:22 2012
@@ -30,6 +30,8 @@ import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
 import javax.net.ssl.SSLEngineResult.Status;
 
+import org.apache.qpid.proton.engine.impl.SslEngineFacade;
+
 
 /**
  * A simpler implementation of an SSLEngine that has predictable human-readable output, and that allows us to

Modified: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/RememberingTransportInput.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/RememberingTransportInput.java?rev=1417590&r1=1417589&r2=1417590&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/RememberingTransportInput.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/RememberingTransportInput.java Wed Dec  5 19:17:22 2012
@@ -31,11 +31,10 @@ class RememberingTransportInput implemen
     @Override
     public int input(byte[] bytes, int offset, int size)
     {
-        final int returnSize;
+        final String newInput;
         if (!_hasAcceptedLimit)
         {
-            _receivedInput.append(new String(bytes, offset, size));
-            returnSize = size;
+            newInput = new String(bytes, offset, size);
         }
         else
         {
@@ -48,10 +47,11 @@ class RememberingTransportInput implemen
                         + " with accept limit of " + _acceptLimit + ". Test error??");
             }
             int effectiveSize = Math.min(size, spareCapacity);
-            _receivedInput.append(new String(bytes, offset, effectiveSize));
-            returnSize = effectiveSize;
+            newInput = new String(bytes, offset, effectiveSize);
         }
-        return returnSize;
+
+        _receivedInput.append(newInput);
+        return newInput.length();
     }
 
     public void removeAcceptLimit()
@@ -70,4 +70,9 @@ class RememberingTransportInput implemen
         return _receivedInput.toString();
     }
 
+    @Override
+    public String toString()
+    {
+        return "[RememberingTransportInput receivedInput (length " + _receivedInput.length() + ") is:" + _receivedInput.toString() + "]";
+    }
 }
\ No newline at end of file

Modified: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapperTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapperTest.java?rev=1417590&r1=1417589&r2=1417590&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapperTest.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SimpleSslTransportWrapperTest.java Wed Dec  5 19:17:22 2012
@@ -20,14 +20,16 @@
  */
 package org.apache.qpid.proton.engine.impl;
 
+import static org.apache.qpid.proton.engine.impl.ByteTestHelper.assertArrayUntouchedExcept;
+import static org.apache.qpid.proton.engine.impl.ByteTestHelper.createFilledBuffer;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.Arrays;
-
 import org.apache.qpid.proton.engine.Ssl;
+import org.apache.qpid.proton.engine.impl.SimpleSslTransportWrapper;
+import org.apache.qpid.proton.engine.impl.SslEngineFacadeFactory;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -364,29 +366,4 @@ public class SimpleSslTransportWrapperTe
         assertEquals(expectedOutputProduced.length(), numberProduced);
         assertArrayUntouchedExcept(expectedOutputProduced, encodedBytes);
     }
-
-
-    private void assertArrayUntouchedExcept(String expectedString, byte[] actualBytes)
-    {
-        assertArrayUntouchedExcept(expectedString, actualBytes, 0);
-    }
-
-    private void assertArrayUntouchedExcept(String expectedString, byte[] actualBytes, int offset)
-    {
-        byte[] string = expectedString.getBytes();
-
-        byte[] expectedBytes = createFilledBuffer(actualBytes.length);
-        System.arraycopy(string, 0, expectedBytes, offset, string.length);
-
-        assertEquals(new String(expectedBytes), new String(actualBytes));
-
-    }
-
-    private byte[] createFilledBuffer(int length)
-    {
-        byte[] expectedBytes = new byte[length];
-        Arrays.fill(expectedBytes, (byte)'@');
-        return expectedBytes;
-    }
-
 }

Modified: qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SslHandshakeSniffingTransportWrapperTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SslHandshakeSniffingTransportWrapperTest.java?rev=1417590&r1=1417589&r2=1417590&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SslHandshakeSniffingTransportWrapperTest.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/test/java/org/apache/qpid/proton/engine/impl/SslHandshakeSniffingTransportWrapperTest.java Wed Dec  5 19:17:22 2012
@@ -25,6 +25,8 @@ import static org.mockito.Mockito.verify
 import static org.mockito.Mockito.verifyZeroInteractions;
 
 import org.apache.qpid.proton.engine.TransportWrapper;
+import org.apache.qpid.proton.engine.impl.SslHandshakeSniffingTransportWrapper;
+import org.apache.qpid.proton.engine.impl.SslTransportWrapper;
 import org.junit.Test;
 
 public class SslHandshakeSniffingTransportWrapperTest



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org