blob: 02b8c74feb4056eebb63d9fae3dc6cd924926506 [file] [log] [blame]
/*
*
* 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.server.protocol;
import static org.mockito.Mockito.when;
import java.nio.ByteBuffer;
import java.util.EnumSet;
import java.util.Set;
import org.apache.qpid.protocol.ServerProtocolEngine;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.transport.TestNetworkConnection;
public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
{
private VirtualHost _virtualHost;
private Broker _broker;
@Override
protected void setUp() throws Exception
{
super.setUp();
BrokerTestHelper.setUp();
_broker = BrokerTestHelper.createBrokerMock();
VirtualHostRegistry virtualHostRegistry = _broker.getVirtualHostRegistry();
when(_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)).thenReturn("default");
// AMQP 1-0 connection needs default vhost to be present
_virtualHost = BrokerTestHelper.createVirtualHost("default", virtualHostRegistry);
}
@Override
protected void tearDown() throws Exception
{
try
{
_virtualHost.close();
}
finally
{
BrokerTestHelper.tearDown();
super.tearDown();
}
}
private static final byte[] AMQP_0_8_HEADER =
new byte[] { (byte) 'A',
(byte) 'M',
(byte) 'Q',
(byte) 'P',
(byte) 1,
(byte) 1,
(byte) 8,
(byte) 0
};
private static final byte[] AMQP_0_9_HEADER =
new byte[] { (byte) 'A',
(byte) 'M',
(byte) 'Q',
(byte) 'P',
(byte) 1,
(byte) 1,
(byte) 0,
(byte) 9
};
private static final byte[] AMQP_0_9_1_HEADER =
new byte[] { (byte) 'A',
(byte) 'M',
(byte) 'Q',
(byte) 'P',
(byte) 0,
(byte) 0,
(byte) 9,
(byte) 1
};
private static final byte[] AMQP_0_10_HEADER =
new byte[] { (byte) 'A',
(byte) 'M',
(byte) 'Q',
(byte) 'P',
(byte) 1,
(byte) 1,
(byte) 0,
(byte) 10
};
private static final byte[] AMQP_1_0_0_HEADER =
new byte[] {
(byte)'A',
(byte)'M',
(byte)'Q',
(byte)'P',
(byte) 0,
(byte) 1,
(byte) 0,
(byte) 0
};
private byte[] getAmqpHeader(final AmqpProtocolVersion version)
{
switch(version)
{
case v0_8:
return AMQP_0_8_HEADER;
case v0_9:
return AMQP_0_9_HEADER;
case v0_9_1:
return AMQP_0_9_1_HEADER;
case v0_10:
return AMQP_0_10_HEADER;
case v1_0_0:
return AMQP_1_0_0_HEADER;
default:
fail("unknown AMQP version, appropriate header must be added for new protocol version");
return null;
}
}
/**
* Test to verify that connections established using a MultiVersionProtocolEngine are assigned
* IDs from a common sequence, independent of the protocol version under use.
*/
public void testDifferentProtocolVersionsShareCommonIDNumberingSequence()
{
Set<AmqpProtocolVersion> versions = EnumSet.allOf(AmqpProtocolVersion.class);
MultiVersionProtocolEngineFactory factory =
new MultiVersionProtocolEngineFactory(_broker, versions, null);
//create a dummy to retrieve the 'current' ID number
long previousId = factory.newProtocolEngine().getConnectionId();
//create a protocol engine and send the AMQP header for all supported AMQP verisons,
//ensuring the ID assigned increases as expected
for(AmqpProtocolVersion version : versions)
{
long expectedID = previousId + 1;
byte[] header = getAmqpHeader(version);
assertNotNull("protocol header should not be null", header);
ServerProtocolEngine engine = factory.newProtocolEngine();
TestNetworkConnection conn = new TestNetworkConnection();
engine.setNetworkConnection(conn, conn.getSender());
assertEquals("ID did not increment as expected", expectedID, engine.getConnectionId());
//actually feed in the AMQP header for this protocol version, and ensure the ID remains consistent
engine.received(ByteBuffer.wrap(header));
assertEquals("ID was not as expected following receipt of the AMQP version header", expectedID, engine.getConnectionId());
previousId = expectedID;
engine.closed();
}
}
/**
* Test to verify that when requesting a ProtocolEngineFactory to produce engines having a default reply to unsupported
* version initiations, there is enforcement that the default reply is itself a supported protocol version.
*/
public void testUnsupportedDefaultReplyCausesIllegalArgumentException()
{
Set<AmqpProtocolVersion> versions = EnumSet.allOf(AmqpProtocolVersion.class);
versions.remove(AmqpProtocolVersion.v0_9);
try
{
new MultiVersionProtocolEngineFactory(_broker, versions, AmqpProtocolVersion.v0_9);
fail("should not have been allowed to create the factory");
}
catch(IllegalArgumentException iae)
{
//expected
}
}
}