QPID-8074: [JMS AMQP 0-x][System Tests] Copy client specofic test ConnectionTest from Broker-J sources
diff --git a/systests/src/main/java/org/apache/qpid/systest/core/BrokerAdmin.java b/systests/src/main/java/org/apache/qpid/systest/core/BrokerAdmin.java
index befba5f..136d3f0 100644
--- a/systests/src/main/java/org/apache/qpid/systest/core/BrokerAdmin.java
+++ b/systests/src/main/java/org/apache/qpid/systest/core/BrokerAdmin.java
@@ -43,10 +43,11 @@
String getValidUsername();
String getValidPassword();
+ String getVirtualHostName();
String getType();
- BrokerType getBrokerType();
+ BrokerType getBrokerType();
Connection getConnection() throws JMSException;
Connection getConnection(Map<String, String> options) throws JMSException;
diff --git a/systests/src/main/java/org/apache/qpid/systest/core/brokerj/SpawnQpidBrokerAdmin.java b/systests/src/main/java/org/apache/qpid/systest/core/brokerj/SpawnQpidBrokerAdmin.java
index 8842e83..913b018 100644
--- a/systests/src/main/java/org/apache/qpid/systest/core/brokerj/SpawnQpidBrokerAdmin.java
+++ b/systests/src/main/java/org/apache/qpid/systest/core/brokerj/SpawnQpidBrokerAdmin.java
@@ -219,6 +219,12 @@
}
@Override
+ public String getVirtualHostName()
+ {
+ return _virtualHostNodeName;
+ }
+
+ @Override
public String getType()
{
return SpawnQpidBrokerAdmin.class.getSimpleName();
diff --git a/systests/src/test/java/org/apache/qpid/systest/connection/ConnectionTest.java b/systests/src/test/java/org/apache/qpid/systest/connection/ConnectionTest.java
new file mode 100644
index 0000000..ce62831
--- /dev/null
+++ b/systests/src/test/java/org/apache/qpid/systest/connection/ConnectionTest.java
@@ -0,0 +1,326 @@
+/*
+ *
+ * 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.systest.connection;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeThat;
+
+import java.net.InetSocketAddress;
+import java.util.Enumeration;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionMetaData;
+import javax.jms.QueueSession;
+import javax.jms.TopicSession;
+
+import org.junit.Test;
+
+import org.apache.qpid.QpidException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.jms.Session;
+import org.apache.qpid.systest.core.BrokerAdmin;
+import org.apache.qpid.systest.core.JmsTestBase;
+
+public class ConnectionTest extends JmsTestBase
+{
+ private static final String BROKER_URL_TEMPLATE = "tcp://%s:%d?failover='nofailover'";
+ private static final String CONNECTION_URL_TEMPLATE = "amqp://%s:%s@%s/%s?brokerlist='%s'";
+ private static final String USER1 = "guest";
+ private static final String USER1_PASSWORD = "guest";
+ private static final String USER2 = "admin";
+ private static final String USER2_PASSWORD = "admin";
+
+ @Test
+ public void testDefaultExchanges() throws Exception
+ {
+ assumeThat("0-10 c++ broker doesn't implement wacky exchanges",
+ getBrokerAdmin().getBrokerType(),
+ is(equalTo(BrokerAdmin.BrokerType.BROKERJ)));
+
+ String connectionUrlTemplate = CONNECTION_URL_TEMPLATE
+ + "&defaultQueueExchange='test.direct'"
+ + "&defaultTopicExchange='test.topic'"
+ + "&temporaryQueueExchange='tmp.direct'"
+ + "&temporaryTopicExchange='tmp.topic'";
+ BrokerAdmin admin = getBrokerAdmin();
+ InetSocketAddress brokerAddress = admin.getBrokerAddress(BrokerAdmin.PortType.AMQP);
+ String brokerUrl = String.format(BROKER_URL_TEMPLATE, brokerAddress.getHostName(), brokerAddress.getPort());
+ String urlString = String.format(connectionUrlTemplate,
+ admin.getValidUsername(),
+ admin.getValidPassword(),
+ getTestName(),
+ admin.getVirtualHostName(),
+ brokerUrl);
+ AMQConnection conn = new AMQConnection(new AMQConnectionURL(urlString));
+ try
+ {
+
+ AMQSession sess = (AMQSession) conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ sess.declareExchange("test.direct", ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);
+
+ sess.declareExchange("tmp.direct", ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);
+
+ sess.declareExchange("tmp.topic", ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);
+
+ sess.declareExchange("test.topic", ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);
+
+ QueueSession queueSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ AMQQueue queue = (AMQQueue) queueSession.createQueue("MyQueue");
+
+ assertEquals(queue.getExchangeName(), "test.direct");
+
+ AMQQueue tempQueue = (AMQQueue) queueSession.createTemporaryQueue();
+
+ assertEquals(tempQueue.getExchangeName(), "tmp.direct");
+
+ queueSession.close();
+
+ TopicSession topicSession = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ AMQTopic topic = (AMQTopic) topicSession.createTopic("silly.topic");
+
+ assertEquals(topic.getExchangeName(), "test.topic");
+
+ AMQTopic tempTopic = (AMQTopic) topicSession.createTemporaryTopic();
+
+ assertEquals(tempTopic.getExchangeName(), "tmp.topic");
+
+ topicSession.close();
+ }
+ finally
+ {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testClientIdIsPopulatedAutomatically() throws Exception
+ {
+ BrokerAdmin admin = getBrokerAdmin();
+ InetSocketAddress brokerAddress = admin.getBrokerAddress(BrokerAdmin.PortType.AMQP);
+ String brokerUrl = String.format(BROKER_URL_TEMPLATE, brokerAddress.getHostName(), brokerAddress.getPort());
+ Connection connection = new AMQConnection(brokerUrl,
+ admin.getValidUsername(),
+ admin.getValidPassword(),
+ null,
+ admin.getVirtualHostName());
+ try
+ {
+ assertNotNull(connection.getClientID());
+ }
+ finally
+ {
+ connection.close();
+ }
+ connection.close();
+ }
+
+ @Test
+ public void testUnsupportedSASLMechanism() throws Exception
+ {
+ BrokerAdmin admin = getBrokerAdmin();
+ InetSocketAddress brokerAddress = admin.getBrokerAddress(BrokerAdmin.PortType.AMQP);
+ String brokerUrl = String.format(BROKER_URL_TEMPLATE + "&sasl_mechs='%s'", brokerAddress.getHostName(),
+ brokerAddress.getPort(), "MY_MECH");
+
+ try
+ {
+ new AMQConnection(brokerUrl,
+ admin.getValidUsername(),
+ admin.getValidPassword(),
+ null,
+ admin.getVirtualHostName());
+ fail("The client should throw a ConnectionException stating the" +
+ " broker does not support the SASL mech specified by the client");
+ }
+ catch (QpidException e)
+ {
+ if (getProtocol().equals("0-10"))
+ {
+ assertTrue("Unexpected exception message : " + e.getMessage(),
+ e.getMessage().contains("Client and broker have no SASL mechanisms in common."));
+ assertTrue("Unexpected exception message : " + e.getMessage(),
+ e.getMessage().contains("Client restricted itself to : MY_MECH"));
+ }
+ else
+ {
+ assertTrue("Unexpected exception message : " + e.getMessage(),
+ e.getMessage().contains("No supported security mechanism found"));
+ }
+ }
+ }
+
+ /**
+ * Tests that when the same user connects twice with same clientid, the second connection
+ * fails if the clientid verification feature is enabled (which uses a dummy 0-10 Session
+ * with the clientid as its name to detect the previous usage of the clientid by the user)
+ */
+ @Test
+ public void testClientIDVerificationForSameUser() throws Exception
+ {
+ assumeThat("QPID-3396: 0-10 client specific behaviour",
+ getProtocol(),
+ is(equalTo("0-10")));
+
+ System.setProperty(ClientProperties.QPID_VERIFY_CLIENT_ID, "true");
+ try
+ {
+ BrokerAdmin admin = getBrokerAdmin();
+ InetSocketAddress brokerAddress = admin.getBrokerAddress(BrokerAdmin.PortType.AMQP);
+ String brokerUrl = String.format(BROKER_URL_TEMPLATE, brokerAddress.getHostName(), brokerAddress.getPort());
+ Connection con = new AMQConnection(brokerUrl,
+ admin.getValidUsername(),
+ admin.getValidPassword(),
+ "client_id",
+ admin.getVirtualHostName());
+ try
+ {
+
+ new AMQConnection(brokerUrl,
+ admin.getValidUsername(),
+ admin.getValidPassword(),
+ "client_id",
+ admin.getVirtualHostName());
+
+ fail("The client should throw a ConnectionException stating the" +
+ " client ID is not unique");
+ }
+ catch (QpidException e)
+ {
+ assertTrue("Incorrect exception thrown: " + e.getMessage(),
+ e.getMessage().contains("ClientID must be unique"));
+ }
+ finally
+ {
+ con.close();
+ }
+ }
+ finally
+ {
+ System.clearProperty(ClientProperties.QPID_VERIFY_CLIENT_ID);
+ }
+ }
+
+ /**
+ * Tests that when different users connects with same clientid, the second connection
+ * succeeds even though the clientid verification feature is enabled (which uses a dummy
+ * 0-10 Session with the clientid as its name; these are only verified unique on a
+ * per-principal basis)
+ */
+ @Test
+ public void testClientIDVerificationForDifferentUsers() throws Exception
+ {
+ System.setProperty(ClientProperties.QPID_VERIFY_CLIENT_ID, "true");
+ try
+ {
+ BrokerAdmin admin = getBrokerAdmin();
+ InetSocketAddress brokerAddress = admin.getBrokerAddress(BrokerAdmin.PortType.AMQP);
+ String brokerUrl = String.format(BROKER_URL_TEMPLATE, brokerAddress.getHostName(), brokerAddress.getPort());
+
+ String clientId = "client_id";
+ Connection con = new AMQConnection(brokerUrl, USER1, USER1_PASSWORD,
+ clientId, admin.getVirtualHostName());
+ try
+ {
+ Connection con2 = new AMQConnection(brokerUrl, USER2, USER2_PASSWORD,
+ clientId, admin.getVirtualHostName());
+ try
+ {
+ assertNotNull(con2.createSession(false, Session.AUTO_ACKNOWLEDGE));
+ }
+ finally
+ {
+ con2.close();
+ }
+ }
+ finally
+ {
+ con.close();
+ }
+ }
+ finally
+ {
+ System.clearProperty(ClientProperties.QPID_VERIFY_CLIENT_ID);
+ }
+ }
+
+ @Test
+ public void testExceptionWhenUserPassIsRequired() throws Exception
+ {
+ assumeThat("QPID-3396: NPE is thrown on 0-8..0-10.",
+ getProtocol(),
+ is(equalTo("0-10")));
+
+ BrokerAdmin admin = getBrokerAdmin();
+ InetSocketAddress brokerAddress = admin.getBrokerAddress(BrokerAdmin.PortType.AMQP);
+ String brokerUrl = String.format(BROKER_URL_TEMPLATE, brokerAddress.getHostName(), brokerAddress.getPort())
+ + "&sasl_mechs='PLAIN%2520CRAM-MD5'";
+ String urlString = String.format("amqp:///%s?brokerlist='%s'", admin.getVirtualHostName(), brokerUrl);
+ AMQConnection conn = null;
+ try
+ {
+ conn = new AMQConnection(urlString);
+ fail("Exception should be thrown as user name and password is required");
+ }
+ catch (Exception e)
+ {
+ if (!e.getMessage().contains("Username and Password is required for the selected mechanism"))
+ {
+ if (conn != null && !conn.isClosed())
+ {
+ conn.close();
+ }
+ fail("Incorrect Exception thrown! The exception thrown is : " + e.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void testConnectionMetadata() throws Exception
+ {
+ Connection con = getConnection();
+ ConnectionMetaData metaData = con.getMetaData();
+ assertNotNull(metaData);
+
+ assertNotNull("Provider version unexpectedly null", metaData.getProviderVersion());
+ assertTrue("Provider version unexpectedly empty", metaData.getProviderVersion().length() > 0);
+
+ assertTrue("Provider major version has unexpected value", metaData.getProviderMajorVersion() > -1);
+ assertTrue("Provider minor version has unexpected value", metaData.getProviderMinorVersion() > -1);
+
+ Enumeration names = metaData.getJMSXPropertyNames();
+ assertNotNull("JMSXPropertyNames unexpectedly null", names);
+ assertTrue("JMSXPropertyNames should have at least one name", names.hasMoreElements());
+ }
+}