You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ph...@apache.org on 2013/04/04 12:50:59 UTC

svn commit: r1464428 [1/2] - in /qpid/proton/trunk: ./ proton-c/bindings/java/src/main/java/org/apache/qpid/proton/jni/ proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messenger/jni/ proton-j/proton-api/src/main/java/org/apache/qpid/proton/...

Author: philharveyonline
Date: Thu Apr  4 10:50:58 2013
New Revision: 1464428

URL: http://svn.apache.org/r1464428
Log:
PROTON-284: Added first version of ConnectionTest and TransportTest which contain AMQP spec-driven JUnit tests.
We think the set of test methods is nearly complete. However, only a few have been implemented. Only these ones
have the @Test annotation.
Enhanced Proton Factory classes to allow the proton-c or proton-j implementation to be requested.
Also added JavaDoc in various places to highlight issues that the tests have revealed.

Added:
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactory.java
      - copied, changed from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/test/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/ProtonFactoryLoaderTest.java
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/transport/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/transport/ErrorConditionTest.java
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonCFactory.java
      - copied, changed from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonFactory.java
      - copied, changed from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonJFactory.java
      - copied, changed from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/test/resources/
    qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/
    qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/services/
    qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/services/org.apache.qpid.proton.factoryloadertesting.DummyProtonFactory
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/ProtonFactoryImpl.java
      - copied, changed from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/AmqpFramer.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ProtonFactoryTestFixture.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/TransportPumper.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/TransportTest.java
Modified:
    qpid/proton/trunk/pom.xml
    qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/jni/JNIFactory.java
    qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messenger/jni/JNIMessengerFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactoryLoader.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Delivery.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Endpoint.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/message/MessageFactory.java
    qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/messenger/MessengerFactory.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/codec/impl/DataFactoryImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/driver/impl/DriverFactoryImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/message/impl/MessageFactoryImpl.java
    qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/messenger/impl/MessengerFactoryImpl.java
    qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtocolTracerEnabler.java
    qpid/proton/trunk/tests/pom.xml

Modified: qpid/proton/trunk/pom.xml
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/pom.xml?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/pom.xml (original)
+++ qpid/proton/trunk/pom.xml Thu Apr  4 10:50:58 2013
@@ -89,6 +89,8 @@
       <id>proton-jni</id>
       <modules>
         <module>proton-j/proton-api</module>
+        <!--proton-j-impl is required so we can use its EncoderImpl and DecoderImpl to generate test data -->
+        <module>proton-j/proton</module>
         <module>tests</module>
       </modules>
     </profile>

Modified: qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/jni/JNIFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/jni/JNIFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/jni/JNIFactory.java (original)
+++ qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/jni/JNIFactory.java Thu Apr  4 10:50:58 2013
@@ -21,7 +21,9 @@ package org.apache.qpid.proton.jni;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-public abstract class JNIFactory
+import org.apache.qpid.proton.ProtonFactory;
+
+public abstract class JNIFactory implements ProtonFactory
 {
     private static final Logger LOGGER = Logger.getLogger(JNIFactory.class.getName());
 
@@ -42,4 +44,9 @@ public abstract class JNIFactory
         }
     }
 
+    @Override
+    public final ImplementationType getImplementationType()
+    {
+        return ImplementationType.PROTON_C;
+    }
 }

Modified: qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messenger/jni/JNIMessengerFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messenger/jni/JNIMessengerFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messenger/jni/JNIMessengerFactory.java (original)
+++ qpid/proton/trunk/proton-c/bindings/java/src/main/java/org/apache/qpid/proton/messenger/jni/JNIMessengerFactory.java Thu Apr  4 10:50:58 2013
@@ -20,10 +20,12 @@
 package org.apache.qpid.proton.messenger.jni;
 
 import org.apache.qpid.proton.ProtonUnsupportedOperationException;
+import org.apache.qpid.proton.jni.JNIFactory;
 import org.apache.qpid.proton.messenger.Messenger;
 import org.apache.qpid.proton.messenger.MessengerFactory;
 
