/* * 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.provider.amqp; 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.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.qpid.jms.meta.JmsAbstractResource; import org.apache.qpid.jms.meta.JmsAbstractResourceId; import org.apache.qpid.jms.meta.JmsConnectionId; import org.apache.qpid.jms.meta.JmsConnectionInfo; import org.apache.qpid.jms.meta.JmsResource; import org.apache.qpid.jms.meta.JmsResourceId; import org.apache.qpid.jms.meta.JmsResourceVistor; import org.apache.qpid.jms.provider.DefaultProviderListener; import org.apache.qpid.jms.provider.ProviderFuture; import org.apache.qpid.jms.test.QpidJmsTestCase; import org.apache.qpid.jms.test.testpeer.TestAmqpPeer; import org.apache.qpid.jms.util.IdGenerator; import org.apache.qpid.proton.engine.impl.TransportImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * Test some basic functionality of the AmqpProvider */ public class AmqpProviderTest extends QpidJmsTestCase { private final IdGenerator connectionIdGenerator = new IdGenerator(); private final String TEST_USERNAME = "user"; private final String TEST_PASSWORD = "password"; private AmqpProvider provider; private JmsConnectionInfo connectionInfo; @Override @Before public void setUp() throws Exception { connectionInfo = new JmsConnectionInfo(new JmsConnectionId("ID:TEST-Connection:1")); } @Override @After public void tearDown() throws Exception { if (provider != null) { provider.close(); provider = null; } } @Test(timeout=20000) public void testCreate() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); } @Test(timeout=20000, expected=RuntimeException.class) public void testGetMessageFactoryTrowsWhenNotConnected() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); provider.getMessageFactory(); } @Test(timeout=20000) public void testUnInitializedProviderReturnsDefaultConnectTimeout() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); assertEquals(JmsConnectionInfo.DEFAULT_CONNECT_TIMEOUT, provider.getConnectTimeout()); } @Test(timeout=20000) public void testUnInitializedProviderReturnsDefaultCloseTimeout() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); assertEquals(JmsConnectionInfo.DEFAULT_CLOSE_TIMEOUT, provider.getCloseTimeout()); } @Test(timeout=20000) public void testUnInitializedProviderReturnsDefaultSendTimeout() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); assertEquals(JmsConnectionInfo.DEFAULT_SEND_TIMEOUT, provider.getSendTimeout()); } @Test(timeout=20000) public void testUnInitializedProviderReturnsDefaultRequestTimeout() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); assertEquals(JmsConnectionInfo.DEFAULT_REQUEST_TIMEOUT, provider.getRequestTimeout()); } @Test(timeout=20000) public void testGetDefaultDrainTimeout() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); assertEquals(TimeUnit.MINUTES.toMillis(1), provider.getDrainTimeout()); } @Test(timeout=20000) public void testGetDefaultIdleTimeout() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); assertEquals(TimeUnit.MINUTES.toMillis(1), provider.getIdleTimeout()); } @Test(timeout=20000) public void testEnableTraceFrames() throws Exception { provider = new AmqpProviderFactory().createProvider(getDefaultURI()); TransportImpl transport = (TransportImpl) provider.getProtonTransport(); assertNotNull(transport); assertNull(transport.getProtocolTracer()); provider.setTraceFrames(true); assertNotNull(transport.getProtocolTracer()); } @Test(timeout=20000) public void testCreateFailsWithUnknownProtocol() throws Exception { try { AmqpProviderFactory factory = new AmqpProviderFactory(); factory.setTransportScheme("ftp"); factory.createProvider(new URI("ftp://localhost:5672")); fail("Should have failed to connect."); } catch (Exception ex) { } } @Test(timeout=20000) public void testConnectThrowsWhenNoPeer() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { URI peerURI = getPeerURI(testPeer); testPeer.close(); provider = new AmqpProviderFactory().createProvider(peerURI); try { provider.connect(connectionInfo); fail("Should have failed to connect."); } catch (Exception ex) { } } } @Test(timeout=20000) public void testDisableSaslLayer() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); provider.setSaslLayer(false); provider.connect(connectionInfo); testPeer.expectSaslLayerDisabledConnect(null); testPeer.expectClose(); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testSetIdleTimeout() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { testPeer.expectSaslAnonymous(); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); TransportImpl transport = (TransportImpl) provider.getProtonTransport(); final int NEW_TIMEOUT = provider.getIdleTimeout() + 500; provider.setIdleTimeout(NEW_TIMEOUT); provider.connect(connectionInfo); assertEquals(NEW_TIMEOUT, transport.getIdleTimeout()); testPeer.expectOpen(); testPeer.expectClose(); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testSetMaxFrameSize() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { testPeer.expectSaslAnonymous(); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); TransportImpl transport = (TransportImpl) provider.getProtonTransport(); final int NEW_MAX_FRAME_SIZE = provider.getMaxFrameSize() + 500; provider.setMaxFrameSize(NEW_MAX_FRAME_SIZE); provider.connect(connectionInfo); assertEquals(NEW_MAX_FRAME_SIZE, transport.getMaxFrameSize()); testPeer.expectOpen(); testPeer.expectClose(); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testSkipSetMaxFrameSize() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { testPeer.expectSaslAnonymous(); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); TransportImpl transport = (TransportImpl) provider.getProtonTransport(); final int RECORDED_MAX = transport.getMaxFrameSize(); provider.setMaxFrameSize(-1); provider.connect(connectionInfo); assertEquals(RECORDED_MAX, transport.getMaxFrameSize()); testPeer.expectOpen(); testPeer.expectClose(); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testStartThrowsIfNoListenerSet() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { testPeer.expectSaslAnonymous(); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); provider.connect(connectionInfo); assertNull(provider.getProviderListener()); try { provider.start(); fail("Should have thrown an error, no listener registered."); } catch (Exception ex) { } provider.setProviderListener(new DefaultProviderListener()); assertNotNull(provider.getProviderListener()); try { provider.start(); } catch (Exception ex) { fail("Should not have thrown an error, listener registered."); } testPeer.expectOpen(); testPeer.expectClose(); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testToString() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { testPeer.expectSaslAnonymous(); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); provider.connect(connectionInfo); assertTrue(provider.toString().contains("localhost")); assertTrue(provider.toString().contains(String.valueOf(testPeer.getServerPort()))); testPeer.expectOpen(); testPeer.expectClose(); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testClosedProviderThrowsIOException() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { testPeer.expectSaslAnonymous(); testPeer.expectOpen(); testPeer.expectClose(); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); provider.connect(connectionInfo); provider.close(); try { provider.start(); fail("Should have thrown an IOException when closed."); } catch (IOException ex) {} try { provider.connect(connectionInfo); fail("Should have thrown an IOException when closed."); } catch (IOException ex) {} ProviderFuture request = new ProviderFuture(); try { provider.unsubscribe("subscription-name", request); fail("Should have thrown an IOException when closed."); } catch (IOException ex) {} provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout=20000) public void testTimeoutsSetFromConnectionInfo() throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { final long CONNECT_TIMEOUT = TimeUnit.SECONDS.toMillis(4); final long CLOSE_TIMEOUT = TimeUnit.SECONDS.toMillis(5); final long SEND_TIMEOUT = TimeUnit.SECONDS.toMillis(6); final long REQUEST_TIMEOUT = TimeUnit.SECONDS.toMillis(7); connectionInfo.setUsername(TEST_USERNAME); connectionInfo.setPassword(TEST_PASSWORD); provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); testPeer.expectSaslPlain(TEST_USERNAME, TEST_PASSWORD); testPeer.expectOpen(); testPeer.expectBegin(); provider.connect(connectionInfo); testPeer.expectClose(); JmsConnectionInfo connectionInfo = createConnectionInfo(); connectionInfo.setConnectTimeout(CONNECT_TIMEOUT); connectionInfo.setCloseTimeout(CLOSE_TIMEOUT); connectionInfo.setSendTimeout(SEND_TIMEOUT); connectionInfo.setRequestTimeout(REQUEST_TIMEOUT); ProviderFuture request = new ProviderFuture(); provider.create(connectionInfo, request); request.sync(); assertEquals(CONNECT_TIMEOUT, provider.getConnectTimeout()); assertEquals(CLOSE_TIMEOUT, provider.getCloseTimeout()); assertEquals(SEND_TIMEOUT, provider.getSendTimeout()); assertEquals(REQUEST_TIMEOUT, provider.getRequestTimeout()); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } @Test(timeout = 20000) public void testErrorDuringCreateResourceFailsRequest() throws Exception { doErrorDuringOperationFailsRequesTTestImpl(Op.CREATE); } @Test(timeout = 20000) public void testErrorDuringStartResourceFailsRequest() throws Exception { doErrorDuringOperationFailsRequesTTestImpl(Op.START); } @Test(timeout = 20000) public void testErrorDuringStopResourceFailsRequest() throws Exception { doErrorDuringOperationFailsRequesTTestImpl(Op.STOP); } @Test(timeout = 20000) public void testErrorDuringDestroyResourceFailsRequest() throws Exception { doErrorDuringOperationFailsRequesTTestImpl(Op.DESTROY); } private void doErrorDuringOperationFailsRequesTTestImpl(Op operation) throws Exception { try (TestAmqpPeer testPeer = new TestAmqpPeer()) { provider = new AmqpProviderFactory().createProvider(getPeerURI(testPeer)); final AtomicBoolean errorThrown = new AtomicBoolean(); JmsResource resourceInfo = new JmsAbstractResource() { @Override public void visit(JmsResourceVistor visitor) { errorThrown.set(true); throw new Error("Deliberate error for testing"); } @Override public JmsResourceId getId() { return new JmsAbstractResourceId() { }; } }; assertFalse("Error should not yet be thrown", errorThrown.get()); ProviderFuture request = new ProviderFuture(); switch(operation) { case CREATE: provider.create(resourceInfo, request); break; case START: provider.start(resourceInfo, request); break; case STOP: provider.stop(resourceInfo, request); break; case DESTROY: provider.destroy(resourceInfo, request); break; default: throw new IllegalArgumentException("Unexpected operation given"); } try { request.sync(); fail("Request should have failed"); } catch (IOException e) { // Expected } assertTrue("Error should have been thrown", errorThrown.get()); provider.close(); testPeer.waitForAllHandlersToComplete(1000); } } private JmsConnectionInfo createConnectionInfo() { JmsConnectionId connectionId = new JmsConnectionId(connectionIdGenerator.generateId()); JmsConnectionInfo connectionInfo = new JmsConnectionInfo(connectionId); connectionInfo.setUsername(TEST_USERNAME); connectionInfo.setPassword(TEST_PASSWORD); return connectionInfo; } private enum Op { CREATE, START, STOP, DESTROY } private URI getDefaultURI() throws URISyntaxException { return new URI("amqp://localhost:5672"); } private URI getPeerURI(TestAmqpPeer peer) throws URISyntaxException { return new URI("amqp://localhost:" + peer.getServerPort()); } }