You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2018/04/25 17:15:15 UTC

[1/2] qpid-jms git commit: QPIDJMS-384 Allow for extensions to provide information to the connection

Repository: qpid-jms
Updated Branches:
  refs/heads/master 0933c9eee -> 8bf97c4b7


http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java
index f716f79..f3d7ec3 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java
@@ -16,11 +16,17 @@
  */
 package org.apache.qpid.jms.transports;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
+import javax.net.ssl.SSLContext;
+
 import org.apache.qpid.jms.test.QpidJmsTestCase;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * Test for class TransportOptions
@@ -39,11 +45,51 @@ public class TransportOptionsTest extends QpidJmsTestCase {
     public static final boolean TEST_USE_EPOLL_VALUE = !TransportOptions.DEFAULT_USE_EPOLL;
     public static final boolean TEST_TRACE_BYTES_VALUE = !TransportOptions.DEFAULT_TRACE_BYTES;
 
+    private static final String PASSWORD = "password";
+    private static final String CLIENT_KEYSTORE = "src/test/resources/client-jks.keystore";
+    private static final String CLIENT_TRUSTSTORE = "src/test/resources/client-jks.truststore";
+    private static final String KEYSTORE_TYPE = "jks";
+    private static final String KEY_ALIAS = "myTestAlias";
+    private static final String CONTEXT_PROTOCOL = "TLSv1.1";
+    private static final boolean TRUST_ALL = true;
+    private static final boolean VERIFY_HOST = true;
+
+    private static final int TEST_DEFAULT_SSL_PORT = 5681;
+
+    private static final String[] ENABLED_PROTOCOLS = new String[] {"TLSv1.2"};
+    private static final String[] DISABLED_PROTOCOLS = new String[] {"SSLv3", "TLSv1.2"};
+    private static final String[] ENABLED_CIPHERS = new String[] {"CIPHER_A", "CIPHER_B"};
+    private static final String[] DISABLED_CIPHERS = new String[] {"CIPHER_C"};
+
+    private static final SSLContext SSL_CONTEXT = Mockito.mock(SSLContext.class);
+
+    private static final String JAVAX_NET_SSL_KEY_STORE = "javax.net.ssl.keyStore";
+    private static final String JAVAX_NET_SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
+    private static final String JAVAX_NET_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
+    private static final String JAVAX_NET_SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
+
     @Test
     public void testCreate() {
         TransportOptions options = new TransportOptions();
 
         assertEquals(TransportOptions.DEFAULT_TCP_NO_DELAY, options.isTcpNoDelay());
+        assertEquals(TransportOptions.DEFAULT_TRUST_ALL, options.isTrustAll());
+        assertEquals(TransportOptions.DEFAULT_STORE_TYPE, options.getKeyStoreType());
+        assertEquals(TransportOptions.DEFAULT_STORE_TYPE, options.getTrustStoreType());
+
+        assertEquals(TransportOptions.DEFAULT_CONTEXT_PROTOCOL, options.getContextProtocol());
+        assertNull(options.getEnabledProtocols());
+        assertArrayEquals(TransportOptions.DEFAULT_DISABLED_PROTOCOLS.toArray(new String[0]),
+                          options.getDisabledProtocols());
+        assertNull(options.getEnabledCipherSuites());
+        assertNull(options.getDisabledCipherSuites());
+
+        assertNull(options.getKeyStoreLocation());
+        assertNull(options.getKeyStorePassword());
+        assertNull(options.getTrustStoreLocation());
+        assertNull(options.getTrustStorePassword());
+        assertNull(options.getKeyAlias());
+        assertNull(options.getSslContextOverride());
     }
 
     @Test
@@ -76,8 +122,22 @@ public class TransportOptionsTest extends QpidJmsTestCase {
         assertEquals(TEST_SO_TIMEOUT, options.getSoTimeout());
         assertEquals(TEST_CONNECT_TIMEOUT, options.getConnectTimeout());
         assertEquals(TEST_DEFAULT_TCP_PORT, options.getDefaultTcpPort());
+        assertEquals(TEST_DEFAULT_SSL_PORT, options.getDefaultSslPort());
         assertEquals(TEST_USE_EPOLL_VALUE, options.isUseEpoll());
         assertEquals(TEST_TRACE_BYTES_VALUE, options.isTraceBytes());
+        assertEquals(CLIENT_KEYSTORE, options.getKeyStoreLocation());
+        assertEquals(PASSWORD, options.getKeyStorePassword());
+        assertEquals(CLIENT_TRUSTSTORE, options.getTrustStoreLocation());
+        assertEquals(PASSWORD, options.getTrustStorePassword());
+        assertEquals(KEYSTORE_TYPE, options.getKeyStoreType());
+        assertEquals(KEYSTORE_TYPE, options.getTrustStoreType());
+        assertEquals(KEY_ALIAS, options.getKeyAlias());
+        assertEquals(CONTEXT_PROTOCOL, options.getContextProtocol());
+        assertEquals(SSL_CONTEXT, options.getSslContextOverride());
+        assertArrayEquals(ENABLED_PROTOCOLS,options.getEnabledProtocols());
+        assertArrayEquals(DISABLED_PROTOCOLS,options.getDisabledProtocols());
+        assertArrayEquals(ENABLED_CIPHERS,options.getEnabledCipherSuites());
+        assertArrayEquals(DISABLED_CIPHERS,options.getDisabledCipherSuites());
     }
 
     @Test
@@ -133,6 +193,108 @@ public class TransportOptionsTest extends QpidJmsTestCase {
         options.setTrafficClass(255);
     }
 
+    @Test
+    public void testCreateAndConfigure() {
+        TransportOptions options = createSslOptions();
+
+        assertEquals(TEST_SEND_BUFFER_SIZE, options.getSendBufferSize());
+        assertEquals(TEST_RECEIVE_BUFFER_SIZE, options.getReceiveBufferSize());
+        assertEquals(TEST_TRAFFIC_CLASS, options.getTrafficClass());
+        assertEquals(TEST_TCP_NO_DELAY, options.isTcpNoDelay());
+        assertEquals(TEST_TCP_KEEP_ALIVE, options.isTcpKeepAlive());
+        assertEquals(TEST_SO_LINGER, options.getSoLinger());
+        assertEquals(TEST_SO_TIMEOUT, options.getSoTimeout());
+        assertEquals(TEST_CONNECT_TIMEOUT, options.getConnectTimeout());
+
+        assertEquals(CLIENT_KEYSTORE, options.getKeyStoreLocation());
+        assertEquals(PASSWORD, options.getKeyStorePassword());
+        assertEquals(CLIENT_TRUSTSTORE, options.getTrustStoreLocation());
+        assertEquals(PASSWORD, options.getTrustStorePassword());
+        assertEquals(KEYSTORE_TYPE, options.getKeyStoreType());
+        assertEquals(KEYSTORE_TYPE, options.getTrustStoreType());
+        assertEquals(KEY_ALIAS, options.getKeyAlias());
+        assertEquals(CONTEXT_PROTOCOL, options.getContextProtocol());
+        assertEquals(SSL_CONTEXT, options.getSslContextOverride());
+        assertArrayEquals(ENABLED_PROTOCOLS,options.getEnabledProtocols());
+        assertArrayEquals(DISABLED_PROTOCOLS,options.getDisabledProtocols());
+        assertArrayEquals(ENABLED_CIPHERS,options.getEnabledCipherSuites());
+        assertArrayEquals(DISABLED_CIPHERS,options.getDisabledCipherSuites());
+    }
+
+    private TransportOptions createSslOptions() {
+        TransportOptions options = new TransportOptions();
+
+        options.setKeyStoreLocation(CLIENT_KEYSTORE);
+        options.setTrustStoreLocation(CLIENT_TRUSTSTORE);
+        options.setKeyStorePassword(PASSWORD);
+        options.setTrustStorePassword(PASSWORD);
+        options.setStoreType(KEYSTORE_TYPE);
+        options.setTrustAll(TRUST_ALL);
+        options.setVerifyHost(VERIFY_HOST);
+        options.setKeyAlias(KEY_ALIAS);
+        options.setContextProtocol(CONTEXT_PROTOCOL);
+        options.setEnabledProtocols(ENABLED_PROTOCOLS);
+        options.setDisabledProtocols(DISABLED_PROTOCOLS);
+        options.setEnabledCipherSuites(ENABLED_CIPHERS);
+        options.setDisabledCipherSuites(DISABLED_CIPHERS);
+
+        options.setSendBufferSize(TEST_SEND_BUFFER_SIZE);
+        options.setReceiveBufferSize(TEST_RECEIVE_BUFFER_SIZE);
+        options.setTrafficClass(TEST_TRAFFIC_CLASS);
+        options.setTcpNoDelay(TEST_TCP_NO_DELAY);
+        options.setTcpKeepAlive(TEST_TCP_KEEP_ALIVE);
+        options.setSoLinger(TEST_SO_LINGER);
+        options.setSoTimeout(TEST_SO_TIMEOUT);
+        options.setConnectTimeout(TEST_CONNECT_TIMEOUT);
+        options.setDefaultSslPort(TEST_DEFAULT_SSL_PORT);
+        options.setSslContextOverride(SSL_CONTEXT);
+
+        return options;
+    }
+
+    @Test
+    public void testSslSystemPropertiesInfluenceDefaults() {
+        String keystore = "keystore";
+        String keystorePass = "keystorePass";
+        String truststore = "truststore";
+        String truststorePass = "truststorePass";
+
+        setSslSystemPropertiesForCurrentTest(keystore, keystorePass, truststore, truststorePass);
+
+        TransportOptions options1 = new TransportOptions();
+
+        assertEquals(keystore, options1.getKeyStoreLocation());
+        assertEquals(keystorePass, options1.getKeyStorePassword());
+        assertEquals(truststore, options1.getTrustStoreLocation());
+        assertEquals(truststorePass, options1.getTrustStorePassword());
+
+        keystore +="2";
+        keystorePass +="2";
+        truststore +="2";
+        truststorePass +="2";
+
+        setSslSystemPropertiesForCurrentTest(keystore, keystorePass, truststore, truststorePass);
+
+        TransportOptions options2 = new TransportOptions();
+
+        assertEquals(keystore, options2.getKeyStoreLocation());
+        assertEquals(keystorePass, options2.getKeyStorePassword());
+        assertEquals(truststore, options2.getTrustStoreLocation());
+        assertEquals(truststorePass, options2.getTrustStorePassword());
+
+        assertNotEquals(options1.getKeyStoreLocation(), options2.getKeyStoreLocation());
+        assertNotEquals(options1.getKeyStorePassword(), options2.getKeyStorePassword());
+        assertNotEquals(options1.getTrustStoreLocation(), options2.getTrustStoreLocation());
+        assertNotEquals(options1.getTrustStorePassword(), options2.getTrustStorePassword());
+    }
+
+    private void setSslSystemPropertiesForCurrentTest(String keystore, String keystorePassword, String truststore, String truststorePassword) {
+        setTestSystemProperty(JAVAX_NET_SSL_KEY_STORE, keystore);
+        setTestSystemProperty(JAVAX_NET_SSL_KEY_STORE_PASSWORD, keystorePassword);
+        setTestSystemProperty(JAVAX_NET_SSL_TRUST_STORE, truststore);
+        setTestSystemProperty(JAVAX_NET_SSL_TRUST_STORE_PASSWORD, truststorePassword);
+    }
+
     private TransportOptions createNonDefaultOptions() {
         TransportOptions options = new TransportOptions();
 
@@ -145,8 +307,20 @@ public class TransportOptionsTest extends QpidJmsTestCase {
         options.setSoTimeout(TEST_SO_TIMEOUT);
         options.setConnectTimeout(TEST_CONNECT_TIMEOUT);
         options.setDefaultTcpPort(TEST_DEFAULT_TCP_PORT);
+        options.setDefaultSslPort(TEST_DEFAULT_SSL_PORT);
         options.setUseEpoll(TEST_USE_EPOLL_VALUE);
         options.setTraceBytes(TEST_TRACE_BYTES_VALUE);
+        options.setKeyStoreLocation(CLIENT_KEYSTORE);
+        options.setKeyStorePassword(PASSWORD);
+        options.setTrustStoreLocation(CLIENT_TRUSTSTORE);
+        options.setTrustStorePassword(PASSWORD);
+        options.setKeyAlias(KEY_ALIAS);
+        options.setContextProtocol(CONTEXT_PROTOCOL);
+        options.setSslContextOverride(SSL_CONTEXT);
+        options.setEnabledProtocols(ENABLED_PROTOCOLS);
+        options.setEnabledCipherSuites(ENABLED_CIPHERS);
+        options.setDisabledProtocols(DISABLED_PROTOCOLS);
+        options.setDisabledCipherSuites(DISABLED_CIPHERS);
 
         return options;
     }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSslOptionsTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSslOptionsTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSslOptionsTest.java
deleted file mode 100644
index 7d1a30d..0000000
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSslOptionsTest.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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.jms.transports;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
-
-import javax.net.ssl.SSLContext;
-
-import org.apache.qpid.jms.test.QpidJmsTestCase;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Test for class TransportSslOptions
- */
-public class TransportSslOptionsTest extends QpidJmsTestCase {
-
-    private static final String PASSWORD = "password";
-    private static final String CLIENT_KEYSTORE = "src/test/resources/client-jks.keystore";
-    private static final String CLIENT_TRUSTSTORE = "src/test/resources/client-jks.truststore";
-    private static final String KEYSTORE_TYPE = "jks";
-    private static final String KEY_ALIAS = "myTestAlias";
-    private static final String CONTEXT_PROTOCOL = "TLSv1.1";
-    private static final boolean TRUST_ALL = true;
-    private static final boolean VERIFY_HOST = true;
-
-    private static final int TEST_SEND_BUFFER_SIZE = 128 * 1024;
-    private static final int TEST_RECEIVE_BUFFER_SIZE = TEST_SEND_BUFFER_SIZE;
-    private static final int TEST_TRAFFIC_CLASS = 1;
-    private static final boolean TEST_TCP_NO_DELAY = false;
-    private static final boolean TEST_TCP_KEEP_ALIVE = true;
-    private static final int TEST_SO_LINGER = Short.MAX_VALUE;
-    private static final int TEST_SO_TIMEOUT = 10;
-    private static final int TEST_CONNECT_TIMEOUT = 90000;
-    private static final int TEST_DEFAULT_SSL_PORT = 5681;
-
-    private static final String[] ENABLED_PROTOCOLS = new String[] {"TLSv1.2"};
-    private static final String[] DISABLED_PROTOCOLS = new String[] {"SSLv3", "TLSv1.2"};
-    private static final String[] ENABLED_CIPHERS = new String[] {"CIPHER_A", "CIPHER_B"};
-    private static final String[] DISABLED_CIPHERS = new String[] {"CIPHER_C"};
-
-    private static final SSLContext SSL_CONTEXT = Mockito.mock(SSLContext.class);
-
-    private static final String JAVAX_NET_SSL_KEY_STORE = "javax.net.ssl.keyStore";
-    private static final String JAVAX_NET_SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
-    private static final String JAVAX_NET_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
-    private static final String JAVAX_NET_SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
-
-    @Test
-    public void testCreate() {
-        TransportSslOptions options = new TransportSslOptions();
-
-        assertEquals(TransportSslOptions.DEFAULT_TRUST_ALL, options.isTrustAll());
-        assertEquals(TransportSslOptions.DEFAULT_STORE_TYPE, options.getKeyStoreType());
-        assertEquals(TransportSslOptions.DEFAULT_STORE_TYPE, options.getTrustStoreType());
-
-        assertEquals(TransportSslOptions.DEFAULT_CONTEXT_PROTOCOL, options.getContextProtocol());
-        assertNull(options.getEnabledProtocols());
-        assertArrayEquals(TransportSslOptions.DEFAULT_DISABLED_PROTOCOLS.toArray(new String[0]),
-                          options.getDisabledProtocols());
-        assertNull(options.getEnabledCipherSuites());
-        assertNull(options.getDisabledCipherSuites());
-
-        assertNull(options.getKeyStoreLocation());
-        assertNull(options.getKeyStorePassword());
-        assertNull(options.getTrustStoreLocation());
-        assertNull(options.getTrustStorePassword());
-        assertNull(options.getKeyAlias());
-        assertNull(options.getSslContextOverride());
-    }
-
-    @Test
-    public void testCreateAndConfigure() {
-        TransportSslOptions options = createSslOptions();
-
-        assertEquals(TEST_SEND_BUFFER_SIZE, options.getSendBufferSize());
-        assertEquals(TEST_RECEIVE_BUFFER_SIZE, options.getReceiveBufferSize());
-        assertEquals(TEST_TRAFFIC_CLASS, options.getTrafficClass());
-        assertEquals(TEST_TCP_NO_DELAY, options.isTcpNoDelay());
-        assertEquals(TEST_TCP_KEEP_ALIVE, options.isTcpKeepAlive());
-        assertEquals(TEST_SO_LINGER, options.getSoLinger());
-        assertEquals(TEST_SO_TIMEOUT, options.getSoTimeout());
-        assertEquals(TEST_CONNECT_TIMEOUT, options.getConnectTimeout());
-
-        assertEquals(CLIENT_KEYSTORE, options.getKeyStoreLocation());
-        assertEquals(PASSWORD, options.getKeyStorePassword());
-        assertEquals(CLIENT_TRUSTSTORE, options.getTrustStoreLocation());
-        assertEquals(PASSWORD, options.getTrustStorePassword());
-        assertEquals(KEYSTORE_TYPE, options.getKeyStoreType());
-        assertEquals(KEYSTORE_TYPE, options.getTrustStoreType());
-        assertEquals(KEY_ALIAS, options.getKeyAlias());
-        assertEquals(CONTEXT_PROTOCOL, options.getContextProtocol());
-        assertEquals(SSL_CONTEXT, options.getSslContextOverride());
-        assertArrayEquals(ENABLED_PROTOCOLS,options.getEnabledProtocols());
-        assertArrayEquals(DISABLED_PROTOCOLS,options.getDisabledProtocols());
-        assertArrayEquals(ENABLED_CIPHERS,options.getEnabledCipherSuites());
-        assertArrayEquals(DISABLED_CIPHERS,options.getDisabledCipherSuites());
-    }
-
-    @Test
-    public void testClone() {
-        TransportSslOptions options = createSslOptions().clone();
-
-        assertEquals(TEST_SEND_BUFFER_SIZE, options.getSendBufferSize());
-        assertEquals(TEST_RECEIVE_BUFFER_SIZE, options.getReceiveBufferSize());
-        assertEquals(TEST_TRAFFIC_CLASS, options.getTrafficClass());
-        assertEquals(TEST_TCP_NO_DELAY, options.isTcpNoDelay());
-        assertEquals(TEST_TCP_KEEP_ALIVE, options.isTcpKeepAlive());
-        assertEquals(TEST_SO_LINGER, options.getSoLinger());
-        assertEquals(TEST_SO_TIMEOUT, options.getSoTimeout());
-        assertEquals(TEST_CONNECT_TIMEOUT, options.getConnectTimeout());
-        assertEquals(TEST_DEFAULT_SSL_PORT, options.getDefaultSslPort());
-
-        assertEquals(CLIENT_KEYSTORE, options.getKeyStoreLocation());
-        assertEquals(PASSWORD, options.getKeyStorePassword());
-        assertEquals(CLIENT_TRUSTSTORE, options.getTrustStoreLocation());
-        assertEquals(PASSWORD, options.getTrustStorePassword());
-        assertEquals(KEYSTORE_TYPE, options.getKeyStoreType());
-        assertEquals(KEYSTORE_TYPE, options.getTrustStoreType());
-        assertEquals(KEY_ALIAS, options.getKeyAlias());
-        assertEquals(CONTEXT_PROTOCOL, options.getContextProtocol());
-        assertEquals(SSL_CONTEXT, options.getSslContextOverride());
-        assertArrayEquals(ENABLED_PROTOCOLS,options.getEnabledProtocols());
-        assertArrayEquals(DISABLED_PROTOCOLS,options.getDisabledProtocols());
-        assertArrayEquals(ENABLED_CIPHERS,options.getEnabledCipherSuites());
-        assertArrayEquals(DISABLED_CIPHERS,options.getDisabledCipherSuites());
-    }
-
-    private TransportSslOptions createSslOptions() {
-        TransportSslOptions options = new TransportSslOptions();
-
-        options.setKeyStoreLocation(CLIENT_KEYSTORE);
-        options.setTrustStoreLocation(CLIENT_TRUSTSTORE);
-        options.setKeyStorePassword(PASSWORD);
-        options.setTrustStorePassword(PASSWORD);
-        options.setStoreType(KEYSTORE_TYPE);
-        options.setTrustAll(TRUST_ALL);
-        options.setVerifyHost(VERIFY_HOST);
-        options.setKeyAlias(KEY_ALIAS);
-        options.setContextProtocol(CONTEXT_PROTOCOL);
-        options.setEnabledProtocols(ENABLED_PROTOCOLS);
-        options.setDisabledProtocols(DISABLED_PROTOCOLS);
-        options.setEnabledCipherSuites(ENABLED_CIPHERS);
-        options.setDisabledCipherSuites(DISABLED_CIPHERS);
-
-        options.setSendBufferSize(TEST_SEND_BUFFER_SIZE);
-        options.setReceiveBufferSize(TEST_RECEIVE_BUFFER_SIZE);
-        options.setTrafficClass(TEST_TRAFFIC_CLASS);
-        options.setTcpNoDelay(TEST_TCP_NO_DELAY);
-        options.setTcpKeepAlive(TEST_TCP_KEEP_ALIVE);
-        options.setSoLinger(TEST_SO_LINGER);
-        options.setSoTimeout(TEST_SO_TIMEOUT);
-        options.setConnectTimeout(TEST_CONNECT_TIMEOUT);
-        options.setDefaultSslPort(TEST_DEFAULT_SSL_PORT);
-        options.setSslContextOverride(SSL_CONTEXT);
-
-        return options;
-    }
-
-    @Test
-    public void testSslSystemPropertiesInfluenceDefaults() {
-        String keystore = "keystore";
-        String keystorePass = "keystorePass";
-        String truststore = "truststore";
-        String truststorePass = "truststorePass";
-
-        setSslSystemPropertiesForCurrentTest(keystore, keystorePass, truststore, truststorePass);
-
-        TransportSslOptions options1 = new TransportSslOptions();
-
-        assertEquals(keystore, options1.getKeyStoreLocation());
-        assertEquals(keystorePass, options1.getKeyStorePassword());
-        assertEquals(truststore, options1.getTrustStoreLocation());
-        assertEquals(truststorePass, options1.getTrustStorePassword());
-
-        keystore +="2";
-        keystorePass +="2";
-        truststore +="2";
-        truststorePass +="2";
-
-        setSslSystemPropertiesForCurrentTest(keystore, keystorePass, truststore, truststorePass);
-
-        TransportSslOptions options2 = new TransportSslOptions();
-
-        assertEquals(keystore, options2.getKeyStoreLocation());
-        assertEquals(keystorePass, options2.getKeyStorePassword());
-        assertEquals(truststore, options2.getTrustStoreLocation());
-        assertEquals(truststorePass, options2.getTrustStorePassword());
-
-        assertNotEquals(options1.getKeyStoreLocation(), options2.getKeyStoreLocation());
-        assertNotEquals(options1.getKeyStorePassword(), options2.getKeyStorePassword());
-        assertNotEquals(options1.getTrustStoreLocation(), options2.getTrustStoreLocation());
-        assertNotEquals(options1.getTrustStorePassword(), options2.getTrustStorePassword());
-    }
-
-    private void setSslSystemPropertiesForCurrentTest(String keystore, String keystorePassword, String truststore, String truststorePassword) {
-        setTestSystemProperty(JAVAX_NET_SSL_KEY_STORE, keystore);
-        setTestSystemProperty(JAVAX_NET_SSL_KEY_STORE_PASSWORD, keystorePassword);
-        setTestSystemProperty(JAVAX_NET_SSL_TRUST_STORE, truststore);
-        setTestSystemProperty(JAVAX_NET_SSL_TRUST_STORE_PASSWORD, truststorePassword);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java
index bf6e995..23b58ff 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java
@@ -68,7 +68,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testLegacySslProtocolsDisabledByDefault() throws Exception {
-        TransportSslOptions options = createJksSslOptions(null);
+        TransportOptions options = createJksSslOptions(null);
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -83,7 +83,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslContextJksStore() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -93,7 +93,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslContextJksStoreWithConfiguredContextProtocol() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         String contextProtocol = "TLSv1.2";
         options.setContextProtocol(contextProtocol);
 
@@ -105,42 +105,42 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test(expected = UnrecoverableKeyException.class)
     public void testCreateSslContextNoKeyStorePassword() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setKeyStorePassword(null);
         TransportSupport.createSslContext(options);
     }
 
     @Test(expected = IOException.class)
     public void testCreateSslContextWrongKeyStorePassword() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setKeyStorePassword("wrong");
         TransportSupport.createSslContext(options);
     }
 
     @Test(expected = IOException.class)
     public void testCreateSslContextBadPathToKeyStore() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE + ".bad");
         TransportSupport.createSslContext(options);
     }
 
     @Test(expected = IOException.class)
     public void testCreateSslContextWrongTrustStorePassword() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setTrustStorePassword("wrong");
         TransportSupport.createSslContext(options);
     }
 
     @Test(expected = IOException.class)
     public void testCreateSslContextBadPathToTrustStore() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE + ".bad");
         TransportSupport.createSslContext(options);
     }
 
     @Test
     public void testCreateSslContextJceksStore() throws Exception {
-        TransportSslOptions options = createJceksSslOptions();
+        TransportOptions options = createJceksSslOptions();
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -150,7 +150,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslContextPkcs12Store() throws Exception {
-        TransportSslOptions options = createPkcs12SslOptions();
+        TransportOptions options = createPkcs12SslOptions();
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -160,14 +160,14 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test(expected = IOException.class)
     public void testCreateSslContextIncorrectStoreType() throws Exception {
-        TransportSslOptions options = createPkcs12SslOptions();
+        TransportOptions options = createPkcs12SslOptions();
         options.setStoreType(KEYSTORE_JCEKS_TYPE);
         TransportSupport.createSslContext(options);
     }
 
     @Test
     public void testCreateSslEngineFromPkcs12Store() throws Exception {
-        TransportSslOptions options = createPkcs12SslOptions();
+        TransportOptions options = createPkcs12SslOptions();
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -181,7 +181,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocols() throws Exception {
-        TransportSslOptions options = createPkcs12SslOptions(ENABLED_PROTOCOLS);
+        TransportOptions options = createPkcs12SslOptions(ENABLED_PROTOCOLS);
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -194,7 +194,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineFromJksStore() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -208,7 +208,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocols() throws Exception {
-        TransportSslOptions options = createJksSslOptions(ENABLED_PROTOCOLS);
+        TransportOptions options = createJksSslOptions(ENABLED_PROTOCOLS);
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -222,7 +222,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
     @Test
     public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocols() throws Exception {
         // Discover the default enabled protocols
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         SSLEngine directEngine = createSSLEngineDirectly(options);
         String[] protocols = directEngine.getEnabledProtocols();
         assertTrue("There were no initial protocols to choose from!", protocols.length > 0);
@@ -242,7 +242,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
     @Test
     public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtocols() throws Exception {
         // Discover the default enabled protocols
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         SSLEngine directEngine = createSSLEngineDirectly(options);
         String[] protocols = directEngine.getEnabledProtocols();
         assertTrue("There were no initial protocols to choose from!", protocols.length > 1);
@@ -266,7 +266,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
     @Test
     public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphers() throws Exception {
         // Discover the default enabled ciphers
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         SSLEngine directEngine = createSSLEngineDirectly(options);
         String[] ciphers = directEngine.getEnabledCipherSuites();
         assertTrue("There were no initial ciphers to choose from!", ciphers.length > 0);
@@ -286,7 +286,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
     @Test
     public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphers() throws Exception {
         // Discover the default enabled ciphers
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         SSLEngine directEngine = createSSLEngineDirectly(options);
         String[] ciphers = directEngine.getEnabledCipherSuites();
         assertTrue("There were no initial ciphers to choose from!", ciphers.length > 0);
@@ -306,7 +306,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
     @Test
     public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphers() throws Exception {
         // Discover the default enabled ciphers
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         SSLEngine directEngine = createSSLEngineDirectly(options);
         String[] ciphers = directEngine.getEnabledCipherSuites();
         assertTrue("There werent enough initial ciphers to choose from!", ciphers.length > 1);
@@ -329,7 +329,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineFromJceksStore() throws Exception {
-        TransportSslOptions options = createJceksSslOptions();
+        TransportOptions options = createJceksSslOptions();
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -343,7 +343,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocols() throws Exception {
-        TransportSslOptions options = createJceksSslOptions(ENABLED_PROTOCOLS);
+        TransportOptions options = createJceksSslOptions(ENABLED_PROTOCOLS);
 
         SSLContext context = TransportSupport.createSslContext(options);
         assertNotNull(context);
@@ -356,7 +356,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineWithVerifyHost() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setVerifyHost(true);
 
         SSLContext context = TransportSupport.createSslContext(options);
@@ -370,7 +370,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslEngineWithoutVerifyHost() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setVerifyHost(false);
 
         SSLContext context = TransportSupport.createSslContext(options);
@@ -384,7 +384,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslContextWithKeyAliasWhichDoesntExist() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setKeyAlias(ALIAS_DOES_NOT_EXIST);
 
         try {
@@ -397,7 +397,7 @@ public class TransportSupportTest extends QpidJmsTestCase {
 
     @Test
     public void testCreateSslContextWithKeyAliasWhichRepresentsNonKeyEntry() throws Exception {
-        TransportSslOptions options = createJksSslOptions();
+        TransportOptions options = createJksSslOptions();
         options.setKeyAlias(ALIAS_CA_CERT);
 
         try {
@@ -408,12 +408,12 @@ public class TransportSupportTest extends QpidJmsTestCase {
         }
     }
 
-    private TransportSslOptions createJksSslOptions() {
+    private TransportOptions createJksSslOptions() {
         return createJksSslOptions(null);
     }
 
-    private TransportSslOptions createJksSslOptions(String[] enabledProtocols) {
-        TransportSslOptions options = new TransportSslOptions();
+    private TransportOptions createJksSslOptions(String[] enabledProtocols) {
+        TransportOptions options = new TransportOptions();
 
         options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE);
         options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE);
@@ -427,12 +427,12 @@ public class TransportSupportTest extends QpidJmsTestCase {
         return options;
     }
 
-    private TransportSslOptions createJceksSslOptions() {
+    private TransportOptions createJceksSslOptions() {
         return createJceksSslOptions(null);
     }
 
-    private TransportSslOptions createJceksSslOptions(String[] enabledProtocols) {
-        TransportSslOptions options = new TransportSslOptions();
+    private TransportOptions createJceksSslOptions(String[] enabledProtocols) {
+        TransportOptions options = new TransportOptions();
 
         options.setKeyStoreLocation(CLIENT_JCEKS_KEYSTORE);
         options.setTrustStoreLocation(CLIENT_JCEKS_TRUSTSTORE);
@@ -446,12 +446,12 @@ public class TransportSupportTest extends QpidJmsTestCase {
         return options;
     }
 
-    private TransportSslOptions createPkcs12SslOptions() {
+    private TransportOptions createPkcs12SslOptions() {
         return createPkcs12SslOptions(null);
     }
 
-    private TransportSslOptions createPkcs12SslOptions(String[] enabledProtocols) {
-        TransportSslOptions options = new TransportSslOptions();
+    private TransportOptions createPkcs12SslOptions(String[] enabledProtocols) {
+        TransportOptions options = new TransportOptions();
 
         options.setKeyStoreLocation(CLIENT_PKCS12_KEYSTORE);
         options.setTrustStoreLocation(CLIENT_PKCS12_TRUSTSTORE);
@@ -465,10 +465,9 @@ public class TransportSupportTest extends QpidJmsTestCase {
         return options;
     }
 
-    private SSLEngine createSSLEngineDirectly(TransportSslOptions options) throws Exception {
+    private SSLEngine createSSLEngineDirectly(TransportOptions options) throws Exception {
         SSLContext context = TransportSupport.createSslContext(options);
         SSLEngine engine = context.createSSLEngine();
         return engine;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyEchoServer.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyEchoServer.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyEchoServer.java
index 32e86f8..3e9cbdc 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyEchoServer.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyEchoServer.java
@@ -32,12 +32,12 @@ public class NettyEchoServer extends NettyServer {
 
     private static final Logger LOG = LoggerFactory.getLogger(NettyEchoServer.class);
 
-    public NettyEchoServer(TransportOptions options, boolean needClientAuth) {
-        super(options, needClientAuth);
+    public NettyEchoServer(TransportOptions options, boolean secure, boolean needClientAuth) {
+        super(options, secure, needClientAuth);
     }
 
-    public NettyEchoServer(TransportOptions options, boolean needClientAuth, boolean webSocketServer) {
-        super(options, needClientAuth, webSocketServer);
+    public NettyEchoServer(TransportOptions options, boolean secure, boolean needClientAuth, boolean webSocketServer) {
+        super(options, secure, needClientAuth, webSocketServer);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyServer.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyServer.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyServer.java
index 55e3624..afde7d6 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyServer.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyServer.java
@@ -31,7 +31,6 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 
 import org.apache.qpid.jms.transports.TransportOptions;
-import org.apache.qpid.jms.transports.TransportSslOptions;
 import org.apache.qpid.jms.transports.TransportSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,6 +61,7 @@ import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
 import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame;
 import io.netty.handler.codec.http.websocketx.WebSocketFrame;
 import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
+import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
 import io.netty.handler.logging.LogLevel;
 import io.netty.handler.logging.LoggingHandler;
 import io.netty.handler.ssl.SslHandler;
@@ -83,6 +83,7 @@ public abstract class NettyServer implements AutoCloseable {
     private EventLoopGroup workerGroup;
     private Channel serverChannel;
     private final TransportOptions options;
+    private final boolean secure;
     private int serverPort;
     private final boolean needClientAuth;
     private final boolean webSocketServer;
@@ -90,25 +91,27 @@ public abstract class NettyServer implements AutoCloseable {
     private String webSocketPath = WEBSOCKET_PATH;
     private volatile boolean fragmentWrites;
     private volatile SslHandler sslHandler;
+    private volatile HandshakeComplete handshakeComplete;
 
     private final AtomicBoolean started = new AtomicBoolean();
 
-    public NettyServer(TransportOptions options) {
-        this(options, false);
+    public NettyServer(TransportOptions options, boolean secure) {
+        this(options, secure, false);
     }
 
-    public NettyServer(TransportOptions options, boolean needClientAuth) {
-        this(options, needClientAuth, false);
+    public NettyServer(TransportOptions options, boolean secure, boolean needClientAuth) {
+        this(options, secure, needClientAuth, false);
     }
 
-    public NettyServer(TransportOptions options, boolean needClientAuth, boolean webSocketServer) {
+    public NettyServer(TransportOptions options, boolean secure, boolean needClientAuth, boolean webSocketServer) {
+        this.secure = secure;
         this.options = options;
         this.needClientAuth = needClientAuth;
         this.webSocketServer = webSocketServer;
     }
 
     public boolean isSecureServer() {
-        return options instanceof TransportSslOptions;
+        return secure;
     }
 
     public boolean isWebSocketServer() {
@@ -143,6 +146,10 @@ public abstract class NettyServer implements AutoCloseable {
         return fragmentWrites;
     }
 
+    public HandshakeComplete getHandshakeComplete() {
+        return handshakeComplete;
+    }
+
     protected URI getConnectionURI() throws Exception {
         if (!started.get()) {
             throw new IllegalStateException("Cannot get URI of non-started server");
@@ -193,10 +200,9 @@ public abstract class NettyServer implements AutoCloseable {
 
                 @Override
                 public void initChannel(Channel ch) throws Exception {
-                    if (options instanceof TransportSslOptions) {
-                        TransportSslOptions sslOptions = (TransportSslOptions) options;
-                        SSLContext context = TransportSupport.createSslContext(sslOptions);
-                        SSLEngine engine = TransportSupport.createSslEngine(context, sslOptions);
+                    if (isSecureServer()) {
+                        SSLContext context = TransportSupport.createSslContext(options);
+                        SSLEngine engine = TransportSupport.createSslEngine(context, options);
                         engine.setUseClientMode(false);
                         engine.setNeedClientAuth(needClientAuth);
                         sslHandler = new SslHandler(engine);
@@ -273,7 +279,7 @@ public abstract class NettyServer implements AutoCloseable {
         public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
             LOG.trace("NettyServerHandler: Channel write: {}", msg);
             if (isWebSocketServer() && msg instanceof ByteBuf) {
-                if(isFragmentWrites()) {
+                if (isFragmentWrites()) {
                     ByteBuf orig = (ByteBuf) msg;
                     int origIndex = orig.readerIndex();
                     int split = orig.readableBytes()/2;
@@ -300,6 +306,13 @@ public abstract class NettyServer implements AutoCloseable {
     private class NettyServerInboundHandler extends ChannelInboundHandlerAdapter  {
 
         @Override
+        public void userEventTriggered(ChannelHandlerContext context, Object payload) {
+            if (payload instanceof HandshakeComplete) {
+                handshakeComplete = (HandshakeComplete) payload;
+            }
+        }
+
+        @Override
         public void channelActive(final ChannelHandlerContext ctx) {
             LOG.info("NettyServerHandler -> New active channel: {}", ctx.channel());
             SslHandler handler = ctx.pipeline().get(SslHandler.class);

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySimpleAmqpServer.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySimpleAmqpServer.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySimpleAmqpServer.java
index 1525144..01d1f32 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySimpleAmqpServer.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySimpleAmqpServer.java
@@ -85,16 +85,16 @@ public class NettySimpleAmqpServer extends NettyServer {
     private boolean allowNonSaslConnections;
     private ConnectionIntercepter connectionIntercepter;
 
-    public NettySimpleAmqpServer(TransportOptions options) {
+    public NettySimpleAmqpServer(TransportOptions options, boolean secure) {
         this(options, false, false);
     }
 
-    public NettySimpleAmqpServer(TransportOptions options, boolean needClientAuth) {
-        this(options, needClientAuth, false);
+    public NettySimpleAmqpServer(TransportOptions options, boolean secure, boolean needClientAuth) {
+        this(options, secure, needClientAuth, false);
     }
 
-    public NettySimpleAmqpServer(TransportOptions options, boolean needClientAuth, boolean webSocketServer) {
-        super(options, needClientAuth, webSocketServer);
+    public NettySimpleAmqpServer(TransportOptions options, boolean secure, boolean needClientAuth, boolean webSocketServer) {
+        super(options, secure, needClientAuth, webSocketServer);
 
         this.serializer = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
 

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactoryTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactoryTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactoryTest.java
index c37a29e..054d41c 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactoryTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactoryTest.java
@@ -32,7 +32,6 @@ import java.util.List;
 
 import org.apache.qpid.jms.transports.Transport;
 import org.apache.qpid.jms.transports.TransportOptions;
-import org.apache.qpid.jms.transports.TransportSslOptions;
 import org.junit.Test;
 
 /**
@@ -90,18 +89,15 @@ public class NettySslTransportFactoryTest {
         assertEquals(TransportOptions.DEFAULT_SO_LINGER, options.getSoLinger());
         assertEquals(TransportOptions.DEFAULT_SO_TIMEOUT, options.getSoTimeout());
 
-        assertTrue(options instanceof TransportSslOptions);
-        TransportSslOptions sslOptions = (TransportSslOptions) options;
+        assertEquals(TransportOptions.DEFAULT_CONTEXT_PROTOCOL, options.getContextProtocol());
+        assertNull(options.getEnabledProtocols());
+        assertArrayEquals(TransportOptions.DEFAULT_DISABLED_PROTOCOLS.toArray(new String[0]), options.getDisabledProtocols());
+        assertNull(options.getEnabledCipherSuites());
 
-        assertEquals(TransportSslOptions.DEFAULT_CONTEXT_PROTOCOL, sslOptions.getContextProtocol());
-        assertNull(sslOptions.getEnabledProtocols());
-        assertArrayEquals(TransportSslOptions.DEFAULT_DISABLED_PROTOCOLS.toArray(new String[0]), sslOptions.getDisabledProtocols());
-        assertNull(sslOptions.getEnabledCipherSuites());
-
-        assertEquals(TransportSslOptions.DEFAULT_STORE_TYPE, sslOptions.getKeyStoreType());
-        assertEquals(TransportSslOptions.DEFAULT_STORE_TYPE, sslOptions.getTrustStoreType());
-        assertEquals(TransportSslOptions.DEFAULT_VERIFY_HOST, sslOptions.isVerifyHost());
-        assertNull(sslOptions.getKeyAlias());
+        assertEquals(TransportOptions.DEFAULT_STORE_TYPE, options.getKeyStoreType());
+        assertEquals(TransportOptions.DEFAULT_STORE_TYPE, options.getTrustStoreType());
+        assertEquals(TransportOptions.DEFAULT_VERIFY_HOST, options.isVerifyHost());
+        assertNull(options.getKeyAlias());
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -162,8 +158,8 @@ public class NettySslTransportFactoryTest {
         assertEquals(CUSTOM_SO_LINGER, options.getSoLinger());
         assertEquals(CUSTOM_SO_TIMEOUT, options.getSoTimeout());
 
-        assertTrue(options instanceof TransportSslOptions);
-        TransportSslOptions sslOptions = (TransportSslOptions) options;
+        assertTrue(options instanceof TransportOptions);
+        TransportOptions sslOptions = options;
 
         List<String> enabledProtocols = Arrays.asList(sslOptions.getEnabledProtocols());
         List<String> customProtocols = Arrays.asList(CUSTOM_ENABLED_PROTOCOLS);
@@ -197,11 +193,11 @@ public class NettySslTransportFactoryTest {
         NettySslTransportFactory factory = new NettySslTransportFactory();
         Transport transport = factory.createTransport(configuredURI);
         TransportOptions options = transport.getTransportOptions();
-        assertTrue(options instanceof TransportSslOptions);
-        TransportSslOptions sslOptions = (TransportSslOptions) options;
+        assertTrue(options instanceof TransportOptions);
+        TransportOptions sslOptions = options;
 
         assertEquals(CUSTOM_STORE_TYPE, sslOptions.getKeyStoreType());
-        assertEquals(TransportSslOptions.DEFAULT_STORE_TYPE, sslOptions.getTrustStoreType());
+        assertEquals(TransportOptions.DEFAULT_STORE_TYPE, sslOptions.getTrustStoreType());
     }
 
     @Test
@@ -213,10 +209,10 @@ public class NettySslTransportFactoryTest {
         NettySslTransportFactory factory = new NettySslTransportFactory();
         Transport transport = factory.createTransport(configuredURI);
         TransportOptions options = transport.getTransportOptions();
-        assertTrue(options instanceof TransportSslOptions);
-        TransportSslOptions sslOptions = (TransportSslOptions) options;
+        assertTrue(options instanceof TransportOptions);
+        TransportOptions sslOptions = options;
 
-        assertEquals(TransportSslOptions.DEFAULT_STORE_TYPE, sslOptions.getKeyStoreType());
+        assertEquals(TransportOptions.DEFAULT_STORE_TYPE, sslOptions.getKeyStoreType());
         assertEquals(CUSTOM_STORE_TYPE, sslOptions.getTrustStoreType());
     }
 
@@ -230,11 +226,10 @@ public class NettySslTransportFactoryTest {
         NettySslTransportFactory factory = new NettySslTransportFactory();
         Transport transport = factory.createTransport(configuredURI);
         TransportOptions options = transport.getTransportOptions();
-        assertTrue(options instanceof TransportSslOptions);
-        TransportSslOptions sslOptions = (TransportSslOptions) options;
+        assertTrue(options instanceof TransportOptions);
 
-        assertEquals(CUSTOM_STORE_TYPE_PKCS12, sslOptions.getKeyStoreType());
-        assertEquals(CUSTOM_STORE_TYPE, sslOptions.getTrustStoreType());
+        assertEquals(CUSTOM_STORE_TYPE_PKCS12, options.getKeyStoreType());
+        assertEquals(CUSTOM_STORE_TYPE, options.getTrustStoreType());
     }
 
     @Test
@@ -249,8 +244,8 @@ public class NettySslTransportFactoryTest {
         NettySslTransportFactory factory = new NettySslTransportFactory();
         Transport transport = factory.createTransport(configuredURI);
         TransportOptions options = transport.getTransportOptions();
-        assertTrue(options instanceof TransportSslOptions);
-        TransportSslOptions sslOptions = (TransportSslOptions) options;
+        assertTrue(options instanceof TransportOptions);
+        TransportOptions sslOptions = options;
 
         assertEquals(CUSTOM_TRUST_STORE_LOCATION, sslOptions.getTrustStoreLocation());
         assertEquals(CUSTOM_TRUST_STORE_PASSWORD, sslOptions.getTrustStorePassword());

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportTest.java
index 4fbc66c..fa62a10 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettySslTransportTest.java
@@ -31,7 +31,6 @@ import java.security.cert.X509Certificate;
 import org.apache.qpid.jms.transports.Transport;
 import org.apache.qpid.jms.transports.TransportListener;
 import org.apache.qpid.jms.transports.TransportOptions;
-import org.apache.qpid.jms.transports.TransportSslOptions;
 import org.apache.qpid.jms.util.QpidJMSTestRunner;
 import org.apache.qpid.jms.util.Repeat;
 import org.junit.Test;
@@ -110,7 +109,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
             int port = server.getServerPort();
             URI serverLocation = new URI("tcp://localhost:" + port);
 
-            TransportSslOptions options = new TransportSslOptions();
+            TransportOptions options = new TransportOptions();
 
             options.setTrustStoreLocation(OTHER_CA_TRUSTSTORE);
             options.setTrustStorePassword(PASSWORD);
@@ -157,7 +156,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
 
     @Test(timeout = 60 * 1000)
     public void testConnectWithNeedClientAuth() throws Exception {
-        TransportSslOptions serverOptions = createServerOptions();
+        TransportOptions serverOptions = createServerOptions();
 
         try (NettyEchoServer server = createEchoServer(serverOptions, true)) {
             server.start();
@@ -165,7 +164,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
             int port = server.getServerPort();
             URI serverLocation = new URI("tcp://localhost:" + port);
 
-            TransportSslOptions clientOptions = createClientOptions();
+            TransportOptions clientOptions = createClientOptions();
 
             NettyTcpTransport transport = createTransport(serverLocation, testListener, clientOptions);
             try {
@@ -195,7 +194,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
     }
 
     private void doClientAuthAliasTestImpl(String alias, String expectedDN) throws Exception, URISyntaxException, IOException, InterruptedException {
-        TransportSslOptions serverOptions = createServerOptions();
+        TransportOptions serverOptions = createServerOptions();
 
         try (NettyEchoServer server = createEchoServer(serverOptions, true)) {
             server.start();
@@ -203,7 +202,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
             int port = server.getServerPort();
             URI serverLocation = new URI("tcp://localhost:" + port);
 
-            TransportSslOptions clientOptions = createClientOptions();
+            TransportOptions clientOptions = createClientOptions();
             clientOptions.setKeyStoreLocation(CLIENT_MULTI_KEYSTORE);
             clientOptions.setKeyAlias(alias);
 
@@ -244,7 +243,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
     }
 
     private void doConnectToServerVerifyHostTestImpl(boolean verifyHost) throws Exception, URISyntaxException, IOException, InterruptedException {
-        TransportSslOptions serverOptions = createServerOptions();
+        TransportOptions serverOptions = createServerOptions();
         serverOptions.setKeyStoreLocation(SERVER_WRONG_HOST_KEYSTORE);
 
         try (NettyEchoServer server = createEchoServer(serverOptions)) {
@@ -253,7 +252,7 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
             int port = server.getServerPort();
             URI serverLocation = new URI("tcp://localhost:" + port);
 
-            TransportSslOptions clientOptions = createClientOptionsIsVerify(verifyHost);
+            TransportOptions clientOptions = createClientOptionsIsVerify(verifyHost);
 
             if (verifyHost) {
                 assertTrue("Expected verifyHost to be true", clientOptions.isVerifyHost());
@@ -288,16 +287,26 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
 
     @Override
     protected NettyTcpTransport createTransport(URI serverLocation, TransportListener listener, TransportOptions options) {
-        return new NettyTcpTransport(listener, serverLocation, options);
+        return new NettyTcpTransport(listener, serverLocation, options, true);
     }
 
     @Override
-    protected TransportSslOptions createClientOptions() {
+	protected NettyEchoServer createEchoServer(TransportOptions options) {
+        return createEchoServer(options, false);
+    }
+
+    @Override
+	protected NettyEchoServer createEchoServer(TransportOptions options, boolean needClientAuth) {
+        return new NettyEchoServer(options, true, needClientAuth);
+    }
+
+    @Override
+    protected TransportOptions createClientOptions() {
         return createClientOptionsIsVerify(false);
     }
 
-    protected TransportSslOptions createClientOptionsIsVerify(boolean verifyHost) {
-        TransportSslOptions options = new TransportSslOptions();
+    protected TransportOptions createClientOptionsIsVerify(boolean verifyHost) {
+        TransportOptions options = new TransportOptions();
 
         options.setKeyStoreLocation(CLIENT_KEYSTORE);
         options.setKeyStorePassword(PASSWORD);
@@ -310,8 +319,8 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
     }
 
     @Override
-    protected TransportSslOptions createServerOptions() {
-        TransportSslOptions options = new TransportSslOptions();
+    protected TransportOptions createServerOptions() {
+        TransportOptions options = new TransportOptions();
 
         options.setKeyStoreLocation(SERVER_KEYSTORE);
         options.setKeyStorePassword(PASSWORD);
@@ -323,8 +332,8 @@ public class NettySslTransportTest extends NettyTcpTransportTest {
         return options;
     }
 
-    protected TransportSslOptions createClientOptionsWithoutTrustStore(boolean trustAll) {
-        TransportSslOptions options = new TransportSslOptions();
+    protected TransportOptions createClientOptionsWithoutTrustStore(boolean trustAll) {
+        TransportOptions options = new TransportOptions();
 
         options.setStoreType(KEYSTORE_TYPE);
         options.setTrustAll(trustAll);

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpToMockServerTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpToMockServerTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpToMockServerTest.java
index 14418ef..57fb5eb 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpToMockServerTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpToMockServerTest.java
@@ -21,6 +21,8 @@ import static org.apache.qpid.jms.provider.amqp.AmqpSupport.OPEN_HOSTNAME;
 import static org.apache.qpid.jms.provider.amqp.AmqpSupport.PATH;
 import static org.apache.qpid.jms.provider.amqp.AmqpSupport.PORT;
 import static org.apache.qpid.jms.provider.amqp.AmqpSupport.SCHEME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -34,6 +36,7 @@ import javax.jms.Connection;
 import javax.jms.InvalidClientIDException;
 import javax.jms.Session;
 
+import org.apache.qpid.jms.JmsConnectionExtensions;
 import org.apache.qpid.jms.JmsConnectionFactory;
 import org.apache.qpid.jms.test.QpidJmsTestCase;
 import org.apache.qpid.jms.transports.TransportOptions;
@@ -47,6 +50,8 @@ import org.junit.rules.TestName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
+
 /**
  * Test Client connection to Mock AMQP server.
  */
@@ -294,6 +299,43 @@ public class NettyTcpToMockServerTest extends QpidJmsTestCase {
         }
     }
 
+    @Test(timeout = 60000)
+    public void testConnectToWSServerWithHttpHeaderConnectionExtensions() throws Exception {
+        try (NettySimpleAmqpServer server = createWSServer(createServerOptions())) {
+            server.start();
+
+            JmsConnectionFactory cf = new JmsConnectionFactory(createConnectionURI(server));
+            cf.setExtension(JmsConnectionExtensions.HTTP_HEADERS_OVERRIDE.toString(), (connection) -> {
+                Map<String, String> headers = new HashMap<>();
+
+                headers.put("test-header1", "FOO");
+                headers.put("test-header2", "BAR");
+
+                return headers;
+            });
+
+            Connection connection = null;
+            try {
+                connection = cf.createConnection();
+                connection.start();
+
+                assertNotNull(server.getHandshakeComplete());
+
+                HandshakeComplete handshake = server.getHandshakeComplete();
+                assertTrue(handshake.requestHeaders().contains("test-header1"));
+                assertTrue(handshake.requestHeaders().contains("test-header2"));
+
+                assertEquals("FOO", handshake.requestHeaders().get("test-header1"));
+                assertEquals("BAR", handshake.requestHeaders().get("test-header2"));
+            } catch (Exception ex) {
+                LOG.error("Caught exception while attempting to connect");
+                fail("Should be able to connect in this simple test");
+            } finally {
+                connection.close();
+            }
+        }
+    }
+
     protected URI createConnectionURI(NettyServer server) throws Exception {
         return createConnectionURI(server, null);
     }
@@ -328,10 +370,10 @@ public class NettyTcpToMockServerTest extends QpidJmsTestCase {
     }
 
     protected NettySimpleAmqpServer createServer(TransportOptions options, boolean needClientAuth) {
-        return new NettySimpleAmqpServer(options, needClientAuth);
+        return new NettySimpleAmqpServer(options, false, needClientAuth);
     }
 
     protected NettySimpleAmqpServer createWSServer(TransportOptions options) {
-        return new NettySimpleAmqpServer(options, false, true);
+        return new NettySimpleAmqpServer(options, false, false, true);
     }
 }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactoryTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactoryTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactoryTest.java
index fb81b35..1f0f97c 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactoryTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactoryTest.java
@@ -81,6 +81,13 @@ public class NettyTcpTransportFactoryTest {
         factory.createTransport(BASE_URI);
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testCreateTransportWithHttpHeaders() throws Exception {
+        URI BASE_URI = new URI("tcp://localhost:5672?transport.httpHeaders=A");
+        NettyTcpTransportFactory factory = new NettyTcpTransportFactory();
+        factory.createTransport(BASE_URI);
+    }
+
     @Test(expected = IOException.class)
     public void testCreateWithBadKey() throws Exception {
         URI BASE_URI = new URI("tcp://localhost:5672?transport.trafficClass=4096");

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportTest.java
index 3d150f5..91a33b9 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportTest.java
@@ -649,9 +649,9 @@ public class NettyTcpTransportTest extends QpidJmsTestCase {
 
     protected Transport createTransport(URI serverLocation, TransportListener listener, TransportOptions options) {
         if (listener == null) {
-            return new NettyTcpTransport(serverLocation, options);
+            return new NettyTcpTransport(serverLocation, options, false);
         } else {
-            return new NettyTcpTransport(listener, serverLocation, options);
+            return new NettyTcpTransport(listener, serverLocation, options, false);
         }
     }
 
@@ -676,7 +676,7 @@ public class NettyTcpTransportTest extends QpidJmsTestCase {
     }
 
     protected NettyEchoServer createEchoServer(TransportOptions options, boolean needClientAuth) {
-        return new NettyEchoServer(options, needClientAuth);
+        return new NettyEchoServer(options, false, needClientAuth, false);
     }
 
     public class NettyTransportListener implements TransportListener {

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWsTransportTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWsTransportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWsTransportTest.java
index f7b6b69..fa1935f 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWsTransportTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWsTransportTest.java
@@ -18,6 +18,7 @@ package org.apache.qpid.jms.transports.netty;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.buffer.Unpooled;
+import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.HandshakeComplete;
 
 /**
  * Test the Netty based WebSocket Transport
@@ -47,15 +49,15 @@ public class NettyWsTransportTest extends NettyTcpTransportTest {
 
     @Override
     protected NettyEchoServer createEchoServer(TransportOptions options, boolean needClientAuth) {
-        return new NettyEchoServer(options, needClientAuth, true);
+        return new NettyEchoServer(options, false, needClientAuth, true);
     }
 
     @Override
     protected Transport createTransport(URI serverLocation, TransportListener listener, TransportOptions options) {
         if (listener == null) {
-            return new NettyWsTransport(serverLocation, options);
+            return new NettyWsTransport(serverLocation, options, false);
         } else {
-            return new NettyWsTransport(listener, serverLocation, options);
+            return new NettyWsTransport(listener, serverLocation, options, false);
         }
     }
 
@@ -316,4 +318,66 @@ public class NettyWsTransportTest extends NettyTcpTransportTest {
             }, 10000, 50));
         }
     }
+
+    @Test(timeout = 30000)
+    public void testCreateWithHttpHeadersSpecified() throws Exception {
+        URI BASE_URI = new URI("ws://localhost:5672?" +
+                "transport.ws.httpHeader.first=FOO&" +
+                "transport.ws.httpHeader.second=BAR");
+
+        NettyWsTransportFactory factory = new NettyWsTransportFactory();
+
+        Transport transport = factory.createTransport(BASE_URI);
+
+        assertNotNull(transport);
+        assertTrue(transport instanceof NettyWsTransport);
+        assertFalse(transport.isConnected());
+
+        TransportOptions options = transport.getTransportOptions();
+        assertNotNull(options);
+
+        assertTrue(options.getHttpHeaders().containsKey("first"));
+        assertTrue(options.getHttpHeaders().containsKey("second"));
+
+        assertEquals("FOO", options.getHttpHeaders().get("first"));
+        assertEquals("BAR", options.getHttpHeaders().get("second"));
+    }
+
+    @Test(timeout = 60 * 1000)
+    public void testConfiguredHttpHeadersArriveAtServer() throws Exception {
+        try (NettyEchoServer server = createEchoServer(createServerOptions())) {
+            server.start();
+
+            int port = server.getServerPort();
+            URI serverLocation = new URI("tcp://localhost:" + port);
+
+            TransportOptions clientOptions = createClientOptions();
+            clientOptions.getHttpHeaders().put("test-header1", "FOO");
+            clientOptions.getHttpHeaders().put("test-header2", "BAR");
+
+            Transport transport = createTransport(serverLocation, testListener, clientOptions);
+            try {
+                transport.connect(null);
+                LOG.info("Connected to server:{} as expected.", serverLocation);
+            } catch (Exception e) {
+                fail("Should have connected to the server at " + serverLocation + " but got exception: " + e);
+            }
+
+            assertTrue(transport.isConnected());
+            assertEquals(serverLocation, transport.getRemoteLocation());
+
+            HandshakeComplete handshake = server.getHandshakeComplete();
+            assertTrue(handshake.requestHeaders().contains("test-header1"));
+            assertTrue(handshake.requestHeaders().contains("test-header2"));
+
+            assertEquals("FOO", handshake.requestHeaders().get("test-header1"));
+            assertEquals("BAR", handshake.requestHeaders().get("test-header2"));
+
+            transport.close();
+        }
+
+        assertTrue(!transportClosed);  // Normal shutdown does not trigger the event.
+        assertTrue(exceptions.isEmpty());
+        assertTrue(data.isEmpty());
+    }
 }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWssTransportTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWssTransportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWssTransportTest.java
index 69fdd57..f157537 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWssTransportTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/netty/NettyWssTransportTest.java
@@ -28,15 +28,15 @@ public class NettyWssTransportTest extends NettySslTransportTest {
 
     @Override
     protected NettyEchoServer createEchoServer(TransportOptions options, boolean needClientAuth) {
-        return new NettyEchoServer(options, needClientAuth, true);
+        return new NettyEchoServer(options, true, needClientAuth, true);
     }
 
     @Override
     protected NettyTcpTransport createTransport(URI serverLocation, TransportListener listener, TransportOptions options) {
         if (listener == null) {
-            return new NettyWsTransport(serverLocation, options);
+            return new NettyWsTransport(serverLocation, options, true);
         } else {
-            return new NettyWsTransport(listener, serverLocation, options);
+            return new NettyWsTransport(listener, serverLocation, options, true);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsSSLConnectionTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsSSLConnectionTest.java b/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsSSLConnectionTest.java
index a458fe6..dae603e 100644
--- a/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsSSLConnectionTest.java
+++ b/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsSSLConnectionTest.java
@@ -25,7 +25,7 @@ import javax.net.ssl.SSLContext;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.activemq.broker.SslContext;
 import org.apache.activemq.broker.TransportConnector;
-import org.apache.qpid.jms.transports.TransportSslOptions;
+import org.apache.qpid.jms.transports.TransportOptions;
 import org.apache.qpid.jms.transports.TransportSupport;
 import org.junit.After;
 import org.junit.Before;
@@ -53,7 +53,7 @@ public class JmsSSLConnectionTest {
         brokerService.setUseJmx(false);
 
         // Setup broker SSL context...
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsWSSConnectionTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsWSSConnectionTest.java b/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsWSSConnectionTest.java
index 4e3b183..3a01e73 100644
--- a/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsWSSConnectionTest.java
+++ b/qpid-jms-interop-tests/qpid-jms-activemq-tests/src/test/java/org/apache/qpid/jms/JmsWSSConnectionTest.java
@@ -28,7 +28,7 @@ import javax.net.ssl.SSLContext;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.activemq.broker.SslContext;
 import org.apache.activemq.broker.TransportConnector;
-import org.apache.qpid.jms.transports.TransportSslOptions;
+import org.apache.qpid.jms.transports.TransportOptions;
 import org.apache.qpid.jms.transports.TransportSupport;
 import org.junit.After;
 import org.junit.Before;
@@ -60,7 +60,7 @@ public class JmsWSSConnectionTest {
         brokerService.setUseJmx(false);
 
         // Setup broker SSL context...
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);


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


[2/2] qpid-jms git commit: QPIDJMS-384 Allow for extensions to provide information to the connection

Posted by ta...@apache.org.
QPIDJMS-384 Allow for extensions to provide information to the connection

Create an extension mechanism where the user can supply functions that are
called at various point in the connection lifecylce to supply or override
conifguration based on user needs.

This closes #18


Project: http://git-wip-us.apache.org/repos/asf/qpid-jms/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-jms/commit/8bf97c4b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-jms/tree/8bf97c4b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-jms/diff/8bf97c4b

Branch: refs/heads/master
Commit: 8bf97c4b7829fd602d2d09b61b2046d46870ef16
Parents: 0933c9e
Author: Timothy Bish <ta...@gmail.com>
Authored: Wed Apr 25 13:14:22 2018 -0400
Committer: Timothy Bish <ta...@gmail.com>
Committed: Wed Apr 25 13:14:22 2018 -0400

----------------------------------------------------------------------
 .../java/org/apache/qpid/jms/JmsConnection.java |   1 +
 .../qpid/jms/JmsConnectionExtensions.java       | 129 +++++++
 .../apache/qpid/jms/JmsConnectionFactory.java   |  32 +-
 .../apache/qpid/jms/meta/JmsConnectionInfo.java |  35 +-
 .../qpid/jms/provider/amqp/AmqpProvider.java    |  39 ++-
 .../qpid/jms/transports/TransportFactory.java   |  35 +-
 .../qpid/jms/transports/TransportOptions.java   | 312 ++++++++++++++++-
 .../jms/transports/TransportSslOptions.java     | 340 -------------------
 .../qpid/jms/transports/TransportSupport.java   |  24 +-
 .../netty/NettySslTransportFactory.java         |   8 -
 .../jms/transports/netty/NettyTcpTransport.java |  28 +-
 .../netty/NettyTcpTransportFactory.java         |   2 +-
 .../jms/transports/netty/NettyWsTransport.java  |  22 +-
 .../netty/NettyWsTransportFactory.java          |  17 +-
 .../netty/NettyWssTransportFactory.java         |   8 -
 .../jms/integration/SaslIntegrationTest.java    | 124 ++++++-
 .../jms/integration/SslIntegrationTest.java     |  55 ++-
 ...qpOpenProvidedServerListIntegrationTest.java |  16 +-
 .../jms/transports/TransportOptionsTest.java    | 174 ++++++++++
 .../jms/transports/TransportSslOptionsTest.java | 220 ------------
 .../jms/transports/TransportSupportTest.java    |  73 ++--
 .../jms/transports/netty/NettyEchoServer.java   |   8 +-
 .../qpid/jms/transports/netty/NettyServer.java  |  37 +-
 .../transports/netty/NettySimpleAmqpServer.java |  10 +-
 .../netty/NettySslTransportFactoryTest.java     |  47 ++-
 .../transports/netty/NettySslTransportTest.java |  41 ++-
 .../netty/NettyTcpToMockServerTest.java         |  46 ++-
 .../netty/NettyTcpTransportFactoryTest.java     |   7 +
 .../transports/netty/NettyTcpTransportTest.java |   6 +-
 .../transports/netty/NettyWsTransportTest.java  |  70 +++-
 .../transports/netty/NettyWssTransportTest.java |   6 +-
 .../apache/qpid/jms/JmsSSLConnectionTest.java   |   4 +-
 .../apache/qpid/jms/JmsWSSConnectionTest.java   |   4 +-
 33 files changed, 1174 insertions(+), 806 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnection.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnection.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnection.java
index 1ef72f7..3b2959e 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnection.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnection.java
@@ -148,6 +148,7 @@ public class JmsConnection implements AutoCloseable, Connection, TopicConnection
         }
 
         this.connectionInfo = connectionInfo;
+        this.connectionInfo.setConnection(this);
     }
 
     JmsConnection connect() throws JMSException {

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionExtensions.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionExtensions.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionExtensions.java
new file mode 100644
index 0000000..a340ae1
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionExtensions.java
@@ -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.jms;
+
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.jms.Connection;
+import javax.net.ssl.SSLContext;
+
+/**
+ * Connection Extensions Definitions
+ * <p>
+ * Connection Extensions all the user to apply functions that can override or update
+ * client configuration based on state in their own applications such as providing a custom
+ * SSLContext or updating an authentication token from an external provider on each attempt
+ * to connect to a remote.
+ * <p>
+ * The extensions take the form of a Function<Connection, Object> passed into the ConnectionFactory
+ * using the {@link JmsConnectionFactory#setExtension(String, Function)}.
+ */
+public enum JmsConnectionExtensions {
+
+    /**
+     * Allows a user to inject a custom SSL Context into the client which overrides
+     * the instance that the client would create and use.
+     * <p>
+     * Using this method overrides the effect of URI/System property configuration relating
+     * to the location/credentials/type of SSL key/trust stores and whether to trust all
+     * certificates or use a particular keyAlias.
+     * <p>
+     * The extension function takes the form of a Function defined as the following:
+     * <ul>
+     *   <li>
+     *     {@link Function}<{@link Connection}, {@link SSLContext}>
+     *   </li>
+     * </ul>
+     */
+    SSL_CONTEXT("sslContext"),
+
+    /**
+     * Allows a user to inject a custom user name into the client which overrides
+     * the instance that the client would use to authenticate with the remote.
+     * <p>
+     * Using this method overrides the effect of URI/ConnectionFactory configuration relating
+     * to the user name provided to the remote for authentication.  This method will be invoked
+     * on each connection authentication attempt in the presence of a failover configuration.
+     * <p>
+     * The extension function takes the form of a Function defined as the following:
+     * <ul>
+     *   <li>
+     *     {@link Function}<{@link Connection}, {@link String}>
+     *   </li>
+     * </ul>
+     */
+    USERNAME_OVERRIDE("username"),
+
+    /**
+     * Allows a user to inject a custom password into the client which overrides
+     * the instance that the client would use to authenticate with the remote.
+     * <p>
+     * Using this method overrides the effect of URI/ConnectionFactory configuration relating
+     * to the password provided to the remote for authentication.  This method will be invoked
+     * on each connection authentication attempt in the presence of a failover configuration.
+     * <p>
+     * The extension function takes the form of a Function defined as the following:
+     * <ul>
+     *   <li>
+     *     {@link Function}<{@link Connection}, {@link String}>
+     *   </li>
+     * </ul>
+     */
+    PASSWORD_OVERRIDE("password"),
+
+    /**
+     * Allows a user to inject a custom HTTP header into the client which overrides or
+     * augments the values that the client would use to authenticate with the remote over
+     * a WebSocket based connection.
+     * <p>
+     * Using this method overrides the effect of URI/ConnectionFactory configuration relating
+     * to the HTTP headers provided to the remote for authentication.  This method will be invoked
+     * on each connection authentication attempt in the presence of a failover configuration.
+     * <p>
+     * The extension function takes the form of a Function defined as the following:
+     * <ul>
+     *   <li>
+     *     {@link Function}<{@link Connection}, {@link Map}
+     *   </li>
+     * </ul>
+     */
+    HTTP_HEADERS_OVERRIDE("httpHeaders");
+
+    private final String extensionKey;
+
+    private JmsConnectionExtensions(String key) {
+        this.extensionKey = key;
+    }
+
+    @Override
+    public String toString() {
+        return extensionKey;
+    }
+
+    public static JmsConnectionExtensions fromString(String extensionName) {
+        for (JmsConnectionExtensions ext : JmsConnectionExtensions.values()) {
+            if (ext.extensionKey.equalsIgnoreCase(extensionName)) {
+                return ext;
+            } else if (ext.toString().equalsIgnoreCase(extensionName)) {
+                return ext;
+            }
+        }
+
+        throw new IllegalArgumentException("No Extension with name " + extensionName + " found");
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionFactory.java
index 91ee9ec..f15b478 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsConnectionFactory.java
@@ -20,7 +20,9 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.EnumMap;
 import java.util.Map;
+import java.util.function.Function;
 
 import javax.jms.Connection;
 import javax.jms.ConnectionFactory;
@@ -71,6 +73,8 @@ public class JmsConnectionFactory extends JNDIStorable implements ConnectionFact
 
     private static String DEFAULT_REMOTE_URI;
 
+    private final EnumMap<JmsConnectionExtensions, Function<Connection, Object>> extensionMap = new EnumMap<>(JmsConnectionExtensions.class);
+
     private URI remoteURI;
     private String username;
     private String password;
@@ -104,8 +108,6 @@ public class JmsConnectionFactory extends JNDIStorable implements ConnectionFact
     private JmsMessageIDPolicy messageIDPolicy = new JmsDefaultMessageIDPolicy();
     private JmsDeserializationPolicy deserializationPolicy = new JmsDefaultDeserializationPolicy();
 
-    private SSLContext sslContext;
-
     public JmsConnectionFactory() {
     }
 
@@ -263,7 +265,7 @@ public class JmsConnectionFactory extends JNDIStorable implements ConnectionFact
             connectionInfo.setPresettlePolicy(presettlePolicy.copy());
             connectionInfo.setRedeliveryPolicy(redeliveryPolicy.copy());
             connectionInfo.setDeserializationPolicy(deserializationPolicy.copy());
-            connectionInfo.setSslContextOverride(sslContext);
+            connectionInfo.getExtensionMap().putAll(extensionMap);
 
             // Set properties to make additional configuration changes
             PropertyUtil.setProperties(connectionInfo, properties);
@@ -869,7 +871,7 @@ public class JmsConnectionFactory extends JNDIStorable implements ConnectionFact
      *      the sslContext to use, or null to respect the URI/System property configuration again.
      */
     public void setSslContext(SSLContext sslContext) {
-        this.sslContext = sslContext;
+        this.extensionMap.put(JmsConnectionExtensions.SSL_CONTEXT, (connection) -> sslContext);
     }
 
     public boolean isAwaitClientID() {
@@ -912,6 +914,28 @@ public class JmsConnectionFactory extends JNDIStorable implements ConnectionFact
         this.useDaemonThread = useDaemonThread;
     }
 
+    /**
+     * Provides an entry point for extensions to be configured on this {@link ConnectionFactory}.
+     * <p>
+     * If a previous extension with the same name is present it is replaced with the new value or
+     * cleared if the value is null.
+     *
+     * @param extensionName
+     * 		The name of the extension point being added.
+     * @param extension
+     * 		The Function that implements the extension.
+     *
+     * @see JmsConnectionExtensions
+     */
+    public void setExtension(String extensionName, Function<Connection, Object> extension) {
+        JmsConnectionExtensions extensionKey = JmsConnectionExtensions.fromString(extensionName);
+        if (extension == null) {
+            extensionMap.remove(extensionKey);
+        } else {
+            extensionMap.put(extensionKey, extension);
+        }
+    }
+
     //----- Static Methods ---------------------------------------------------//
 
     /**

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/meta/JmsConnectionInfo.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/meta/JmsConnectionInfo.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/meta/JmsConnectionInfo.java
index db475fe..c624696 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/meta/JmsConnectionInfo.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/meta/JmsConnectionInfo.java
@@ -18,9 +18,13 @@ package org.apache.qpid.jms.meta;
 
 import java.net.URI;
 import java.nio.charset.Charset;
+import java.util.EnumMap;
+import java.util.function.Function;
 
-import javax.net.ssl.SSLContext;
+import javax.jms.Connection;
 
+import org.apache.qpid.jms.JmsConnection;
+import org.apache.qpid.jms.JmsConnectionExtensions;
 import org.apache.qpid.jms.policy.JmsDefaultDeserializationPolicy;
 import org.apache.qpid.jms.policy.JmsDefaultMessageIDPolicy;
 import org.apache.qpid.jms.policy.JmsDefaultPrefetchPolicy;
@@ -45,7 +49,9 @@ public final class JmsConnectionInfo extends JmsAbstractResource implements Comp
     public static final long DEFAULT_REQUEST_TIMEOUT = INFINITE;
 
     private final JmsConnectionId connectionId;
+    private final EnumMap<JmsConnectionExtensions, Function<Connection, Object>> extensionMap = new EnumMap<>(JmsConnectionExtensions.class);
 
+    private JmsConnection connection;
     private URI configuredURI;
     private URI connectedURI;
     private String clientId;
@@ -77,7 +83,6 @@ public final class JmsConnectionInfo extends JmsAbstractResource implements Comp
     private JmsDeserializationPolicy deserializationPolicy;
 
     private volatile byte[] encodedUserId;
-    private SSLContext sslContextOverride;
 
     public JmsConnectionInfo(JmsConnectionId connectionId) {
         if (connectionId == null) {
@@ -322,20 +327,6 @@ public final class JmsConnectionInfo extends JmsAbstractResource implements Comp
         this.messageIDPolicy = messageIDPolicy;
     }
 
-    /**
-     * SSLContext to use for SSL/TLS connections. Overrides URI/System property transport configuration.
-     *
-     * @param sslContextOverride
-     *      the sslContext to use, or null to respect the URI/System property configuration again.
-     */
-    public void setSslContextOverride(SSLContext sslContextOverride) {
-        this.sslContextOverride = sslContextOverride;
-    }
-
-    public SSLContext getSslContextOverride() {
-        return sslContextOverride;
-    }
-
     public boolean isPopulateJMSXUserID() {
         return populateJMSXUserID;
     }
@@ -379,6 +370,18 @@ public final class JmsConnectionInfo extends JmsAbstractResource implements Comp
         this.awaitClientID = awaitClientID;
     }
 
+    public EnumMap<JmsConnectionExtensions, Function<Connection, Object>> getExtensionMap() {
+        return extensionMap;
+    }
+
+    public JmsConnection getConnection() {
+        return connection;
+    }
+
+    public void setConnection(JmsConnection connection) {
+        this.connection = connection;
+    }
+
     @Override
     public String toString() {
         return "JmsConnectionInfo { " + getId() +

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpProvider.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpProvider.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpProvider.java
index 4d0a4bc..579b202 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpProvider.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/AmqpProvider.java
@@ -37,6 +37,7 @@ import javax.jms.JMSException;
 import javax.jms.JMSSecurityRuntimeException;
 import javax.net.ssl.SSLContext;
 
+import org.apache.qpid.jms.JmsConnectionExtensions;
 import org.apache.qpid.jms.JmsTemporaryDestination;
 import org.apache.qpid.jms.message.JmsInboundMessageDispatch;
 import org.apache.qpid.jms.message.JmsMessageFactory;
@@ -197,10 +198,26 @@ public class AmqpProvider implements Provider, TransportListener , AmqpResourceP
                     protonTransport.bind(protonConnection);
                     protonConnection.collect(protonCollector);
 
-                    SSLContext sslContextOverride = connectionInfo.getSslContextOverride();
+                    final SSLContext sslContextOverride;
+                    if (connectionInfo.getExtensionMap().containsKey(JmsConnectionExtensions.SSL_CONTEXT)) {
+                        sslContextOverride =
+                            (SSLContext) connectionInfo.getExtensionMap().get(JmsConnectionExtensions.SSL_CONTEXT).apply(connectionInfo.getConnection());
+                    } else {
+                        sslContextOverride = null;
+                    }
 
                     transport.setTransportListener(AmqpProvider.this);
                     transport.setMaxFrameSize(maxFrameSize);
+
+                    if (connectionInfo.getExtensionMap().containsKey(JmsConnectionExtensions.HTTP_HEADERS_OVERRIDE)) {
+                        @SuppressWarnings({ "unchecked" })
+                        Map<String, String> headers = (Map<String, String>)
+                            connectionInfo.getExtensionMap().get(JmsConnectionExtensions.HTTP_HEADERS_OVERRIDE).apply(connectionInfo.getConnection());
+                        if (headers != null) {
+                            transport.getTransportOptions().getHttpHeaders().putAll(headers);
+                        }
+                    }
+
                     transport.connect(sslContextOverride);
 
                     if (saslLayer) {
@@ -1427,11 +1444,25 @@ public class AmqpProvider implements Provider, TransportListener , AmqpResourceP
 
     private Mechanism findSaslMechanism(String[] remoteMechanisms) throws JMSSecurityRuntimeException {
 
+        final String username;
+        if (connectionInfo.getExtensionMap().containsKey(JmsConnectionExtensions.USERNAME_OVERRIDE)) {
+            username = (String) connectionInfo.getExtensionMap().get(JmsConnectionExtensions.USERNAME_OVERRIDE).apply(connectionInfo.getConnection());
+        } else {
+            username = connectionInfo.getUsername();
+        }
+
+        final String password;
+        if (connectionInfo.getExtensionMap().containsKey(JmsConnectionExtensions.PASSWORD_OVERRIDE)) {
+            password = (String) connectionInfo.getExtensionMap().get(JmsConnectionExtensions.PASSWORD_OVERRIDE).apply(connectionInfo.getConnection());
+        } else {
+            password = connectionInfo.getPassword();
+        }
+
         Mechanism mechanism = SaslMechanismFinder.findMatchingMechanism(
-            connectionInfo.getUsername(), connectionInfo.getPassword(), transport.getLocalPrincipal(), saslMechanisms, remoteMechanisms);
+            username, password, transport.getLocalPrincipal(), saslMechanisms, remoteMechanisms);
 
-        mechanism.setUsername(connectionInfo.getUsername());
-        mechanism.setPassword(connectionInfo.getPassword());
+        mechanism.setUsername(username);
+        mechanism.setPassword(password);
 
         try {
             Map<String, String> saslOptions = PropertyUtil.filterProperties(PropertyUtil.parseQuery(getRemoteURI()), "sasl.options.");

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportFactory.java
index e5a56c8..9582734 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportFactory.java
@@ -53,17 +53,7 @@ public abstract class TransportFactory {
 
         remoteURI = PropertyUtil.replaceQuery(remoteURI, map);
 
-        TransportOptions transportOptions = doCreateTransportOptions();
-
-        Map<String, String> unused = PropertyUtil.setProperties(transportOptions, transportURIOptions);
-        if (!unused.isEmpty()) {
-            String msg = " Not all transport options could be set on the " + getName() +
-                         " Transport. Check the options are spelled correctly." +
-                         " Unused parameters=[" + unused + "]." +
-                         " This provider instance cannot be started.";
-            throw new IllegalArgumentException(msg);
-        }
-
+        TransportOptions transportOptions = applyTransportConfiguration(doCreateTransportOptions(), transportURIOptions);
         Transport result = doCreateTransport(remoteURI, transportOptions);
 
         return result;
@@ -80,6 +70,29 @@ public abstract class TransportFactory {
     }
 
     /**
+     * Apply URI options to a freshly created {@link TransportOptions} instance which will be used
+     * when the actual {@link Transport} is created.
+     *
+     * @param transportOptions
+     * 		The {@link TransportOptions} instance to configure.
+     * @param transportURIOptions
+     * 		The URI options to apply to the given {@link TransportOptions}.
+     * @return
+     */
+    protected TransportOptions applyTransportConfiguration(TransportOptions transportOptions, Map<String, String> transportURIOptions) {
+        Map<String, String> unused = PropertyUtil.setProperties(transportOptions, transportURIOptions);
+        if (!unused.isEmpty()) {
+            String msg = " Not all transport options could be set on the " + getName() +
+                         " Transport. Check the options are spelled correctly." +
+                         " Unused parameters=[" + unused + "]." +
+                         " This provider instance cannot be started.";
+            throw new IllegalArgumentException(msg);
+        }
+
+        return transportOptions;
+    }
+
+    /**
      * Create the actual Transport instance for this factory using the provided URI and
      * TransportOptions instances.
      *

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java
index 3367e6c..7cb520b 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java
@@ -16,8 +16,16 @@
  */
 package org.apache.qpid.jms.transports;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLContext;
+
 /**
- * Encapsulates all the TCP Transport options in one configuration object.
+ * Encapsulates all the Transport options in one configuration object.
  */
 public class TransportOptions implements Cloneable {
 
@@ -33,6 +41,19 @@ public class TransportOptions implements Cloneable {
     public static final boolean DEFAULT_USE_EPOLL = true;
     public static final boolean DEFAULT_USE_KQUEUE = false;
     public static final boolean DEFAULT_TRACE_BYTES = false;
+    public static final String DEFAULT_STORE_TYPE = "jks";
+    public static final String DEFAULT_CONTEXT_PROTOCOL = "TLS";
+    public static final boolean DEFAULT_TRUST_ALL = false;
+    public static final boolean DEFAULT_VERIFY_HOST = true;
+    public static final List<String> DEFAULT_DISABLED_PROTOCOLS = Collections.unmodifiableList(Arrays.asList(new String[]{"SSLv2Hello", "SSLv3"}));
+    public static final int DEFAULT_SSL_PORT = 5671;
+
+    private static final String JAVAX_NET_SSL_KEY_STORE = "javax.net.ssl.keyStore";
+    private static final String JAVAX_NET_SSL_KEY_STORE_TYPE = "javax.net.ssl.keyStoreType";
+    private static final String JAVAX_NET_SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
+    private static final String JAVAX_NET_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
+    private static final String JAVAX_NET_SSL_TRUST_STORE_TYPE = "javax.net.ssl.trustStoreType";
+    private static final String JAVAX_NET_SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
 
     private int sendBufferSize = DEFAULT_SEND_BUFFER_SIZE;
     private int receiveBufferSize = DEFAULT_RECEIVE_BUFFER_SIZE;
@@ -47,6 +68,40 @@ public class TransportOptions implements Cloneable {
     private boolean useKQueue = DEFAULT_USE_KQUEUE;
     private boolean traceBytes = DEFAULT_TRACE_BYTES;
 
+    private String keyStoreLocation;
+    private String keyStorePassword;
+    private String trustStoreLocation;
+    private String trustStorePassword;
+    private String keyStoreType;
+    private String trustStoreType;
+    private String[] enabledCipherSuites;
+    private String[] disabledCipherSuites;
+    private String[] enabledProtocols;
+    private String[] disabledProtocols = DEFAULT_DISABLED_PROTOCOLS.toArray(new String[0]);
+    private String contextProtocol = DEFAULT_CONTEXT_PROTOCOL;
+
+    private boolean trustAll = DEFAULT_TRUST_ALL;
+    private boolean verifyHost = DEFAULT_VERIFY_HOST;
+    private String keyAlias;
+    private int defaultSslPort = DEFAULT_SSL_PORT;
+    private SSLContext sslContextOverride;
+
+    private final Map<String, String> httpHeaders = new HashMap<>();
+
+    public TransportOptions() {
+        setKeyStoreLocation(System.getProperty(JAVAX_NET_SSL_KEY_STORE));
+        setKeyStoreType(System.getProperty(JAVAX_NET_SSL_KEY_STORE_TYPE, DEFAULT_STORE_TYPE));
+        setKeyStorePassword(System.getProperty(JAVAX_NET_SSL_KEY_STORE_PASSWORD));
+        setTrustStoreLocation(System.getProperty(JAVAX_NET_SSL_TRUST_STORE));
+        setTrustStoreType(System.getProperty(JAVAX_NET_SSL_TRUST_STORE_TYPE, DEFAULT_STORE_TYPE));
+        setTrustStorePassword(System.getProperty(JAVAX_NET_SSL_TRUST_STORE_PASSWORD));
+    }
+
+    @Override
+    public TransportOptions clone() {
+        return copyOptions(new TransportOptions());
+    }
+
     /**
      * @return the currently set send buffer size in bytes.
      */
@@ -219,13 +274,242 @@ public class TransportOptions implements Cloneable {
         this.traceBytes = traceBytes;
     }
 
-    @Override
-    public TransportOptions clone() {
-        return copyOptions(new TransportOptions());
+    /**
+     * @return the keyStoreLocation currently configured.
+     */
+    public String getKeyStoreLocation() {
+        return keyStoreLocation;
+    }
+
+    /**
+     * Sets the location on disk of the key store to use.
+     *
+     * @param keyStoreLocation
+     *        the keyStoreLocation to use to create the key manager.
+     */
+    public void setKeyStoreLocation(String keyStoreLocation) {
+        this.keyStoreLocation = keyStoreLocation;
+    }
+
+    /**
+     * @return the keyStorePassword
+     */
+    public String getKeyStorePassword() {
+        return keyStorePassword;
+    }
+
+    /**
+     * @param keyStorePassword the keyStorePassword to set
+     */
+    public void setKeyStorePassword(String keyStorePassword) {
+        this.keyStorePassword = keyStorePassword;
+    }
+
+    /**
+     * @return the trustStoreLocation
+     */
+    public String getTrustStoreLocation() {
+        return trustStoreLocation;
+    }
+
+    /**
+     * @param trustStoreLocation the trustStoreLocation to set
+     */
+    public void setTrustStoreLocation(String trustStoreLocation) {
+        this.trustStoreLocation = trustStoreLocation;
+    }
+
+    /**
+     * @return the trustStorePassword
+     */
+    public String getTrustStorePassword() {
+        return trustStorePassword;
+    }
+
+    /**
+     * @param trustStorePassword the trustStorePassword to set
+     */
+    public void setTrustStorePassword(String trustStorePassword) {
+        this.trustStorePassword = trustStorePassword;
+    }
+
+    /**
+     * @param storeType
+     *        the format that the store files are encoded in.
+     */
+    public void setStoreType(String storeType) {
+        setKeyStoreType(storeType);
+        setTrustStoreType(storeType);
+    }
+
+    /**
+     * @return the keyStoreType
+     */
+    public String getKeyStoreType() {
+        return keyStoreType;
+    }
+
+    /**
+     * @param keyStoreType
+     *        the format that the keyStore file is encoded in
+     */
+    public void setKeyStoreType(String keyStoreType) {
+        this.keyStoreType = keyStoreType;
+    }
+
+    /**
+     * @return the trustStoreType
+     */
+    public String getTrustStoreType() {
+        return trustStoreType;
+    }
+
+    /**
+     * @param trustStoreType
+     *        the format that the trustStore file is encoded in
+     */
+    public void setTrustStoreType(String trustStoreType) {
+        this.trustStoreType = trustStoreType;
+    }
+
+    /**
+     * @return the enabledCipherSuites
+     */
+    public String[] getEnabledCipherSuites() {
+        return enabledCipherSuites;
+    }
+
+    /**
+     * @param enabledCipherSuites the enabledCipherSuites to set
+     */
+    public void setEnabledCipherSuites(String[] enabledCipherSuites) {
+        this.enabledCipherSuites = enabledCipherSuites;
+    }
+
+    /**
+     * @return the disabledCipherSuites
+     */
+    public String[] getDisabledCipherSuites() {
+        return disabledCipherSuites;
+    }
+
+    /**
+     * @param disabledCipherSuites the disabledCipherSuites to set
+     */
+    public void setDisabledCipherSuites(String[] disabledCipherSuites) {
+        this.disabledCipherSuites = disabledCipherSuites;
+    }
+
+    /**
+     * @return the enabledProtocols or null if the defaults should be used
+     */
+    public String[] getEnabledProtocols() {
+        return enabledProtocols;
+    }
+
+    /**
+     * The protocols to be set as enabled.
+     *
+     * @param enabledProtocols the enabled protocols to set, or null if the defaults should be used.
+     */
+    public void setEnabledProtocols(String[] enabledProtocols) {
+        this.enabledProtocols = enabledProtocols;
+    }
+
+    /**
+     * @return the protocols to disable or null if none should be
+     */
+    public String[] getDisabledProtocols() {
+        return disabledProtocols;
+    }
+
+    /**
+     * The protocols to be disable.
+     *
+     * @param disabledProtocols the protocols to disable, or null if none should be.
+     */
+    public void setDisabledProtocols(String[] disabledProtocols) {
+        this.disabledProtocols = disabledProtocols;
+    }
+
+    /**
+    * @return the context protocol to use
+    */
+    public String getContextProtocol() {
+        return contextProtocol;
+    }
+
+    /**
+     * The protocol value to use when creating an SSLContext via
+     * SSLContext.getInstance(protocol).
+     *
+     * @param contextProtocol the context protocol to use.
+     */
+    public void setContextProtocol(String contextProtocol) {
+        this.contextProtocol = contextProtocol;
+    }
+
+    /**
+     * @return the trustAll
+     */
+    public boolean isTrustAll() {
+        return trustAll;
+    }
+
+    /**
+     * @param trustAll the trustAll to set
+     */
+    public void setTrustAll(boolean trustAll) {
+        this.trustAll = trustAll;
+    }
+
+    /**
+     * @return the verifyHost
+     */
+    public boolean isVerifyHost() {
+        return verifyHost;
+    }
+
+    /**
+     * @param verifyHost the verifyHost to set
+     */
+    public void setVerifyHost(boolean verifyHost) {
+        this.verifyHost = verifyHost;
+    }
+
+    /**
+     * @return the key alias
+     */
+    public String getKeyAlias() {
+        return keyAlias;
+    }
+
+    /**
+     * @param keyAlias the key alias to use
+     */
+    public void setKeyAlias(String keyAlias) {
+        this.keyAlias = keyAlias;
+    }
+
+    public int getDefaultSslPort() {
+        return defaultSslPort;
+    }
+
+    public void setDefaultSslPort(int defaultSslPort) {
+        this.defaultSslPort = defaultSslPort;
+    }
+
+    public void setSslContextOverride(SSLContext sslContextOverride) {
+        this.sslContextOverride = sslContextOverride;
+    }
+
+    public SSLContext getSslContextOverride() {
+        return sslContextOverride;
     }
 
-    public boolean isSSL() {
-        return false;
+    // TODO - Expose headers ( ? getWSHeaders : getAuthHeaders ...
+    public Map<String, String> getHttpHeaders() {
+        return httpHeaders;
     }
 
     protected TransportOptions copyOptions(TransportOptions copy) {
@@ -240,6 +524,22 @@ public class TransportOptions implements Cloneable {
         copy.setDefaultTcpPort(getDefaultTcpPort());
         copy.setUseEpoll(isUseEpoll());
         copy.setTraceBytes(isTraceBytes());
+        copy.setKeyStoreLocation(getKeyStoreLocation());
+        copy.setKeyStorePassword(getKeyStorePassword());
+        copy.setTrustStoreLocation(getTrustStoreLocation());
+        copy.setTrustStorePassword(getTrustStorePassword());
+        copy.setKeyStoreType(getKeyStoreType());
+        copy.setTrustStoreType(getTrustStoreType());
+        copy.setEnabledCipherSuites(getEnabledCipherSuites());
+        copy.setDisabledCipherSuites(getDisabledCipherSuites());
+        copy.setEnabledProtocols(getEnabledProtocols());
+        copy.setDisabledProtocols(getDisabledProtocols());
+        copy.setTrustAll(isTrustAll());
+        copy.setVerifyHost(isVerifyHost());
+        copy.setKeyAlias(getKeyAlias());
+        copy.setContextProtocol(getContextProtocol());
+        copy.setDefaultSslPort(getDefaultSslPort());
+        copy.setSslContextOverride(getSslContextOverride());
 
         return copy;
     }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSslOptions.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSslOptions.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSslOptions.java
deleted file mode 100644
index 0fec49a..0000000
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSslOptions.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * 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.jms.transports;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import javax.net.ssl.SSLContext;
-
-
-/**
- * Holds the defined SSL options for connections that operate over a secure
- * transport.  Options are read from the environment and can be overridden by
- * specifying them on the connection URI.
- */
-public class TransportSslOptions extends TransportOptions {
-
-    public static final String DEFAULT_STORE_TYPE = "jks";
-    public static final String DEFAULT_CONTEXT_PROTOCOL = "TLS";
-    public static final boolean DEFAULT_TRUST_ALL = false;
-    public static final boolean DEFAULT_VERIFY_HOST = true;
-    public static final List<String> DEFAULT_DISABLED_PROTOCOLS = Collections.unmodifiableList(Arrays.asList(new String[]{"SSLv2Hello", "SSLv3"}));
-    public static final int DEFAULT_SSL_PORT = 5671;
-
-    private static final String JAVAX_NET_SSL_KEY_STORE = "javax.net.ssl.keyStore";
-    private static final String JAVAX_NET_SSL_KEY_STORE_TYPE = "javax.net.ssl.keyStoreType";
-    private static final String JAVAX_NET_SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
-    private static final String JAVAX_NET_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
-    private static final String JAVAX_NET_SSL_TRUST_STORE_TYPE = "javax.net.ssl.trustStoreType";
-    private static final String JAVAX_NET_SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
-
-    private String keyStoreLocation;
-    private String keyStorePassword;
-    private String trustStoreLocation;
-    private String trustStorePassword;
-    private String keyStoreType;
-    private String trustStoreType;
-    private String[] enabledCipherSuites;
-    private String[] disabledCipherSuites;
-    private String[] enabledProtocols;
-    private String[] disabledProtocols = DEFAULT_DISABLED_PROTOCOLS.toArray(new String[0]);
-    private String contextProtocol = DEFAULT_CONTEXT_PROTOCOL;
-
-    private boolean trustAll = DEFAULT_TRUST_ALL;
-    private boolean verifyHost = DEFAULT_VERIFY_HOST;
-    private String keyAlias;
-    private int defaultSslPort = DEFAULT_SSL_PORT;
-    private SSLContext sslContextOverride;
-
-    public TransportSslOptions() {
-        setKeyStoreLocation(System.getProperty(JAVAX_NET_SSL_KEY_STORE));
-        setKeyStoreType(System.getProperty(JAVAX_NET_SSL_KEY_STORE_TYPE, DEFAULT_STORE_TYPE));
-        setKeyStorePassword(System.getProperty(JAVAX_NET_SSL_KEY_STORE_PASSWORD));
-        setTrustStoreLocation(System.getProperty(JAVAX_NET_SSL_TRUST_STORE));
-        setTrustStoreType(System.getProperty(JAVAX_NET_SSL_TRUST_STORE_TYPE, DEFAULT_STORE_TYPE));
-        setTrustStorePassword(System.getProperty(JAVAX_NET_SSL_TRUST_STORE_PASSWORD));
-    }
-
-    /**
-     * @return the keyStoreLocation currently configured.
-     */
-    public String getKeyStoreLocation() {
-        return keyStoreLocation;
-    }
-
-    /**
-     * Sets the location on disk of the key store to use.
-     *
-     * @param keyStoreLocation
-     *        the keyStoreLocation to use to create the key manager.
-     */
-    public void setKeyStoreLocation(String keyStoreLocation) {
-        this.keyStoreLocation = keyStoreLocation;
-    }
-
-    /**
-     * @return the keyStorePassword
-     */
-    public String getKeyStorePassword() {
-        return keyStorePassword;
-    }
-
-    /**
-     * @param keyStorePassword the keyStorePassword to set
-     */
-    public void setKeyStorePassword(String keyStorePassword) {
-        this.keyStorePassword = keyStorePassword;
-    }
-
-    /**
-     * @return the trustStoreLocation
-     */
-    public String getTrustStoreLocation() {
-        return trustStoreLocation;
-    }
-
-    /**
-     * @param trustStoreLocation the trustStoreLocation to set
-     */
-    public void setTrustStoreLocation(String trustStoreLocation) {
-        this.trustStoreLocation = trustStoreLocation;
-    }
-
-    /**
-     * @return the trustStorePassword
-     */
-    public String getTrustStorePassword() {
-        return trustStorePassword;
-    }
-
-    /**
-     * @param trustStorePassword the trustStorePassword to set
-     */
-    public void setTrustStorePassword(String trustStorePassword) {
-        this.trustStorePassword = trustStorePassword;
-    }
-
-    /**
-     * @param storeType
-     *        the format that the store files are encoded in.
-     */
-    public void setStoreType(String storeType) {
-        setKeyStoreType(storeType);
-        setTrustStoreType(storeType);
-    }
-
-    /**
-     * @return the keyStoreType
-     */
-    public String getKeyStoreType() {
-        return keyStoreType;
-    }
-
-    /**
-     * @param keyStoreType
-     *        the format that the keyStore file is encoded in
-     */
-    public void setKeyStoreType(String keyStoreType) {
-        this.keyStoreType = keyStoreType;
-    }
-
-    /**
-     * @return the trustStoreType
-     */
-    public String getTrustStoreType() {
-        return trustStoreType;
-    }
-
-    /**
-     * @param trustStoreType
-     *        the format that the trustStore file is encoded in
-     */
-    public void setTrustStoreType(String trustStoreType) {
-        this.trustStoreType = trustStoreType;
-    }
-
-    /**
-     * @return the enabledCipherSuites
-     */
-    public String[] getEnabledCipherSuites() {
-        return enabledCipherSuites;
-    }
-
-    /**
-     * @param enabledCipherSuites the enabledCipherSuites to set
-     */
-    public void setEnabledCipherSuites(String[] enabledCipherSuites) {
-        this.enabledCipherSuites = enabledCipherSuites;
-    }
-
-    /**
-     * @return the disabledCipherSuites
-     */
-    public String[] getDisabledCipherSuites() {
-        return disabledCipherSuites;
-    }
-
-    /**
-     * @param disabledCipherSuites the disabledCipherSuites to set
-     */
-    public void setDisabledCipherSuites(String[] disabledCipherSuites) {
-        this.disabledCipherSuites = disabledCipherSuites;
-    }
-
-    /**
-     * @return the enabledProtocols or null if the defaults should be used
-     */
-    public String[] getEnabledProtocols() {
-        return enabledProtocols;
-    }
-
-    /**
-     * The protocols to be set as enabled.
-     *
-     * @param enabledProtocols the enabled protocols to set, or null if the defaults should be used.
-     */
-    public void setEnabledProtocols(String[] enabledProtocols) {
-        this.enabledProtocols = enabledProtocols;
-    }
-
-    /**
-     *
-     * @return the protocols to disable or null if none should be
-     */
-    public String[] getDisabledProtocols() {
-        return disabledProtocols;
-    }
-
-    /**
-     * The protocols to be disable.
-     *
-     * @param disabledProtocols the protocols to disable, or null if none should be.
-     */
-    public void setDisabledProtocols(String[] disabledProtocols) {
-        this.disabledProtocols = disabledProtocols;
-    }
-
-    /**
-    * @return the context protocol to use
-    */
-    public String getContextProtocol() {
-        return contextProtocol;
-    }
-
-    /**
-     * The protocol value to use when creating an SSLContext via
-     * SSLContext.getInstance(protocol).
-     *
-     * @param contextProtocol the context protocol to use.
-     */
-    public void setContextProtocol(String contextProtocol) {
-        this.contextProtocol = contextProtocol;
-    }
-
-    /**
-     * @return the trustAll
-     */
-    public boolean isTrustAll() {
-        return trustAll;
-    }
-
-    /**
-     * @param trustAll the trustAll to set
-     */
-    public void setTrustAll(boolean trustAll) {
-        this.trustAll = trustAll;
-    }
-
-    /**
-     * @return the verifyHost
-     */
-    public boolean isVerifyHost() {
-        return verifyHost;
-    }
-
-    /**
-     * @param verifyHost the verifyHost to set
-     */
-    public void setVerifyHost(boolean verifyHost) {
-        this.verifyHost = verifyHost;
-    }
-
-    /**
-     * @return the key alias
-     */
-    public String getKeyAlias() {
-        return keyAlias;
-    }
-
-    /**
-     * @param keyAlias the key alias to use
-     */
-    public void setKeyAlias(String keyAlias) {
-        this.keyAlias = keyAlias;
-    }
-
-    public int getDefaultSslPort() {
-        return defaultSslPort;
-    }
-
-    public void setDefaultSslPort(int defaultSslPort) {
-        this.defaultSslPort = defaultSslPort;
-    }
-
-    public void setSslContextOverride(SSLContext sslContextOverride) {
-        this.sslContextOverride = sslContextOverride;
-    }
-
-    public SSLContext getSslContextOverride() {
-        return sslContextOverride;
-    }
-
-    @Override
-    public TransportSslOptions clone() {
-        return copyOptions(new TransportSslOptions());
-    }
-
-    @Override
-    public boolean isSSL() {
-        return true;
-    }
-
-    protected TransportSslOptions copyOptions(TransportSslOptions copy) {
-        super.copyOptions(copy);
-
-        copy.setKeyStoreLocation(getKeyStoreLocation());
-        copy.setKeyStorePassword(getKeyStorePassword());
-        copy.setTrustStoreLocation(getTrustStoreLocation());
-        copy.setTrustStorePassword(getTrustStorePassword());
-        copy.setKeyStoreType(getKeyStoreType());
-        copy.setTrustStoreType(getTrustStoreType());
-        copy.setEnabledCipherSuites(getEnabledCipherSuites());
-        copy.setDisabledCipherSuites(getDisabledCipherSuites());
-        copy.setEnabledProtocols(getEnabledProtocols());
-        copy.setDisabledProtocols(getDisabledProtocols());
-        copy.setTrustAll(isTrustAll());
-        copy.setVerifyHost(isVerifyHost());
-        copy.setKeyAlias(getKeyAlias());
-        copy.setContextProtocol(getContextProtocol());
-        copy.setDefaultSslPort(getDefaultSslPort());
-        copy.setSslContextOverride(getSslContextOverride());
-
-        return copy;
-    }
-}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java
index 75cfef1..cc96c78 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java
@@ -16,8 +16,6 @@
  */
 package org.apache.qpid.jms.transports;
 
-import io.netty.handler.ssl.SslHandler;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -44,6 +42,8 @@ import javax.net.ssl.X509TrustManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.netty.handler.ssl.SslHandler;
+
 /**
  * Static class that provides various utility methods used by Transport implementations.
  */
@@ -68,7 +68,7 @@ public class TransportSupport {
      *
      * @throws Exception if an error occurs while creating the SslHandler instance.
      */
-    public static SslHandler createSslHandler(URI remote, TransportSslOptions options) throws Exception {
+    public static SslHandler createSslHandler(URI remote, TransportOptions options) throws Exception {
         SSLContext sslContext = options.getSslContextOverride();
         if(sslContext == null) {
             sslContext = createSslContext(options);
@@ -90,7 +90,7 @@ public class TransportSupport {
      *
      * @throws Exception if an error occurs while creating the context.
      */
-    public static SSLContext createSslContext(TransportSslOptions options) throws Exception {
+    public static SSLContext createSslContext(TransportOptions options) throws Exception {
         try {
             String contextProtocol = options.getContextProtocol();
             LOG.trace("Getting SSLContext instance using protocol: {}", contextProtocol);
@@ -114,13 +114,13 @@ public class TransportSupport {
      * @param context
      *        the SSLContext to use when creating the engine.
      * @param options
-     *        the TransportSslOptions to use to configure the new SSLEngine.
+     *        the TransportOptions to use to configure the new SSLEngine.
      *
      * @return a new SSLEngine instance in client mode.
      *
      * @throws Exception if an error occurs while creating the new SSLEngine.
      */
-    public static SSLEngine createSslEngine(SSLContext context, TransportSslOptions options) throws Exception {
+    public static SSLEngine createSslEngine(SSLContext context, TransportOptions options) throws Exception {
         return createSslEngine(null, context, options);
     }
 
@@ -133,13 +133,13 @@ public class TransportSupport {
      * @param context
      *        the SSLContext to use when creating the engine.
      * @param options
-     *        the TransportSslOptions to use to configure the new SSLEngine.
+     *        the TransportOptions to use to configure the new SSLEngine.
      *
      * @return a new SSLEngine instance in client mode.
      *
      * @throws Exception if an error occurs while creating the new SSLEngine.
      */
-    public static SSLEngine createSslEngine(URI remote, SSLContext context, TransportSslOptions options) throws Exception {
+    public static SSLEngine createSslEngine(URI remote, SSLContext context, TransportOptions options) throws Exception {
         SSLEngine engine = null;
         if(remote == null) {
             engine = context.createSSLEngine();
@@ -160,7 +160,7 @@ public class TransportSupport {
         return engine;
     }
 
-    private static String[] buildEnabledProtocols(SSLEngine engine, TransportSslOptions options) {
+    private static String[] buildEnabledProtocols(SSLEngine engine, TransportOptions options) {
         List<String> enabledProtocols = new ArrayList<String>();
 
         if (options.getEnabledProtocols() != null) {
@@ -185,7 +185,7 @@ public class TransportSupport {
         return enabledProtocols.toArray(new String[0]);
     }
 
-    private static String[] buildEnabledCipherSuites(SSLEngine engine, TransportSslOptions options) {
+    private static String[] buildEnabledCipherSuites(SSLEngine engine, TransportOptions options) {
         List<String> enabledCipherSuites = new ArrayList<String>();
 
         if (options.getEnabledCipherSuites() != null) {
@@ -210,7 +210,7 @@ public class TransportSupport {
         return enabledCipherSuites.toArray(new String[0]);
     }
 
-    private static TrustManager[] loadTrustManagers(TransportSslOptions options) throws Exception {
+    private static TrustManager[] loadTrustManagers(TransportOptions options) throws Exception {
         if (options.isTrustAll()) {
             return new TrustManager[] { createTrustAllTrustManager() };
         }
@@ -233,7 +233,7 @@ public class TransportSupport {
         return fact.getTrustManagers();
     }
 
-    private static KeyManager[] loadKeyManagers(TransportSslOptions options) throws Exception {
+    private static KeyManager[] loadKeyManagers(TransportOptions options) throws Exception {
         if (options.getKeyStoreLocation() == null) {
             return null;
         }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactory.java
index 628983a..db50abe 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettySslTransportFactory.java
@@ -16,20 +16,12 @@
  */
 package org.apache.qpid.jms.transports.netty;
 
-import org.apache.qpid.jms.transports.TransportOptions;
-import org.apache.qpid.jms.transports.TransportSslOptions;
-
 /**
  * Creates a Netty based SSL transport.
  */
 public class NettySslTransportFactory extends NettyTcpTransportFactory {
 
     @Override
-    protected TransportOptions doCreateTransportOptions() {
-        return new TransportSslOptions();
-    }
-
-    @Override
     public String getName() {
         return "SSL";
     }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransport.java
index d1e7ee0..a5b7ef7 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransport.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransport.java
@@ -28,7 +28,6 @@ import javax.net.ssl.SSLContext;
 import org.apache.qpid.jms.transports.Transport;
 import org.apache.qpid.jms.transports.TransportListener;
 import org.apache.qpid.jms.transports.TransportOptions;
-import org.apache.qpid.jms.transports.TransportSslOptions;
 import org.apache.qpid.jms.transports.TransportSupport;
 import org.apache.qpid.jms.util.IOExceptionSupport;
 import org.slf4j.Logger;
@@ -77,6 +76,7 @@ public class NettyTcpTransport implements Transport {
     protected TransportListener listener;
     protected int maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
 
+    private final boolean secure;
     private final TransportOptions options;
     private final URI remote;
     private final AtomicBoolean connected = new AtomicBoolean();
@@ -91,9 +91,11 @@ public class NettyTcpTransport implements Transport {
      *        the URI that defines the remote resource to connect to.
      * @param options
      *        the transport options used to configure the socket connection.
+     * @param secure
+     * 		  should the transport enable an SSL layer.
      */
-    public NettyTcpTransport(URI remoteLocation, TransportOptions options) {
-        this(null, remoteLocation, options);
+    public NettyTcpTransport(URI remoteLocation, TransportOptions options, boolean secure) {
+        this(null, remoteLocation, options, secure);
     }
 
     /**
@@ -105,8 +107,10 @@ public class NettyTcpTransport implements Transport {
      *        the URI that defines the remote resource to connect to.
      * @param options
      *        the transport options used to configure the socket connection.
+     * @param secure
+     * 		  should the transport enable an SSL layer.
      */
-    public NettyTcpTransport(TransportListener listener, URI remoteLocation, TransportOptions options) {
+    public NettyTcpTransport(TransportListener listener, URI remoteLocation, TransportOptions options, boolean secure) {
         if (options == null) {
             throw new IllegalArgumentException("Transport Options cannot be null");
         }
@@ -115,6 +119,7 @@ public class NettyTcpTransport implements Transport {
             throw new IllegalArgumentException("Transport remote location cannot be null");
         }
 
+        this.secure = secure;
         this.options = options;
         this.listener = listener;
         this.remote = remoteLocation;
@@ -127,13 +132,12 @@ public class NettyTcpTransport implements Transport {
             throw new IllegalStateException("A transport listener must be set before connection attempts.");
         }
 
+        getTransportOptions().setSslContextOverride(sslContextOverride);
+
         final SslHandler sslHandler;
         if (isSecure()) {
             try {
-                TransportSslOptions sslOptions = getSslOptions();
-                sslOptions.setSslContextOverride(sslContextOverride);
-
-                sslHandler = TransportSupport.createSslHandler(getRemoteLocation(), sslOptions);
+                sslHandler = TransportSupport.createSslHandler(getRemoteLocation(), getTransportOptions());
             } catch (Exception ex) {
                 // TODO: can we stop it throwing Exception?
                 throw IOExceptionSupport.create(ex);
@@ -229,7 +233,7 @@ public class NettyTcpTransport implements Transport {
 
     @Override
     public boolean isSecure() {
-        return options.isSSL();
+        return secure;
     }
 
     @Override
@@ -322,7 +326,7 @@ public class NettyTcpTransport implements Transport {
         if (remote.getPort() != -1) {
             return remote.getPort();
         } else {
-            return isSecure() ? getSslOptions().getDefaultSslPort() : getTransportOptions().getDefaultTcpPort();
+            return isSecure() ? getTransportOptions().getDefaultSslPort() : getTransportOptions().getDefaultTcpPort();
         }
     }
 
@@ -404,10 +408,6 @@ public class NettyTcpTransport implements Transport {
         connectLatch.countDown();
     }
 
-    private TransportSslOptions getSslOptions() {
-        return (TransportSslOptions) getTransportOptions();
-    }
-
     private void configureNetty(Bootstrap bootstrap, TransportOptions options) {
         bootstrap.option(ChannelOption.TCP_NODELAY, options.isTcpNoDelay());
         bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.getConnectTimeout());

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactory.java
index 56ce248..5278894 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyTcpTransportFactory.java
@@ -28,7 +28,7 @@ public class NettyTcpTransportFactory extends TransportFactory {
 
     @Override
     protected NettyTcpTransport doCreateTransport(URI remoteURI, TransportOptions transportOptions) throws Exception {
-        return new NettyTcpTransport(remoteURI, transportOptions);
+        return new NettyTcpTransport(remoteURI, transportOptions, isSecure());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransport.java
index de69e5a..93370a3 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransport.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransport.java
@@ -19,6 +19,7 @@ package org.apache.qpid.jms.transports.netty;
 import java.io.IOException;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
+import java.util.Map;
 
 import org.apache.qpid.jms.transports.TransportListener;
 import org.apache.qpid.jms.transports.TransportOptions;
@@ -60,9 +61,11 @@ public class NettyWsTransport extends NettyTcpTransport {
      *        the URI that defines the remote resource to connect to.
      * @param options
      *        the transport options used to configure the socket connection.
+     * @param secure
+     * 		  should the transport enable an SSL layer.
      */
-    public NettyWsTransport(URI remoteLocation, TransportOptions options) {
-        super(null, remoteLocation, options);
+    public NettyWsTransport(URI remoteLocation, TransportOptions options, boolean secure) {
+        super(null, remoteLocation, options, secure);
     }
 
     /**
@@ -74,9 +77,11 @@ public class NettyWsTransport extends NettyTcpTransport {
      *        the URI that defines the remote resource to connect to.
      * @param options
      *        the transport options used to configure the socket connection.
+     * @param secure
+     * 		  should the transport enable an SSL layer.
      */
-    public NettyWsTransport(TransportListener listener, URI remoteLocation, TransportOptions options) {
-        super(listener, remoteLocation, options);
+    public NettyWsTransport(TransportListener listener, URI remoteLocation, TransportOptions options, boolean secure) {
+        super(listener, remoteLocation, options, secure);
     }
 
     @Override
@@ -115,9 +120,16 @@ public class NettyWsTransport extends NettyTcpTransport {
         private final WebSocketClientHandshaker handshaker;
 
         public NettyWebSocketTransportHandler() {
+            DefaultHttpHeaders headers = new DefaultHttpHeaders();
+
+            getTransportOptions().getHttpHeaders();
+            for (Map.Entry<String, String> entry : getTransportOptions().getHttpHeaders().entrySet()) {
+                headers.set(entry.getKey(), entry.getValue());
+            }
+
             handshaker = WebSocketClientHandshakerFactory.newHandshaker(
                 getRemoteLocation(), WebSocketVersion.V13, AMQP_SUB_PROTOCOL,
-                true, new DefaultHttpHeaders(), getMaxFrameSize());
+                true, headers, getMaxFrameSize());
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransportFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransportFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransportFactory.java
index 2f416bc..3c500b5 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransportFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWsTransportFactory.java
@@ -17,9 +17,11 @@
 package org.apache.qpid.jms.transports.netty;
 
 import java.net.URI;
+import java.util.Map;
 
 import org.apache.qpid.jms.transports.TransportFactory;
 import org.apache.qpid.jms.transports.TransportOptions;
+import org.apache.qpid.jms.util.PropertyUtil;
 
 /**
  * Factory for creating the Netty based WebSocket Transport.
@@ -28,11 +30,24 @@ public class NettyWsTransportFactory extends TransportFactory {
 
     @Override
     protected NettyTcpTransport doCreateTransport(URI remoteURI, TransportOptions transportOptions) throws Exception {
-        return new NettyWsTransport(remoteURI, transportOptions);
+        return new NettyWsTransport(remoteURI, transportOptions, isSecure());
     }
 
     @Override
     public String getName() {
         return "WS";
     }
+
+    @Override
+    protected TransportOptions applyTransportConfiguration(TransportOptions transportOptions, Map<String, String> transportURIOptions) {
+        // WS Transport allows HTTP Headers in its configuration using a prefix "transport.ws.httpHeader.X=Y"
+        Map<String, String> httpHeaders =
+            PropertyUtil.filterProperties(transportURIOptions, "ws.httpHeader.");
+
+        // We have no way to validate what was configured so apply them all and let the user sort
+        // out any resulting mess if the connection should fail.
+        transportOptions.getHttpHeaders().putAll(httpHeaders);
+
+        return super.applyTransportConfiguration(transportOptions, transportURIOptions);
+    }
 }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWssTransportFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWssTransportFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWssTransportFactory.java
index ef594c6..2bbe5df 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWssTransportFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/netty/NettyWssTransportFactory.java
@@ -16,20 +16,12 @@
  */
 package org.apache.qpid.jms.transports.netty;
 
-import org.apache.qpid.jms.transports.TransportOptions;
-import org.apache.qpid.jms.transports.TransportSslOptions;
-
 /**
  * Creates a Netty based Secure WebSocket transport.
  */
 public class NettyWssTransportFactory extends NettyWsTransportFactory {
 
     @Override
-    protected TransportOptions doCreateTransportOptions() {
-        return new TransportSslOptions();
-    }
-
-    @Override
     public String getName() {
         return "WSS";
     }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslIntegrationTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslIntegrationTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslIntegrationTest.java
index 165ee22..434a503 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslIntegrationTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SaslIntegrationTest.java
@@ -20,15 +20,11 @@
  */
 package org.apache.qpid.jms.integration;
 
-import org.apache.qpid.jms.JmsConnectionFactory;
-import org.apache.qpid.jms.test.QpidJmsTestCase;
-import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
-import org.apache.qpid.jms.transports.TransportSslOptions;
-import org.apache.qpid.jms.transports.TransportSupport;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 
 import java.net.URLDecoder;
 import java.net.URLEncoder;
@@ -42,11 +38,16 @@ import javax.jms.JMSSecurityException;
 import javax.jms.JMSSecurityRuntimeException;
 import javax.net.ssl.SSLContext;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
+import org.apache.qpid.jms.JmsConnectionExtensions;
+import org.apache.qpid.jms.JmsConnectionFactory;
+import org.apache.qpid.jms.test.QpidJmsTestCase;
+import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
+import org.apache.qpid.jms.transports.TransportOptions;
+import org.apache.qpid.jms.transports.TransportSupport;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class SaslIntegrationTest extends QpidJmsTestCase {
 
@@ -68,7 +69,7 @@ public class SaslIntegrationTest extends QpidJmsTestCase {
 
     @Test(timeout = 20000)
     public void testSaslExternalConnection() throws Exception {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);
@@ -300,7 +301,7 @@ public class SaslIntegrationTest extends QpidJmsTestCase {
     }
 
     private void doMechanismSelectedExternalTestImpl(boolean requireClientCert, Symbol clientSelectedMech, Symbol[] serverMechs) throws Exception {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);
@@ -448,4 +449,95 @@ public class SaslIntegrationTest extends QpidJmsTestCase {
             testPeer.waitForAllHandlersToComplete(1000);
         }
     }
+
+    @Test(timeout = 20000)
+    public void testUserOnlyExtensionsApplied() throws Exception {
+        try (TestAmqpPeer testPeer = new TestAmqpPeer();) {
+
+            // Expect a PLAIN connection
+            final String user = "user";
+            final String pass = "qwerty123456";
+
+            testPeer.expectSaslPlain(user, pass);
+            testPeer.expectOpen();
+
+            // Each connection creates a session for managing temporary destinations etc
+            testPeer.expectBegin();
+
+            JmsConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:" + testPeer.getServerPort());
+
+            factory.setExtension(JmsConnectionExtensions.USERNAME_OVERRIDE.toString(), (connection) -> { return user; });
+
+            Connection connection = factory.createConnection(null, pass);
+            // Set a clientID to provoke the actual AMQP connection process to occur.
+            connection.setClientID("clientName");
+
+            testPeer.waitForAllHandlersToComplete(1000);
+            assertNull(testPeer.getThrowable());
+
+            testPeer.expectClose();
+            connection.close();
+        }
+    }
+
+    @Test(timeout = 20000)
+    public void testPasswordOnlyExtensionsApplied() throws Exception {
+        try (TestAmqpPeer testPeer = new TestAmqpPeer();) {
+
+            // Expect a PLAIN connection
+            final String user = "user";
+            final String pass = "qwerty123456";
+
+            testPeer.expectSaslPlain(user, pass);
+            testPeer.expectOpen();
+
+            // Each connection creates a session for managing temporary destinations etc
+            testPeer.expectBegin();
+
+            JmsConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:" + testPeer.getServerPort());
+
+            factory.setExtension(JmsConnectionExtensions.PASSWORD_OVERRIDE.toString(), (connection) -> { return pass; });
+
+            Connection connection = factory.createConnection(user, null);
+            // Set a clientID to provoke the actual AMQP connection process to occur.
+            connection.setClientID("clientName");
+
+            testPeer.waitForAllHandlersToComplete(1000);
+            assertNull(testPeer.getThrowable());
+
+            testPeer.expectClose();
+            connection.close();
+        }
+    }
+
+    @Test(timeout = 20000)
+    public void testUserAndPasswordExtensionsApplied() throws Exception {
+        try (TestAmqpPeer testPeer = new TestAmqpPeer();) {
+
+            // Expect a PLAIN connection
+            final String user = "user";
+            final String pass = "qwerty123456";
+
+            testPeer.expectSaslPlain(user, pass);
+            testPeer.expectOpen();
+
+            // Each connection creates a session for managing temporary destinations etc
+            testPeer.expectBegin();
+
+            JmsConnectionFactory factory = new JmsConnectionFactory("amqp://localhost:" + testPeer.getServerPort());
+
+            factory.setExtension(JmsConnectionExtensions.USERNAME_OVERRIDE.toString(), (connection) -> { return user; });
+            factory.setExtension(JmsConnectionExtensions.PASSWORD_OVERRIDE.toString(), (connection) -> { return pass; });
+
+            Connection connection = factory.createConnection();
+            // Set a clientID to provoke the actual AMQP connection process to occur.
+            connection.setClientID("clientName");
+
+            testPeer.waitForAllHandlersToComplete(1000);
+            assertNull(testPeer.getThrowable());
+
+            testPeer.expectClose();
+            connection.close();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SslIntegrationTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SslIntegrationTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SslIntegrationTest.java
index 9e25779..8837c74 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SslIntegrationTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/integration/SslIntegrationTest.java
@@ -39,10 +39,11 @@ import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
 
+import org.apache.qpid.jms.JmsConnectionExtensions;
 import org.apache.qpid.jms.JmsConnectionFactory;
 import org.apache.qpid.jms.test.QpidJmsTestCase;
 import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
-import org.apache.qpid.jms.transports.TransportSslOptions;
+import org.apache.qpid.jms.transports.TransportOptions;
 import org.apache.qpid.jms.transports.TransportSupport;
 import org.junit.Test;
 
@@ -82,7 +83,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
 
     @Test(timeout = 20000)
     public void testCreateAndCloseSslConnection() throws Exception {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);
@@ -104,7 +105,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
 
     @Test(timeout = 20000)
     public void testCreateSslConnectionWithServerSendingPreemptiveData() throws Exception {
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);
         serverSslOptions.setVerifyHost(false);
@@ -135,7 +136,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
 
     @Test(timeout = 20000)
     public void testCreateAndCloseSslConnectionWithClientAuth() throws Exception {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
@@ -167,7 +168,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
     }
 
     private void doConnectionWithAliasTestImpl(String alias, String expectedDN) throws Exception, JMSException, SSLPeerUnverifiedException, IOException {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
@@ -212,7 +213,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
     }
 
     private void doCreateConnectionWithInvalidAliasTestImpl(String alias) throws Exception, IOException {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
@@ -254,13 +255,24 @@ public class SslIntegrationTest extends QpidJmsTestCase {
         assertNotEquals(CLIENT_DN, CLIENT2_DN);
 
         // Connect providing the Client 1 details via context override, expect Client1 DN.
-        doConnectionWithSslContextOverride(CLIENT_JKS_KEYSTORE, CLIENT_DN);
+        doConnectionWithSslContextOverride(CLIENT_JKS_KEYSTORE, CLIENT_DN, false);
         // Connect providing the Client 2 details via context override, expect Client2 DN instead.
-        doConnectionWithSslContextOverride(CLIENT2_JKS_KEYSTORE, CLIENT2_DN);
+        doConnectionWithSslContextOverride(CLIENT2_JKS_KEYSTORE, CLIENT2_DN, false);
     }
 
-    private void doConnectionWithSslContextOverride(String clientKeyStorePath, String expectedDN) throws Exception {
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+    @Test(timeout = 20000)
+    public void testCreateConnectionWithSslContextOverrideByExtension() throws Exception {
+        assertNotEquals(CLIENT_JKS_KEYSTORE, CLIENT2_JKS_KEYSTORE);
+        assertNotEquals(CLIENT_DN, CLIENT2_DN);
+
+        // Connect providing the Client 1 details via context override, expect Client1 DN.
+        doConnectionWithSslContextOverride(CLIENT_JKS_KEYSTORE, CLIENT_DN, true);
+        // Connect providing the Client 2 details via context override, expect Client2 DN instead.
+        doConnectionWithSslContextOverride(CLIENT2_JKS_KEYSTORE, CLIENT2_DN, true);
+    }
+
+    private void doConnectionWithSslContextOverride(String clientKeyStorePath, String expectedDN, boolean useExtension) throws Exception {
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);
@@ -269,17 +281,26 @@ public class SslIntegrationTest extends QpidJmsTestCase {
 
         SSLContext serverContext = TransportSupport.createSslContext(serverSslOptions);
 
-        TransportSslOptions clientSslOptions = new TransportSslOptions();
+        TransportOptions clientSslOptions = new TransportOptions();
         clientSslOptions.setKeyStoreLocation(clientKeyStorePath);
         clientSslOptions.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE);
         clientSslOptions.setKeyStorePassword(PASSWORD);
         clientSslOptions.setTrustStorePassword(PASSWORD);
 
-        SSLContext clientContext = TransportSupport.createSslContext(clientSslOptions);
-
         try (TestAmqpPeer testPeer = new TestAmqpPeer(serverContext, true);) {
             JmsConnectionFactory factory = new JmsConnectionFactory("amqps://localhost:" + testPeer.getServerPort());
-            factory.setSslContext(clientContext);
+
+            if (useExtension) {
+                factory.setExtension(JmsConnectionExtensions.SSL_CONTEXT.toString(), (options) -> {
+                    try {
+                        return TransportSupport.createSslContext(clientSslOptions);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e.getMessage(), e);
+                    }
+                });
+            } else {
+                factory.setSslContext(TransportSupport.createSslContext(clientSslOptions));
+            }
 
             testPeer.expectSaslPlain("guest", "guest");
             testPeer.expectOpen();
@@ -321,7 +342,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
         // Connect without providing a context, expect Client1 DN.
         doConnectionWithSslContextOverrideAndURIConfig(null, CLIENT_DN);
 
-        TransportSslOptions clientSslOptions = new TransportSslOptions();
+        TransportOptions clientSslOptions = new TransportOptions();
         clientSslOptions.setKeyStoreLocation(CLIENT2_JKS_KEYSTORE);
         clientSslOptions.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE);
         clientSslOptions.setKeyStorePassword(PASSWORD);
@@ -334,7 +355,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
     }
 
     private void doConnectionWithSslContextOverrideAndURIConfig(SSLContext clientContext, String expectedDN) throws Exception {
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);
@@ -442,7 +463,7 @@ public class SslIntegrationTest extends QpidJmsTestCase {
     }
 
     private void doConfigureStoresWithSslSystemPropertiesTestImpl(String expectedDN, boolean usePkcs12Store) throws Exception {
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
 
         if (!usePkcs12Store) {
             serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/8bf97c4b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/failover/FailoverWithAmqpOpenProvidedServerListIntegrationTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/failover/FailoverWithAmqpOpenProvidedServerListIntegrationTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/failover/FailoverWithAmqpOpenProvidedServerListIntegrationTest.java
index 81447bf..347e5a1 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/failover/FailoverWithAmqpOpenProvidedServerListIntegrationTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/failover/FailoverWithAmqpOpenProvidedServerListIntegrationTest.java
@@ -41,7 +41,7 @@ import org.apache.qpid.jms.JmsDefaultConnectionListener;
 import org.apache.qpid.jms.test.QpidJmsTestCase;
 import org.apache.qpid.jms.test.testpeer.TestAmqpPeer;
 import org.apache.qpid.jms.test.testpeer.basictypes.AmqpError;
-import org.apache.qpid.jms.transports.TransportSslOptions;
+import org.apache.qpid.jms.transports.TransportOptions;
 import org.apache.qpid.jms.transports.TransportSupport;
 import org.apache.qpid.jms.util.PropertyUtil;
 import org.apache.qpid.jms.util.URISupport;
@@ -399,7 +399,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
      */
     @Test(timeout = 20000)
     public void testFailoverUsingSSLConfiguredBySystemProperties() throws Exception {
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);
@@ -508,7 +508,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
      */
     @Test(timeout = 20000)
     public void testFailoverUsingSSLConfiguredByTransportOptions() throws Exception {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);
@@ -627,7 +627,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
      */
     @Test(timeout = 20000)
     public void testFailoverUsingSSLConfiguredByNestedTransportOptions() throws Exception {
-        TransportSslOptions sslOptions = new TransportSslOptions();
+        TransportOptions sslOptions = new TransportOptions();
         sslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         sslOptions.setKeyStorePassword(PASSWORD);
         sslOptions.setVerifyHost(false);
@@ -746,7 +746,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
      */
     @Test(timeout = 20000)
     public void testFailoverUsingSSLConfiguredByCustomSSLContext() throws Exception {
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);
@@ -755,7 +755,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
 
         SSLContext serverSslContext = TransportSupport.createSslContext(serverSslOptions);
 
-        TransportSslOptions clientSslOptions = new TransportSslOptions();
+        TransportOptions clientSslOptions = new TransportOptions();
         clientSslOptions.setKeyStoreLocation(CLIENT_JKS_KEYSTORE);
         clientSslOptions.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE);
         clientSslOptions.setKeyStorePassword(PASSWORD);
@@ -885,7 +885,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
 
     private void doTestFailoverHandlingOfInsecureRedirectAdvertisement(boolean allow) throws Exception {
 
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);
@@ -992,7 +992,7 @@ public class FailoverWithAmqpOpenProvidedServerListIntegrationTest extends QpidJ
 
     private void doTestFailoverAcceptsUpdateUsingTransportSchemes(String transportScheme, String expected) throws Exception {
 
-        TransportSslOptions serverSslOptions = new TransportSslOptions();
+        TransportOptions serverSslOptions = new TransportOptions();
         serverSslOptions.setKeyStoreLocation(BROKER_JKS_KEYSTORE);
         serverSslOptions.setTrustStoreLocation(BROKER_JKS_TRUSTSTORE);
         serverSslOptions.setKeyStorePassword(PASSWORD);


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