-public class JNIMessengerFactory implements MessengerFactory
+
+public class JNIMessengerFactory extends JNIFactory implements MessengerFactory
 {
 
     @Override

Copied: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactory.java (from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactory.java?p2=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactory.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java&r1=1464269&r2=1464428&rev=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactory.java Thu Apr  4 10:50:58 2013
@@ -15,13 +15,17 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.driver;
+package org.apache.qpid.proton;
 
-import java.io.IOException;
-
-public interface DriverFactory
+public interface ProtonFactory
 {
-    Driver createDriver() throws IOException;
+    enum ImplementationType
+    {
+        PROTON_C,
+        PROTON_J,
+        ANY;
+    }
+
+    ImplementationType getImplementationType();
 }

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactoryLoader.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactoryLoader.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactoryLoader.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/ProtonFactoryLoader.java Thu Apr  4 10:50:58 2013
@@ -23,13 +23,21 @@ import java.util.ServiceLoader;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.qpid.proton.ProtonFactory.ImplementationType;
+
 /**
  * A thin wrapper around {@link ServiceLoader} intended for loading Proton object factories.
+ *
+ * If system property {@value #IMPLEMENTATION_TYPE_PROPERTY} if set, loads a factory
+ * whose {@link ImplementationType} matches its value.
  */
-public class ProtonFactoryLoader<C>
+public class ProtonFactoryLoader<C extends ProtonFactory>
 {
+    public static final String IMPLEMENTATION_TYPE_PROPERTY = "qpid.proton.implementationtype";
+
     private static final Logger LOGGER = Logger.getLogger(ProtonFactoryLoader.class.getName());
-    private Class<C> _factoryInterface;
+    private final Class<C> _factoryInterface;
+    private final ImplementationType _implementationType;
 
     /**
      * Use this constructor if you intend to explicitly provide factory interface later,
@@ -38,14 +46,34 @@ public class ProtonFactoryLoader<C>
      */
     public ProtonFactoryLoader()
     {
+        this(null);
+    }
+
+    public ProtonFactoryLoader(Class<C> factoryInterface)
+    {
+        this(factoryInterface, getImpliedImplementationType());
+    }
+
+    private static ImplementationType getImpliedImplementationType()
+    {
+        String implementationTypeFromSystemProperty = System.getProperty(IMPLEMENTATION_TYPE_PROPERTY);
+        if(implementationTypeFromSystemProperty != null)
+        {
+            return ImplementationType.valueOf(implementationTypeFromSystemProperty);
+        }
+        else
+        {
+            return ImplementationType.ANY;
+        }
     }
 
     /**
      * @param factoryInterface will be used as the factory interface class in calls to {@link #loadFactory()}.
      */
-    public ProtonFactoryLoader(Class<C> factoryInterface)
+    public ProtonFactoryLoader(Class<C> factoryInterface, ImplementationType implementationType)
     {
         _factoryInterface = factoryInterface;
+        _implementationType = implementationType;
     }
 
     /**
@@ -64,16 +92,20 @@ public class ProtonFactoryLoader<C>
         }
         ServiceLoader<C> serviceLoader = ServiceLoader.load(factoryInterface);
         Iterator<C> serviceLoaderIterator = serviceLoader.iterator();
-        if(!serviceLoaderIterator.hasNext())
-        {
-            throw new IllegalStateException("Can't find service loader for " + factoryInterface.getName());
-        }
-        C factory = serviceLoaderIterator.next();
-        if(LOGGER.isLoggable(Level.FINE))
+        while(serviceLoaderIterator.hasNext())
         {
-            LOGGER.fine("loadFactory returning " + factory);
+            C factory = serviceLoaderIterator.next();
+            if(_implementationType == ImplementationType.ANY || factory.getImplementationType() == _implementationType)
+            {
+                if(LOGGER.isLoggable(Level.FINE))
+                {
+                    LOGGER.fine("loadFactory returning " + factory + " for loader's implementation type " + _implementationType);
+                }
+                return factory;
+            }
         }
-        return factory;
+        throw new IllegalStateException("Can't find service loader for " + factoryInterface.getName() +
+                                        " for implementation type " + _implementationType);
     }
 
 }

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java Thu Apr  4 10:50:58 2013
@@ -20,7 +20,9 @@
  */
 package org.apache.qpid.proton.codec;
 
-public interface DataFactory
+import org.apache.qpid.proton.ProtonFactory;
+
+public interface DataFactory extends ProtonFactory
 {
     Data createData(long capacity);
 }

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java Thu Apr  4 10:50:58 2013
@@ -21,7 +21,9 @@ package org.apache.qpid.proton.driver;
 
 import java.io.IOException;
 
-public interface DriverFactory
+import org.apache.qpid.proton.ProtonFactory;
+
+public interface DriverFactory extends ProtonFactory
 {
     Driver createDriver() throws IOException;
 }

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Connection.java Thu Apr  4 10:50:58 2013
@@ -37,6 +37,9 @@ public interface Connection extends Endp
 {
     /**
      * Returns a newly created session
+     *
+     * TODO does the Connection's channel-max property limit how many sessions can be created,
+     * or opened, or neither?
      */
     public Session session();
 
@@ -46,6 +49,8 @@ public interface Connection extends Endp
      * Typically used to discover sessions whose remote state has acquired
      * particular values, e.g. sessions that have been remotely opened or closed.
      *
+     * TODO what ordering guarantees on the returned "linked list" are provided?
+     *
      * @see Session#next(EnumSet, EnumSet)
      */
     public Session sessionHead(EnumSet<EndpointState> local, EnumSet<EndpointState> remote);

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Delivery.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Delivery.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Delivery.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Delivery.java Thu Apr  4 10:50:58 2013
@@ -58,7 +58,10 @@ public interface Delivery
     public void settle();
 
     /**
-     * Returns whether this delivery has been locally settled.
+     * Returns whether this delivery has been settled.
+     *
+     * TODO proton-j and proton-c return the local and remote statuses. Resolve this ambiguity.
+     *
      * @see #settle()
      */
     public boolean isSettled();

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Endpoint.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Endpoint.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Endpoint.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Endpoint.java Thu Apr  4 10:50:58 2013
@@ -23,11 +23,6 @@ package org.apache.qpid.proton.engine;
 
 import org.apache.qpid.proton.amqp.transport.ErrorCondition;
 
-/**
- * Endpoint
- *
- */
-
 public interface Endpoint
 {
     /**

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/EngineFactory.java Thu Apr  4 10:50:58 2013
@@ -18,7 +18,9 @@
  */
 package org.apache.qpid.proton.engine;
 
-public interface EngineFactory
+import org.apache.qpid.proton.ProtonFactory;
+
+public interface EngineFactory extends ProtonFactory
 {
     Connection createConnection();
     Transport createTransport();

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/engine/Transport.java Thu Apr  4 10:50:58 2013
@@ -24,11 +24,13 @@ package org.apache.qpid.proton.engine;
 /**
  * Transport
  *
+ * TODO why do I implement Endpoint
  */
 
 public interface Transport extends Endpoint
 {
-
+    /** the lower bound for the agreed maximum frame size (in bytes). */
+    public int MIN_MAX_FRAME_SIZE = 512;
     public int SESSION_WINDOW = 1024;
     public int END_OF_STREAM = -1;
 

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/message/MessageFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/message/MessageFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/message/MessageFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/message/MessageFactory.java Thu Apr  4 10:50:58 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.qpid.proton.message;
 
+import org.apache.qpid.proton.ProtonFactory;
 import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
 import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations;
 import org.apache.qpid.proton.amqp.messaging.Footer;
@@ -26,7 +27,7 @@ import org.apache.qpid.proton.amqp.messa
 import org.apache.qpid.proton.amqp.messaging.Properties;
 import org.apache.qpid.proton.amqp.messaging.Section;
 
-public interface MessageFactory
+public interface MessageFactory extends ProtonFactory
 {
     Message createMessage();
     Message createMessage(Header header,

Modified: qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/messenger/MessengerFactory.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/messenger/MessengerFactory.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/messenger/MessengerFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/messenger/MessengerFactory.java Thu Apr  4 10:50:58 2013
@@ -19,7 +19,9 @@
  */
 package org.apache.qpid.proton.messenger;
 
-public interface MessengerFactory
+import org.apache.qpid.proton.ProtonFactory;
+
+public interface MessengerFactory extends ProtonFactory
 {
     Messenger createMessenger();
     Messenger createMessenger(String name);

Added: qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/ProtonFactoryLoaderTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/ProtonFactoryLoaderTest.java?rev=1464428&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/ProtonFactoryLoaderTest.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/ProtonFactoryLoaderTest.java Thu Apr  4 10:50:58 2013
@@ -0,0 +1,129 @@
+/*
+ * 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;
+
+import static org.apache.qpid.proton.ProtonFactory.ImplementationType.ANY;
+import static org.apache.qpid.proton.ProtonFactory.ImplementationType.PROTON_C;
+import static org.apache.qpid.proton.ProtonFactory.ImplementationType.PROTON_J;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.qpid.proton.ProtonFactory.ImplementationType;
+import org.apache.qpid.proton.factoryloadertesting.DummyProtonFactory;
+import org.junit.Test;
+
+public class ProtonFactoryLoaderTest
+{
+    private String _previousImplementationType;
+
+    @Test
+    public void testLoadFactoryForAnyImplementationType()
+    {
+        ImplementationType implementationType = ANY;
+
+        ProtonFactoryLoader<DummyProtonFactory> factoryLoader =
+                new ProtonFactoryLoader<DummyProtonFactory>(DummyProtonFactory.class, implementationType);
+
+        assertNotNull(factoryLoader);
+    }
+
+    @Test
+    public void testLoadFactoryForProtonJ()
+    {
+        testImplementationType(PROTON_J);
+    }
+
+    @Test
+    public void testLoadFactoryForProtonC()
+    {
+        testImplementationType(PROTON_C);
+    }
+
+    private void testImplementationType(ImplementationType implementationType)
+    {
+        ProtonFactoryLoader<DummyProtonFactory> factoryLoader =
+                new ProtonFactoryLoader<DummyProtonFactory>(DummyProtonFactory.class, implementationType);
+
+        assertEquals(implementationType, factoryLoader.loadFactory().getImplementationType());
+    }
+
+    @Test
+    public void testLoadFactoryUsingProtonCImplementationTypeFromSystemProperty()
+    {
+        testLoadFactoryUsingImplementationTypeFromSystemProperty(PROTON_C.name());
+    }
+
+    @Test
+    public void testLoadFactoryUsingProtonJImplementationTypeFromSystemProperty()
+    {
+        testLoadFactoryUsingImplementationTypeFromSystemProperty(PROTON_J.name());
+    }
+
+    @Test
+    public void testLoadFactoryUsingDefaultImplementationType()
+    {
+        testLoadFactoryUsingImplementationTypeFromSystemProperty(null);
+    }
+
+    private void testLoadFactoryUsingImplementationTypeFromSystemProperty(String implementationTypeName)
+    {
+        try
+        {
+            setImplementationTypeSystemProperty(implementationTypeName);
+            ProtonFactoryLoader<DummyProtonFactory> factoryLoader = new ProtonFactoryLoader<DummyProtonFactory>(DummyProtonFactory.class);
+            DummyProtonFactory factory = factoryLoader.loadFactory();
+
+            assertNotNull(factory);
+
+            if(implementationTypeName != null)
+            {
+                assertEquals(
+                        ImplementationType.valueOf(implementationTypeName),
+                        factory.getImplementationType());
+            }
+        }
+        finally
+        {
+            resetImplementationTypeSystemProperty();
+        }
+    }
+
+    private void setImplementationTypeSystemProperty(String implementationTypeName)
+    {
+        _previousImplementationType = System.getProperty(ProtonFactoryLoader.IMPLEMENTATION_TYPE_PROPERTY);
+        setOrClearSystemProperty(implementationTypeName);
+    }
+
+    private void resetImplementationTypeSystemProperty()
+    {
+        setOrClearSystemProperty(_previousImplementationType);
+    }
+
+    private void setOrClearSystemProperty(String propertyValue)
+    {
+        if(propertyValue == null)
+        {
+            System.clearProperty(ProtonFactoryLoader.IMPLEMENTATION_TYPE_PROPERTY);
+        }
+        else
+        {
+            System.setProperty(ProtonFactoryLoader.IMPLEMENTATION_TYPE_PROPERTY, propertyValue);
+        }
+    }
+}

Added: qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/transport/ErrorConditionTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/transport/ErrorConditionTest.java?rev=1464428&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/transport/ErrorConditionTest.java (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/amqp/transport/ErrorConditionTest.java Thu Apr  4 10:50:58 2013
@@ -0,0 +1,129 @@
+/*
+ * 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.amqp.transport;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.Collections;
+
+import org.apache.qpid.proton.amqp.Symbol;
+import org.junit.Test;
+
+public class ErrorConditionTest
+{
+    @Test
+    public void testEqualityOfNewlyConstructed()
+    {
+        ErrorCondition new1 = new ErrorCondition();
+        ErrorCondition new2 = new ErrorCondition();
+        assertErrorConditionsEqual(new1, new2);
+    }
+
+    @Test
+    public void testSameObject()
+    {
+        ErrorCondition error = new ErrorCondition();
+        assertErrorConditionsEqual(error, error);
+    }
+
+    @Test
+    public void testConditionEquality()
+    {
+        String symbolValue = "symbol";
+
+        ErrorCondition same1 = new ErrorCondition();
+        same1.setCondition(Symbol.getSymbol(new String(symbolValue)));
+
+        ErrorCondition same2 = new ErrorCondition();
+        same2.setCondition(Symbol.getSymbol(new String(symbolValue)));
+
+        assertErrorConditionsEqual(same1, same2);
+
+        ErrorCondition different = new ErrorCondition();
+        different.setCondition(Symbol.getSymbol("other"));
+
+        assertErrorConditionsNotEqual(same1, different);
+    }
+
+    @Test
+    public void testConditionAndDescriptionEquality()
+    {
+        String symbolValue = "symbol";
+        String descriptionValue = "description";
+
+        ErrorCondition same1 = new ErrorCondition();
+        same1.setCondition(Symbol.getSymbol(new String(symbolValue)));
+        same1.setDescription(new String(descriptionValue));
+
+        ErrorCondition same2 = new ErrorCondition();
+        same2.setCondition(Symbol.getSymbol(new String(symbolValue)));
+        same2.setDescription(new String(descriptionValue));
+
+        assertErrorConditionsEqual(same1, same2);
+
+        ErrorCondition different = new ErrorCondition();
+        different.setCondition(Symbol.getSymbol(symbolValue));
+        different.setDescription("other");
+
+        assertErrorConditionsNotEqual(same1, different);
+    }
+
+    @Test
+    public void testConditionDescriptionInfoEquality()
+    {
+        String symbolValue = "symbol";
+        String descriptionValue = "description";
+
+        ErrorCondition same1 = new ErrorCondition();
+        same1.setCondition(Symbol.getSymbol(new String(symbolValue)));
+        same1.setDescription(new String(descriptionValue));
+        same1.setInfo(Collections.singletonMap(Symbol.getSymbol("key"), "value"));
+
+        ErrorCondition same2 = new ErrorCondition();
+        same2.setCondition(Symbol.getSymbol(new String(symbolValue)));
+        same2.setDescription(new String(descriptionValue));
+        same2.setInfo(Collections.singletonMap(Symbol.getSymbol("key"), "value"));
+
+        assertErrorConditionsEqual(same1, same2);
+
+        ErrorCondition different = new ErrorCondition();
+        different.setCondition(Symbol.getSymbol(symbolValue));
+        different.setDescription(new String(descriptionValue));
+        different.setInfo(Collections.singletonMap(Symbol.getSymbol("other"), "value"));
+
+        assertErrorConditionsNotEqual(same1, different);
+    }
+
+    private void assertErrorConditionsNotEqual(ErrorCondition error1, ErrorCondition error2)
+    {
+        assertThat(error1, is(not(error2)));
+        assertThat(error2, is(not(error1)));
+    }
+
+    private void assertErrorConditionsEqual(ErrorCondition error1, ErrorCondition error2)
+    {
+        assertEquals(error1, error2);
+        assertEquals(error2, error1);
+        assertEquals(error1.hashCode(), error2.hashCode());
+    }
+}

Copied: qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonCFactory.java (from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonCFactory.java?p2=qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonCFactory.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java&r1=1464269&r2=1464428&rev=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonCFactory.java Thu Apr  4 10:50:58 2013
@@ -15,13 +15,15 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.driver;
+package org.apache.qpid.proton.factoryloadertesting;
 
-import java.io.IOException;
 
-public interface DriverFactory
+public class DummyProtonCFactory implements DummyProtonFactory
 {
-    Driver createDriver() throws IOException;
+    @Override
+    public ImplementationType getImplementationType()
+    {
+        return ImplementationType.PROTON_C;
+    }
 }

Copied: qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonFactory.java (from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonFactory.java?p2=qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonFactory.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java&r1=1464269&r2=1464428&rev=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonFactory.java Thu Apr  4 10:50:58 2013
@@ -15,13 +15,11 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.driver;
+package org.apache.qpid.proton.factoryloadertesting;
 
-import java.io.IOException;
+import org.apache.qpid.proton.ProtonFactory;
 
-public interface DriverFactory
+public interface DummyProtonFactory extends ProtonFactory
 {
-    Driver createDriver() throws IOException;
 }

Copied: qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonJFactory.java (from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonJFactory.java?p2=qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonJFactory.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java&r1=1464269&r2=1464428&rev=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/driver/DriverFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/java/org/apache/qpid/proton/factoryloadertesting/DummyProtonJFactory.java Thu Apr  4 10:50:58 2013
@@ -15,13 +15,15 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.driver;
+package org.apache.qpid.proton.factoryloadertesting;
 
-import java.io.IOException;
 
-public interface DriverFactory
+public class DummyProtonJFactory implements DummyProtonFactory
 {
-    Driver createDriver() throws IOException;
+    @Override
+    public ImplementationType getImplementationType()
+    {
+        return ImplementationType.PROTON_J;
+    }
 }

Added: qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/services/org.apache.qpid.proton.factoryloadertesting.DummyProtonFactory
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/services/org.apache.qpid.proton.factoryloadertesting.DummyProtonFactory?rev=1464428&view=auto
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/services/org.apache.qpid.proton.factoryloadertesting.DummyProtonFactory (added)
+++ qpid/proton/trunk/proton-j/proton-api/src/test/resources/META-INF/services/org.apache.qpid.proton.factoryloadertesting.DummyProtonFactory Thu Apr  4 10:50:58 2013
@@ -0,0 +1,2 @@
+org.apache.qpid.proton.factoryloadertesting.DummyProtonCFactory
+org.apache.qpid.proton.factoryloadertesting.DummyProtonJFactory
\ No newline at end of file

Copied: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/ProtonFactoryImpl.java (from r1464269, qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java)
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/ProtonFactoryImpl.java?p2=qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/ProtonFactoryImpl.java&p1=qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java&r1=1464269&r2=1464428&rev=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton-api/src/main/java/org/apache/qpid/proton/codec/DataFactory.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/ProtonFactoryImpl.java Thu Apr  4 10:50:58 2013
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -16,11 +15,14 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.proton.codec;
+package org.apache.qpid.proton;
 
-public interface DataFactory
+public class ProtonFactoryImpl implements ProtonFactory
 {
-    Data createData(long capacity);
+    @Override
+    public final ImplementationType getImplementationType()
+    {
+        return ImplementationType.PROTON_J;
+    }
 }

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/codec/impl/DataFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/codec/impl/DataFactoryImpl.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/codec/impl/DataFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/codec/impl/DataFactoryImpl.java Thu Apr  4 10:50:58 2013
@@ -20,11 +20,12 @@
  */
 package org.apache.qpid.proton.codec.impl;
 
+import org.apache.qpid.proton.ProtonFactoryImpl;
 import org.apache.qpid.proton.ProtonUnsupportedOperationException;
 import org.apache.qpid.proton.codec.Data;
 import org.apache.qpid.proton.codec.DataFactory;
 
-public class DataFactoryImpl implements DataFactory
+public class DataFactoryImpl extends ProtonFactoryImpl implements DataFactory
 {
     @Override
     public Data createData(final long capacity)

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/driver/impl/DriverFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/driver/impl/DriverFactoryImpl.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/driver/impl/DriverFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/driver/impl/DriverFactoryImpl.java Thu Apr  4 10:50:58 2013
@@ -21,17 +21,15 @@ package org.apache.qpid.proton.driver.im
 
 import java.io.IOException;
 
+import org.apache.qpid.proton.ProtonFactoryImpl;
 import org.apache.qpid.proton.driver.Driver;
 import org.apache.qpid.proton.driver.DriverFactory;
 
-public class DriverFactoryImpl implements DriverFactory
+public class DriverFactoryImpl extends ProtonFactoryImpl implements DriverFactory
 {
-
     @Override
     public Driver createDriver() throws IOException
     {
         return new DriverImpl();
     }
-
-
 }

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/EngineFactoryImpl.java Thu Apr  4 10:50:58 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.qpid.proton.engine.impl;
 
+import org.apache.qpid.proton.ProtonFactoryImpl;
 import org.apache.qpid.proton.engine.EngineFactory;
 import org.apache.qpid.proton.engine.ProtonJConnection;
 import org.apache.qpid.proton.engine.ProtonJSslDomain;
@@ -26,7 +27,7 @@ import org.apache.qpid.proton.engine.Pro
 import org.apache.qpid.proton.engine.impl.ssl.SslDomainImpl;
 import org.apache.qpid.proton.engine.impl.ssl.SslPeerDetailsImpl;
 
-public class EngineFactoryImpl implements EngineFactory
+public class EngineFactoryImpl extends ProtonFactoryImpl implements EngineFactory
 {
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
     @Override

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/engine/impl/FrameParser.java Thu Apr  4 10:50:58 2013
@@ -39,12 +39,9 @@ import java.util.Formatter;
 
 class FrameParser implements TransportInput
 {
-
     public static final byte[] HEADER = new byte[8];
 
-    private ErrorCondition _localError;
     private Logger _traceLogger = Logger.getLogger("proton.trace");
-    private Logger _rawLogger = Logger.getLogger("proton.raw");
     private FrameTransport _frameTransport;
     private TransportFrame _heldFrame;
 
@@ -322,8 +319,6 @@ class FrameParser implements TransportIn
                         {
                             ByteBuffer dup = in.duplicate();
                             dup.limit(dup.position()+_buffer.remaining());
-                            int i = _buffer.remaining();
-                            int d = dup.remaining();
                             in.position(in.position()+_buffer.remaining());
                             _buffer.put(dup);
                             oldIn = in;
@@ -362,17 +357,19 @@ class FrameParser implements TransportIn
                         break;
                     }
 
+                    // note that this skips over the extended header if it's present
                     if(dataOffset!=8)
                     {
                         in.position(in.position()+dataOffset-8);
                     }
 
                     // oldIn null iff not working on duplicated buffer
+                    final int frameBodySize = size - dataOffset;
                     if(oldIn == null)
                     {
                         oldIn = in;
                         in = in.duplicate();
-                        final int endPos = in.position() + size - dataOffset;
+                        final int endPos = in.position() + frameBodySize;
                         in.limit(endPos);
                         oldIn.position(endPos);
 
@@ -380,40 +377,50 @@ class FrameParser implements TransportIn
 
                     try
                     {
-                        _decoder.setByteBuffer(in);
-                        Object val = _decoder.readObject();
+                        if (frameBodySize > 0)
+                        {
 
-                        Binary payload;
+                            _decoder.setByteBuffer(in);
+                            Object val = _decoder.readObject();
 
-                        if(in.hasRemaining())
-                        {
-                            byte[] payloadBytes = new byte[in.remaining()];
-                            in.get(payloadBytes);
-                            payload = new Binary(payloadBytes);
-                        }
-                        else
-                        {
-                            payload = null;
-                        }
+                            Binary payload;
 
-                        if(val instanceof FrameBody)
-                        {
-                            FrameBody frameBody = (FrameBody) val;
-                            if(_traceLogger.isLoggable(Level.FINE))
+                            if(in.hasRemaining())
                             {
-                                _traceLogger.log(Level.FINE, "IN: CH["+channel+"] : " + frameBody + (payload == null ? "" : "[" + payload + "]"));
+                                byte[] payloadBytes = new byte[in.remaining()];
+                                in.get(payloadBytes);
+                                payload = new Binary(payloadBytes);
                             }
-                            TransportFrame frame = new TransportFrame(channel, frameBody, payload);
-                            if(!_frameTransport.input(frame))
+                            else
                             {
-                                transportAccepting = false;
-                                _heldFrame = frame;
+                                payload = null;
                             }
 
+                            if(val instanceof FrameBody)
+                            {
+                                FrameBody frameBody = (FrameBody) val;
+                                if(_traceLogger.isLoggable(Level.FINE))
+                                {
+                                    _traceLogger.log(Level.FINE, "IN: CH["+channel+"] : " + frameBody + (payload == null ? "" : "[" + payload + "]"));
+                                }
+                                TransportFrame frame = new TransportFrame(channel, frameBody, payload);
+                                if(!_frameTransport.input(frame))
+                                {
+                                    transportAccepting = false;
+                                    _heldFrame = frame;
+                                }
+
+                            }
+                            else
+                            {
+                                throw new TransportException("Frameparser encountered a "
+                                        + (val == null? "null" : val.getClass())
+                                        + " which is not a " + FrameBody.class);
+                            }
                         }
                         else
                         {
-                            // TODO - error
+                            _traceLogger.finest("Ignored empty frame");
                         }
                         reset();
                         in = oldIn;
@@ -436,7 +443,6 @@ class FrameParser implements TransportIn
         _state = state;
         _size = size;
 
-        _localError = frameParsingError;
         if(_state == State.ERROR )
         {
             throw new TransportException(frameParsingError.getDescription());
@@ -453,6 +459,7 @@ class FrameParser implements TransportIn
 
     private ErrorCondition createFramingError(String description, Object... args)
     {
+        @SuppressWarnings("resource")
         Formatter formatter = new Formatter();
         formatter.format(description, args);
 

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/message/impl/MessageFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/message/impl/MessageFactoryImpl.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/message/impl/MessageFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/message/impl/MessageFactoryImpl.java Thu Apr  4 10:50:58 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.qpid.proton.message.impl;
 
+import org.apache.qpid.proton.ProtonFactoryImpl;
 import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
 import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations;
 import org.apache.qpid.proton.amqp.messaging.Footer;
@@ -28,7 +29,7 @@ import org.apache.qpid.proton.amqp.messa
 import org.apache.qpid.proton.message.MessageFactory;
 import org.apache.qpid.proton.message.ProtonJMessage;
 
-public class MessageFactoryImpl implements MessageFactory
+public class MessageFactoryImpl extends ProtonFactoryImpl implements MessageFactory
 {
 
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)

Modified: qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/messenger/impl/MessengerFactoryImpl.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/messenger/impl/MessengerFactoryImpl.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/messenger/impl/MessengerFactoryImpl.java (original)
+++ qpid/proton/trunk/proton-j/proton/src/main/java/org/apache/qpid/proton/messenger/impl/MessengerFactoryImpl.java Thu Apr  4 10:50:58 2013
@@ -19,10 +19,11 @@
  */
 package org.apache.qpid.proton.messenger.impl;
 
+import org.apache.qpid.proton.ProtonFactoryImpl;
 import org.apache.qpid.proton.messenger.Messenger;
 import org.apache.qpid.proton.messenger.MessengerFactory;
 
-public class MessengerFactoryImpl implements MessengerFactory
+public class MessengerFactoryImpl extends ProtonFactoryImpl implements MessengerFactory
 {
     @SuppressWarnings("deprecation") // TODO remove once the constructor is made non-public (and therefore non-deprecated)
     @Override

Modified: qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtocolTracerEnabler.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtocolTracerEnabler.java?rev=1464428&r1=1464427&r2=1464428&view=diff
==============================================================================
--- qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtocolTracerEnabler.java (original)
+++ qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/ProtocolTracerEnabler.java Thu Apr  4 10:50:58 2013
@@ -48,15 +48,18 @@ public class ProtocolTracerEnabler
 
             setPrococolTracerMethod.invoke(transport, newLoggingProtocolTracer);
         }
-        catch(ClassNotFoundException e)
-        {
-            LOGGER.fine("Protocol tracing disabled because unable to reflectively set a "
-                    + LOGGING_PROTOCOL_TRACER_CLASS_NAME + " instance on the supplied transport which is a: "
-                    + transport.getClass().getName());
-        }
         catch(Exception e)
         {
-            throw new RuntimeException("Unable to set up protocol tracing", e);
+            if(e instanceof ClassNotFoundException || e instanceof NoSuchMethodException)
+            {
+                LOGGER.fine("Protocol tracing disabled because unable to reflectively set a "
+                        + LOGGING_PROTOCOL_TRACER_CLASS_NAME + " instance on the supplied transport which is a: "
+                        + transport.getClass().getName());
+            }
+            else
+            {
+                throw new RuntimeException("Unable to set up protocol tracing", e);
+            }
         }
     }
 }

Added: qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/AmqpFramer.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/AmqpFramer.java?rev=1464428&view=auto
==============================================================================
--- qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/AmqpFramer.java (added)
+++ qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/AmqpFramer.java Thu Apr  4 10:50:58 2013
@@ -0,0 +1,91 @@
+/*
+ * 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.systemtests.engine;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.amqp.transport.FrameBody;
+import org.apache.qpid.proton.codec.AMQPDefinedTypes;
+import org.apache.qpid.proton.codec.DecoderImpl;
+import org.apache.qpid.proton.codec.EncoderImpl;
+import org.apache.qpid.proton.codec.WritableBuffer;
+
+public class AmqpFramer
+{
+    // My test data is generated by the decoder and encoder from proton-j
+    // although at run-time the Engine internally uses its own implementation.
+
+    private DecoderImpl _decoder = new DecoderImpl();
+    private EncoderImpl _encoder = new EncoderImpl(_decoder);
+
+    public AmqpFramer()
+    {
+        AMQPDefinedTypes.registerAllTypes(_decoder, _encoder);
+    }
+
+    public byte[] createEmptyFrame(int channel)
+    {
+        byte[] emptyFrame = generateFrame(channel, null);
+        return emptyFrame;
+    }
+
+    public byte[] generateFrame(int channel, FrameBody frameBody)
+    {
+        byte[] emptyExtendedHeader = new byte[] {};
+        return generateFrame(channel, emptyExtendedHeader, frameBody);
+    }
+
+    public byte[] generateFrame(int channel, byte[] extendedHeader, FrameBody frameBody)
+    {
+        assertEquals("Extended header must be multiple of 4 bytes", 0, extendedHeader.length % 4);
+        int numberOfExtendedHeaderFourByteWords = extendedHeader.length / 4;
+
+        ByteBuffer buffer = ByteBuffer.allocate(1024);
+
+        buffer.position(8); // leave hole for frame header
+        _encoder.setByteBuffer(new WritableBuffer.ByteBufferWrapper(buffer));
+
+        // write extended header - maybe empty
+        buffer.put(extendedHeader);
+        // write frame body
+        if (frameBody != null)
+        {
+            _encoder.writeObject(frameBody);
+        }
+
+        int frameSize = buffer.position();
+        int framePreambleSizeInFourByteWords = 2;
+        byte dataOffsetFourByteWords = (byte)(framePreambleSizeInFourByteWords + numberOfExtendedHeaderFourByteWords);
+        byte amqpFrameType = 0;
+        buffer.rewind();
+        buffer.putInt(frameSize);
+        buffer.put(dataOffsetFourByteWords);
+        buffer.put(amqpFrameType); // AMQP_FRAME_TYPE
+        buffer.putShort((short)channel);
+
+        byte[] target = new byte[frameSize];
+
+        buffer.rewind();
+        buffer.get(target, 0, frameSize);
+        return target;
+    }
+}

Added: qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java?rev=1464428&view=auto
==============================================================================
--- qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java (added)
+++ qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ConnectionTest.java Thu Apr  4 10:50:58 2013
@@ -0,0 +1,806 @@
+/*
+ * 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.systemtests.engine;
+
+
+import static java.util.EnumSet.of;
+import static org.apache.qpid.proton.engine.EndpointState.ACTIVE;
+import static org.apache.qpid.proton.engine.EndpointState.CLOSED;
+import static org.apache.qpid.proton.engine.EndpointState.UNINITIALIZED;
+import static org.apache.qpid.proton.systemtests.engine.ProtonFactoryTestFixture.isProtonC;
+import static org.apache.qpid.proton.systemtests.engine.ProtonFactoryTestFixture.isProtonJ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeTrue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.transport.Close;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.amqp.transport.Open;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.Endpoint;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.EngineFactory;
+import org.apache.qpid.proton.engine.Session;
+import org.apache.qpid.proton.engine.Transport;
+import org.apache.qpid.proton.engine.TransportException;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Implicitly tests both {@link Connection} and {@link Transport} (e.g. for stuff like the AMQP header exchange).
+ *
+ * TODO test that the connection properties, connection capability, and error info maps have keys that are exclusively of type Symbol.
+ */
+public class ConnectionTest
+{
+    private static final String SERVER_CONTAINER = "serverContainer";
+    private static final String CLIENT_CONTAINER = "clientContainer";
+
+    private final ProtonFactoryTestFixture _protonFactoryTestFixture = new ProtonFactoryTestFixture();
+
+    private EngineFactory _clientFactory = _protonFactoryTestFixture.getFactory1();
+    private EngineFactory _serverFactory = _protonFactoryTestFixture.getFactory2();
+
+    private final Transport _clientTransport = _clientFactory.createTransport();
+    private final Transport _serverTransport = _serverFactory.createTransport();
+
+    private final TransportPumper _pumper = new TransportPumper(_clientTransport, _serverTransport);
+
+    private final Connection _clientConnection = _clientFactory.createConnection();
+    private final Connection _serverConnection = _serverFactory.createConnection();
+
+    private final AmqpFramer _framer = new AmqpFramer();
+
+    // 2.4.1 Opening A Connection
+
+    /** */
+    @Test
+    public void testOpenConnection()
+    {
+        _pumper.pumpAll();
+
+        bindAndOpenConnections();
+    }
+
+
+    /** Container id is a mandatory field so this should cause an error */
+    @Test(expected=TransportException.class)
+    public void testReceiptOfOpenWithoutContainerId_causesTODO()
+    {
+        _pumper.pumpAll();
+
+        Open openWithoutContainerId = new Open();
+        byte[] openFrameBuffer = _framer.generateFrame(0, openWithoutContainerId);
+
+        int serverConsumed = _serverTransport.input(openFrameBuffer, 0, openFrameBuffer.length);
+        assertEquals(openFrameBuffer.length, serverConsumed);
+        assumeTrue(isProtonJ(_serverFactory));
+    }
+
+    /**
+     * "Prior to any explicit negotiation, the maximum frame size is 512 (MIN-MAX-FRAME-SIZE) and the maximum channel number is 0"
+     * */
+    @Test
+    public void testReceiptOfOpenExactlyDefaultMaximumFrameSize()
+    {
+        _pumper.pumpAll();
+
+        _serverTransport.bind(_serverConnection);
+        assertEnpointState(_serverConnection, UNINITIALIZED, UNINITIALIZED);
+
+        // containerId and extended header sized to give an open frame
+        // exactly 512 bytes in length.
+        String containerId = "12345678";
+        int extendedHeaderSize = 122 * 4;
+
+        Open open = new Open();
+        open.setContainerId(containerId);
+        byte[] openFrameBuffer = _framer.generateFrame(0, new byte[extendedHeaderSize], open);
+        assertEquals("Test requires a frame of size MIN_MAX_FRAME_SIZE",
+                Transport.MIN_MAX_FRAME_SIZE, openFrameBuffer.length);
+
+        int serverConsumed = _serverTransport.input(openFrameBuffer, 0, openFrameBuffer.length);
+        assertEquals(openFrameBuffer.length, serverConsumed);
+
+        // Verify that the server has seen the Open arrive
+        assertEnpointState(_serverConnection, UNINITIALIZED, ACTIVE);
+        assertEquals(containerId, _serverConnection.getRemoteContainer());
+    }
+
+    /**
+     * "Prior to any explicit negotiation, the maximum frame size is 512 (MIN-MAX-FRAME-SIZE) and the maximum channel number is 0"
+     */
+    @Test
+    public void testReceiptOfOpenBiggerThanDefaultMaximumFrameSize_causesTODO()
+    {
+        _pumper.pumpAll();
+
+        _serverTransport.bind(_serverConnection);
+        assertEnpointState(_serverConnection, UNINITIALIZED, UNINITIALIZED);
+
+        // containerId and extended header sized to give an open frame
+        // 1 byte larger the than 512 bytes permitted before negotiation by the AMQP spec.
+
+        String containerId = "123456789";
+        int extendedHeaderSize = 122 * 4;
+
+        Open bigOpen = new Open();
+        bigOpen.setContainerId(containerId);
+        byte[] openFrameBuffer = _framer.generateFrame(0, new byte[extendedHeaderSize], bigOpen);
+        assertEquals("Test requires a frame of size MIN_MAX_FRAME_SIZE + 1",
+                Transport.MIN_MAX_FRAME_SIZE + 1, openFrameBuffer.length);
+
+        int serverConsumed = _serverTransport.input(openFrameBuffer, 0, openFrameBuffer.length);
+        assertEquals(openFrameBuffer.length, serverConsumed);
+
+        // TODO server should indicate error but currently both implementations currently process
+        // the larger frames.   The following assertions should fail but currently pass.
+        assertEnpointState(_serverConnection, UNINITIALIZED, ACTIVE);
+        assertNotNull(_serverConnection.getRemoteContainer());
+    }
+
+    @Test
+    public void testReceiptOfSecondOpen_causesTODO()
+    {
+        bindAndOpenConnections();
+
+        Open secondOpen  = new Open(); // erroneous
+        secondOpen.setContainerId("secondOpen");
+        byte[] openFrameBuffer = _framer.generateFrame(0, secondOpen);
+
+        int serverConsumed = _serverTransport.input(openFrameBuffer, 0, openFrameBuffer.length);
+        assertEquals(openFrameBuffer.length, serverConsumed);
+
+        // TODO server should indicate error but currently both implementation currently
+        // allow this condition
+    }
+
+    /** "each peer MUST send an open frame before sending any other frames"
+     *
+     * @see ConnectionTest#testReceiptOfCloseBeforeOpen_causesTODO()
+     */
+    public void testReceiptOfIntialFrameOtherThanOpen_causesTODO()
+    {
+    }
+
+    /**
+     * 2.4.5 "Implementations MUST be prepared to handle empty frames arriving on any valid channel"
+     *
+     * TODO consider moving to {@link TransportTest} once we have a less Connection-centric way of
+     * checking health than calling {@link #bindAndOpenConnections()}
+     */
+    @Test
+    public void testReceiptOfInitialEmptyFrame_isAllowed()
+    {
+        _pumper.pumpAll();
+
+        byte[] emptyFrame = _framer.createEmptyFrame(0);
+        int bytesConsumed = _serverTransport.input(emptyFrame, 0, emptyFrame.length);
+        assertEquals(emptyFrame.length, bytesConsumed);
+
+        bindAndOpenConnections();
+    }
+
+
+    /** "The open frame can only be sent on channel 0" */
+    @Test
+    @Ignore("Reinstate once it is agreed how error condition will be reported to user of API")
+    public void testReceiptOfOpenOnNonZeroChannelNumber_causesTODO()
+    {
+        _pumper.pumpAll();
+
+        Open open = new Open();
+        open.setContainerId(SERVER_CONTAINER);
+
+        int nonZeroChannelId = 1;
+        byte[] buf = _framer.generateFrame(nonZeroChannelId, open);
+        int rv = _serverTransport.input(buf, 0, buf.length);
+        // TODO server should indicate error
+    }
+
+
+    /**
+     * "After sending the open frame and reading its partner's open frame a peer MUST operate within
+     * mutually acceptable limitations from this point forward"
+     * see 2.7.1 "A peer that receives an oversized frame MUST close the connection with the framing-error error-code"
+     */
+    public void testReceiptOfFrameLargerThanAgreedMaximumSize_causesTODO()
+    {
+    }
+
+    public void testThatSentFramesAreWithinMaximumSizeLimit()
+    {
+    }
+
+    // 2.4.2 Pipelined Open
+
+    /** test that the other peer accepts the pipelined frames and creates an open connection */
+    @Test
+    public void testReceiptOfOpenUsingPipelining()
+    {
+        _clientConnection.setContainer(CLIENT_CONTAINER);
+        _clientTransport.bind(_clientConnection);
+        _clientConnection.open();
+
+        _serverTransport.bind(_serverConnection);
+
+        // when pipelining, we delay pumping until the connection is both bound and opened
+        _pumper.pumpOnceFromClientToServer();
+
+        assertEnpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+        assertEnpointState(_serverConnection, UNINITIALIZED, ACTIVE);
+    }
+
+
+    /** test that the other peer accepts the pipelined frames and creates an already-closed connection */
+    @Test
+    public void testReceiptOfOpenThenCloseUsingPipelining()
+    {
+        _clientConnection.setContainer(CLIENT_CONTAINER);
+        _clientTransport.bind(_clientConnection);
+        _clientConnection.open();
+        _clientConnection.close();
+
+        _serverTransport.bind(_serverConnection);
+        _pumper.pumpOnceFromClientToServer();
+
+        assertEnpointState(_clientConnection, CLOSED, UNINITIALIZED);
+        if (!isProtonC(_serverFactory))
+        {
+            assertEnpointState(_serverConnection, UNINITIALIZED, CLOSED);
+        }
+    }
+
+    /**
+     * Similar to {@link #testReceiptOfOpenUsingPipelining()} but opens both ends of the connection
+     * so we can actually use it.
+     */
+    @Test
+    public void testOpenConnectionUsingPipelining()
+    {
+        _clientConnection.setContainer(CLIENT_CONTAINER);
+        _clientTransport.bind(_clientConnection);
+        _clientConnection.open();
+
+
+        _serverConnection.setContainer(SERVER_CONTAINER);
+        _serverTransport.bind(_serverConnection);
+        _serverConnection.open();
+
+        _pumper.pumpAll();
+
+        assertEnpointState(_clientConnection, ACTIVE, ACTIVE);
+        assertEnpointState(_serverConnection, ACTIVE, ACTIVE);
+
+        assertConnectionIsUsable();
+    }
+
+    // 2.4.3 Closing A Connection and 2.7.9 Close
+
+    /**
+     * "each peer MUST write a close frame"
+     * Omits the optional error field
+     */
+    @Test
+    public void testCloseConnection()
+    {
+        bindAndOpenConnections();
+
+        assertEnpointState(_clientConnection, ACTIVE, ACTIVE);
+        assertEnpointState(_serverConnection, ACTIVE, ACTIVE);
+
+        _clientConnection.close();
+
+        assertEnpointState(_clientConnection, CLOSED, ACTIVE);
+        assertEnpointState(_serverConnection, ACTIVE, ACTIVE);
+
+        _pumper.pumpAll();
+
+        assertEnpointState(_clientConnection, CLOSED, ACTIVE);
+        assertEnpointState(_serverConnection, ACTIVE, CLOSED);
+
+        _serverConnection.close();
+
+        assertEnpointState(_clientConnection, CLOSED, ACTIVE);
+        assertEnpointState(_serverConnection, CLOSED, CLOSED);
+
+        _pumper.pumpAll();
+
+        assertEnpointState(_clientConnection, CLOSED, CLOSED);
+        assertEnpointState(_serverConnection, CLOSED, CLOSED);
+    }
+
+    /**
+     * "each peer MUST write a close frame with a code indicating the reason for closing"
+     * Also see 2.8.16 Connection Error
+     */
+    @Test
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public void testCloseConnectionWithErrorCode_causesCloseFrameContainingErrorCodeToBeSent()
+    {
+        // TODO Proton-c fails if no remote condition is set
+        assumeTrue(isProtonJ(_clientFactory) && isProtonJ(_serverFactory));
+
+        bindAndOpenConnections();
+
+        /*
+         * TODO javadoc for {@link Connection#getCondition()} states null is returned if there is no condition,
+         * this differs from the implementation of both Proton-c and Proton-j.
+         */
+        assertNull(_clientConnection.getCondition().getCondition());
+        assertNull(_serverConnection.getCondition().getCondition());
+
+        assertNull(_clientConnection.getRemoteCondition().getCondition());
+        assertNull(_serverConnection.getRemoteCondition().getCondition());
+
+        ErrorCondition clientErrorCondition = new ErrorCondition(Symbol.getSymbol("myerror"), "mydescription");
+        Map info = new HashMap();
+        info.put(Symbol.getSymbol("simplevalue"), "value");
+        info.put(Symbol.getSymbol("list"), Arrays.asList("e1", "e2", "e3"));
+        clientErrorCondition.setInfo(info);
+        _clientConnection.setCondition(clientErrorCondition);
+
+        _clientConnection.close();
+        _pumper.pumpAll();
+
+        assertEquals(clientErrorCondition, _serverConnection.getRemoteCondition());
+        assertNull(_serverConnection.getCondition().getCondition());
+    }
+
+    /**
+     * "each peer MUST write a close frame with a code indicating the reason for closing"
+     */
+    public void testReceiptOfConnectionCloseContainingErrorCode_allowsErrorCodeToBeObserved()
+    {
+    }
+
+    /**
+     * A test for when the connection close frame contains a session error
+     * rather than a connection error. This is allowed by the spec.
+     */
+    public void testReceiptOfConnectionCloseContainingNonConnectionErrorCode_causesTODO()
+    {
+    }
+
+    /** "This frame MUST be the last thing ever written onto a connection." */
+    public void testUsingProtonAfterClosingConnection_doesntCauseFrameToBeSent()
+    {
+    }
+
+    /** "This frame MUST be the last thing ever written onto a connection." */
+    public void testReceiptOfFrameAfterClose_causesTODO()
+    {
+    }
+
+    /** "A close frame MAY be received on any channel up to the maximum channel number negotiated in open" */
+    public void testReceiptOfCloseOnNonZeroChannelNumber_causesHappyPathTODO()
+    {
+    }
+
+    /**
+     * "each peer MUST send an open frame before sending any other frames"
+     */
+    @Test
+    public void testReceiptOfCloseBeforeOpen_causesTODO()
+    {
+        _pumper.pumpAll();
+
+        Close surprisingClose = new Close();
+
+        byte[] buf = _framer.generateFrame(0, surprisingClose);
+        assumeTrue(isProtonJ(_serverFactory));
+        // TODO Proton-C: function pn_do_close causes a SEGV fault if you try and close an unopened connection
+        _serverTransport.input(buf, 0, buf.length);
+
+        // TODO server should indicate error
+    }
+
+    // 2.4.4 Simultaneous Close
+
+    /** "both endpoints MAY simultaneously" */
+    public void testPeersCloseConnectionSimultaneously()
+    {
+    }
+
+    // 2.4.5 Idle Timeout Of A Connection
+
+    public void testReceiptOfFrame_preventsIdleTimeoutOccurring()
+    {
+    }
+
+    /** "If the threshold is exceeded, then a peer SHOULD try to gracefully close the connection using a close frame with an error explaining why" */
+    public void testReceiptOfFrameTooLate_causedIdleTimeoutToOccur()
+    {
+    }
+
+    /** "Each peer has its own (independent) idle timeout." */
+    public void testPeersWithDifferentIdleTimeouts_timeOutAtTheCorrectTimes()
+    {
+    }
+
+    /**
+     * "If the value is not set, then the sender does not have an idle time-out. However,
+     * senders doing this SHOULD be aware that implementations MAY choose to use an internal default
+     * to efficiently manage a peer's resources."
+     */
+    public void testReceiptOfFrameWithZeroIdleTimeout_causesNoIdleFramesToBeSent()
+    {
+    }
+
+    /**
+     * "If a peer can not, for any reason support a proposed idle timeout,
+     * then it SHOULD close the connection using a close frame with an error explaining why"
+     */
+    public void testReceiptOfOpenWithUnsupportedTimeout_causesCloseWithError()
+    {
+    }
+
+    /**
+     * implementations ... MUST use channel 0 if a maximum channel number has not yet been negotiated
+     * (i.e., before an open frame has been received)
+     */
+    public void testReceiptOfEmptyFrameOnNonZeroChannelBeforeMaximumChannelsNegotiated_causesTODO()
+    {
+    }
+
+
+    // 2.4.7 State transitions
+
+    /**
+     * The DISCARDING state is a variant of the CLOSE_SENT state where the close is triggered by an error.
+     * In this case any incoming frames on the connection MUST be silently discarded until the peer's close frame is received
+     */
+    public void testReceiptOfFrameWhenInDiscardingState_isIgnored()
+    {
+    }
+
+    // 2.7.1 Open
+
+    public void testReceiptOfOpen_containerCanBeRetrieved()
+    {
+    }
+
+    /**
+     * The spec says:
+     * "If no hostname is provided the receiving peer SHOULD select a default based on its own configuration"
+     * but Proton's Engine layer does not do any defaulting - this is the responsibility
+     * of other layers e.g. Messenger or Driver.
+     */
+    public void testReceiptOfOpenWithoutHostname_nullHostnameIsRetrieved()
+    {
+    }
+
+    public void testReceiptOfOpenWithHostname_hostnameCanBeRetrieved()
+    {
+    }
+
+    /**
+     * "Both peers MUST accept frames of up to 512 (MIN-MAX-FRAME-SIZE) octets."
+     */
+    public void testReceiptOfOpenWithMaximumFramesizeLowerThanMinMaxFrameSize_causesTODO()
+    {
+    }
+
+    public void testInitiatingPeerAndReceivingPeerUseDifferentMaxFrameSizes()
+    {
+    }
+
+    public void testReceiptOfSessionBeginThatBreaksChannelMax_causesTODO()
+    {
+    }
+
+    public void testCreationOfSessionThatBreaksChannelMax_causesTODO()
+    {
+    }
+
+    public void testOpenConnectionWithPeersUsingUnequalChannelMax_enforcesLowerOfTwoValues()
+    {
+    }
+
+    public void testOpenConnectionWithOnePeerUsingUnsetChannelMax_enforcesTheSetValue()
+    {
+    }
+
+    public void testReceiptOfBeginWithInUseChannelId_causesTODO()
+    {
+    }
+
+    /** "If a session is locally initiated, the remote-channel MUST NOT be set." */
+    public void testReceiptOfUnsolicitedBeginWithChannelId_causesTODO()
+    {
+    }
+
+    /**
+     * "When an endpoint responds to a remotely initiated session, the remote-channel MUST be set
+     * to the channel on which the remote session sent the begin."
+     */
+    public void testThatBeginResponseContainsChannelId()
+    {
+    }
+
+    /**
+     * I imagine we will want to begin ChannelMax number of sessions, then end
+     * a session from the 'middle'.  Then check we are correctly begin a new
+     * channel.
+     */
+    public void testEnd_channelNumberAvailableForReuse()
+    {
+    }
+
+    public void testReceiptOfOpenWithOutgoingLocales_outgoingLocalesCanBeRetrieved()
+    {
+    }
+
+    /** "A null value or an empty list implies that only en-US is supported. " */
+    public void testReceiptOfOpenWithNullOutgoingLocales_defaultOutgoingLocaleCanBeRetrieved()
+    {
+    }
+
+    /** "A null value or an empty list implies that only en-US is supported. " */
+    public void testReceiptOfOpenWithEmptyListOfOutgoingLocales_defaultOutgoingLocaleCanBeRetrieved()
+    {
+    }
+
+    public void testReceiptOfOpenWithIncomingLocales_incomingLocalesCanBeRetrieved()
+    {
+    }
+
+    /** "A null value or an empty list implies that only en-US is supported. " */
+    public void testReceiptOfOpenWithNullIncomingLocales_defaultIncomingLocaleCanBeRetrieved()
+    {
+    }
+
+    /** "A null value or an empty list implies that only en-US is supported. " */
+    public void testReceiptOfOpenWithEmptyListOfIncomingLocales_defaultIncomingLocaleCanBeRetrieved()
+    {
+    }
+
+    // TODO It seems that currently Proton-j merely exposes the remote capabilities to
+    // the user and is seems to be a end-user responsibility to enforce "If the receiver of the
+    // offered-capabilities requires an extension capability which is not present in the
+    // offered-capability list then it MUST close the connection.".  However, i wonder if this
+    // is an omission -- surely Proton could valid that request desirable capabilities are
+    // offered by the remote???
+
+    public void testReceiptOfOpenWithOfferedCapabilities_offeredCapabilitiesCanBeRetrieved()
+    {
+    }
+
+    public void testReceiptOfOpenWithDesiredCapabilities_desiredCapabilitiesCanBeRetrieved()
+    {
+    }
+
+    public void testReceiptOfOpenWithProperties_propertiesCanBeRetrieved()
+    {
+    }
+
+    // Transport/Connection related api-inspired tests
+
+    /**
+     * TODO is there a limit on the number of connections?
+     * Also try closing them in a different order to their creation.
+     */
+    public void testCreateMultipleConnections()
+    {
+    }
+
+    public void testBindTwoConnectionsToATransport_causesTODO()
+    {
+    }
+
+    public void testBindAConnectionToTwoTransports_causesTODO()
+    {
+    }
+
+    /**
+     * TODO possibly try to bind this "opened" connection too if it doesn't go pop before this.
+     */
+    public void testOpenBeforeBind_causesTODO()
+    {
+    }
+
+    public void testOpenTwice_throwsExceptionTODO()
+    {
+    }
+
+    public void testOpenAfterClose_throwsExceptionTODO()
+    {
+    }
+
+    // Connection.java-related api-inspired tests
+
+    /**
+     * also test that the session appears in the connection's session list
+     */
+    public void testCreateSession()
+    {
+    }
+
+    public void testSessionHeadWhenNoSessionsExist_returnsNull()
+    {
+    }
+
+    public void testSessionHead_returnsSessionsMatchingCriteria()
+    {
+    }
+
+    public void testLinkHeadWhenNoLinksExist_returnsNull()
+    {
+    }
+
+    public void testLinkHead_returnsLinksMatchingCriteria()
+    {
+    }
+
+    public void testGetWorkHeadWhenNoWork_returnsNull()
+    {
+    }
+
+    public void testGetWorkHeadWhenOneDeliveryIsPending_returnsTheDelivery()
+    {
+    }
+
+    /**
+     * use a name that is longer than the limit of AMQShortString
+     */
+    public void testSetContainerWithLongName_isAllowed()
+    {
+    }
+
+    public void testSetContainerWithNullName_throwsException()
+    {
+    }
+
+    public void testSetContainerWithEmptyName_throwsException()
+    {
+    }
+
+    public void testSetContainerAfterOpeningConnection_throwsExceptionTODO()
+    {
+    }
+
+    public void testOpenWithoutContainerName_throwsExceptionTODO()
+    {
+    }
+
+    public void testGetRemoteContainerBeforeOpen_returnsNull()
+    {
+    }
+
+    public void testGetRemoteContainerBeforeReceiptOfOpen_returnsNull()
+    {
+    }
+
+    public void testSetHostnameWithLongName_isAllowed()
+    {
+    }
+
+    /**
+     * Proton does not require the conventional foo.bar.com format for hostnames.
+     */
+    public void testSetHostnameWithNonstandardName_isAllowed()
+    {
+    }
+
+    public void testSetHostnameAfterOpeningConnection_throwsExceptionTODO()
+    {
+    }
+
+    public void testSetOfferedCapabilitiesAfterOpeningConnection_throwsExceptionTODO()
+    {
+    }
+
+    public void testSetDesiredCapabilitiesAfterOpeningConnection_throwsExceptionTODO()
+    {
+    }
+
+    public void testSetPropertiesAfterOpeningConnection_throwsExceptionTODO()
+    {
+    }
+
+    // Endpoint api-inspired tests
+
+    public void testGetLocalStateBeforeOpen_returnsUninitialised()
+    {
+    }
+
+    public void testGetLocalStateAfterClose_returnsClosed()
+    {
+    }
+
+    public void testGetRemoteStateBeforeReceiptOfOpen_returnsUninitialised()
+    {
+    }
+
+    public void testGetRemoteStateAfterReceiptOfClose_returnsClosed()
+    {
+    }
+
+    public void testFree_isAllowed()
+    {
+    }
+
+    public void testSetContext_contextCanBeRetrieved()
+    {
+    }
+
+    public void testGetContextWithoutSettingContext_returnsNull()
+    {
+    }
+
+    private void assertConnectionIsUsable()
+    {
+        Session clientSesion = _clientConnection.session();
+        clientSesion.open();
+        _pumper.pumpAll();
+
+        Session serverSession = _serverConnection.sessionHead(of(UNINITIALIZED), of(ACTIVE));
+        serverSession.open();
+        _pumper.pumpAll();
+
+        assertEnpointState(clientSesion, ACTIVE, ACTIVE);
+        assertEnpointState(serverSession, ACTIVE, ACTIVE);
+    }
+
+    private void bindAndOpenConnections()
+    {
+        // TODO should we be checking local and remote error conditions as part of this?
+
+        _clientConnection.setContainer(CLIENT_CONTAINER);
+        _serverConnection.setContainer(SERVER_CONTAINER);
+
+        assertEnpointState(_clientConnection, UNINITIALIZED, UNINITIALIZED);
+        assertEnpointState(_serverConnection, UNINITIALIZED, UNINITIALIZED);
+
+        _clientTransport.bind(_clientConnection);
+        _serverTransport.bind(_serverConnection);
+
+        _clientConnection.open();
+
+        assertEnpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+        assertEnpointState(_serverConnection, UNINITIALIZED, UNINITIALIZED);
+
+        _pumper.pumpAll();
+
+        assertEnpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+        assertEnpointState(_serverConnection, UNINITIALIZED, ACTIVE);
+
+        _serverConnection.open();
+
+        assertEnpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+        assertEnpointState(_serverConnection, ACTIVE, ACTIVE);
+
+        _pumper.pumpAll();
+
+        assertEnpointState(_clientConnection, ACTIVE, ACTIVE);
+        assertEnpointState(_serverConnection, ACTIVE, ACTIVE);
+    }
+
+    private void assertEnpointState(Endpoint endpoint, EndpointState localState, EndpointState remoteState)
+    {
+        assertEquals("Unexpected local state", localState, endpoint.getLocalState());
+        assertEquals("Unexpected remote state", remoteState, endpoint.getRemoteState());
+    }
+}

Added: qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ProtonFactoryTestFixture.java
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ProtonFactoryTestFixture.java?rev=1464428&view=auto
==============================================================================
--- qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ProtonFactoryTestFixture.java (added)
+++ qpid/proton/trunk/tests/java/org/apache/qpid/proton/systemtests/engine/ProtonFactoryTestFixture.java Thu Apr  4 10:50:58 2013
@@ -0,0 +1,54 @@
+/*
+ * 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.systemtests.engine;
+
+import static org.apache.qpid.proton.ProtonFactory.ImplementationType.PROTON_C;
+import static org.apache.qpid.proton.ProtonFactory.ImplementationType.PROTON_J;
+
+import org.apache.qpid.proton.ProtonFactoryLoader;
+import org.apache.qpid.proton.engine.EngineFactory;
+
+public class ProtonFactoryTestFixture
+{
+    private final EngineFactory _engineFactory = new ProtonFactoryLoader<EngineFactory>(EngineFactory.class).loadFactory();
+
+    public static boolean isProtonC(EngineFactory engineFactory)
+    {
+        return engineFactory.getImplementationType() == PROTON_C;
+    }
+
+    public static boolean isProtonJ(EngineFactory engineFactory)
+    {
+        return engineFactory.getImplementationType() == PROTON_J;
+    }
+
+    /**
+     * TODO support different implementations for factory1 and factory2
+     */
+    public EngineFactory getFactory1()
+    {
+        return _engineFactory;
+    }
+
+    public EngineFactory getFactory2()
+    {
+        return _engineFactory;
+    }
+
+}



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