diff options
author | Martin Ritchie <ritchiem@apache.org> | 2006-12-04 16:38:10 +0000 |
---|---|---|
committer | Martin Ritchie <ritchiem@apache.org> | 2006-12-04 16:38:10 +0000 |
commit | ab09bbfdd27265f67d1f5e83c3f8953f2cacdf0d (patch) | |
tree | 1a66aa379c6bba7bf3d1c1a632c8c518b7cc89e3 | |
parent | 9bbc2fb73926209434894bdb6b8f74a02e1d5fd7 (diff) | |
download | qpid-python-ab09bbfdd27265f67d1f5e83c3f8953f2cacdf0d.tar.gz |
QPID-148
AMQMinaProtocolSession.java - updated comment
AbstractJMSMessage.java - removed a lot of getHeaders() == null checks. Updated logic accordingly.. Now a request for a property that doesn't exist will be consistent with calls on an empty table rather than just creating a default value.
BasicContentHeaderProperties.java - the culprit for QPID-148 changed new FieldTable() to setHeaders(new FieldTable()) to ensure propertyFlag is set to write headers to the wire.
Added PropertyValueTest.java - that tests all the valid values on the Message.
*NOTE*: A number of the tests are commented out as AMQP and therefore the FieldTable do not support these values. QPID-9
Added SVN ignores for the target directories.
Updated AbstractJMSMessage.java _readableProperties to be set correctly in the constructor.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@482238 13f79535-47bb-0310-9956-ffa450edef68
4 files changed, 354 insertions, 184 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index be8d2c4c82..1aa62dbfa4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -367,6 +367,11 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, int i = pv.length - 1; _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); // TODO: Close connection (but how to wait until message is sent?) + // ritchiem 2006-12-04 will this not do? +// WriteFuture future = _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); +// future.join(); +// close connection + } } else diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java index a5b135da2d..30031326d5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java @@ -73,7 +73,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms { _data.acquire(); } - _readableProperties = (_contentHeaderProperties != null); + _readableProperties = false; _readableMessage = (data != null); } @@ -86,13 +86,13 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms _data.acquire(); } - _readableProperties = (_contentHeaderProperties != null); _readableMessage = data != null; } protected AbstractJMSMessage(BasicContentHeaderProperties contentHeader, long deliveryTag) { super(contentHeader, deliveryTag); + _readableProperties = (_contentHeaderProperties != null); } public String getJMSMessageID() throws JMSException @@ -221,11 +221,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public String getJMSType() throws JMSException { + //fixme wrong QPID-152 return getMimeType(); } public void setJMSType(String string) throws JMSException - { + { //throw new JMSException("Cannot set JMS Type - it is implicitly defined based on message type"); // this is not spec comliant, should not throw the message } @@ -252,10 +253,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public void clearProperties() throws JMSException { - if (getJmsContentHeaderProperties().getHeaders() != null) - { - getJmsContentHeaderProperties().getHeaders().clear(); - } + getJmsContentHeaderProperties().getHeaders().clear(); _readableProperties = false; } @@ -270,190 +268,130 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public boolean propertyExists(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return false; - } - else + + Iterator keys = getJmsContentHeaderProperties().getHeaders().keySet().iterator(); + + while (keys.hasNext()) { - Iterator keys = getJmsContentHeaderProperties().getHeaders().keySet().iterator(); + String key = (String) keys.next(); - while (keys.hasNext()) + if (key.endsWith(propertyName)) { - String key = (String) keys.next(); - - if (key.endsWith(propertyName)) - { - return true; - } + return true; } - return false; } + return false; + } public boolean getBooleanProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + // store as integer as temporary workaround + //Boolean b = (Boolean) getJmsContentHeaderProperties().headers.get(BOOLEAN_PROPERTY_PREFIX + propertyName); + Long b = (Long) getJmsContentHeaderProperties().getHeaders().get(BOOLEAN_PROPERTY_PREFIX + propertyName); + + if (b == null) { return Boolean.valueOf(null).booleanValue(); } else { - // store as integer as temporary workaround - //Boolean b = (Boolean) getJmsContentHeaderProperties().headers.get(BOOLEAN_PROPERTY_PREFIX + propertyName); - Long b = (Long) getJmsContentHeaderProperties().getHeaders().get(BOOLEAN_PROPERTY_PREFIX + propertyName); - - if (b == null) - { - return Boolean.valueOf(null).booleanValue(); - } - else - { - return b.longValue() != 0; - } + return b.longValue() != 0; } + } public byte getByteProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Byte b = (Byte) getJmsContentHeaderProperties().getHeaders().get(BYTE_PROPERTY_PREFIX + propertyName); + if (b == null) { return Byte.valueOf(null).byteValue(); } else { - Byte b = (Byte) getJmsContentHeaderProperties().getHeaders().get(BYTE_PROPERTY_PREFIX + propertyName); - if (b == null) - { - return Byte.valueOf(null).byteValue(); - } - else - { - return b.byteValue(); - } + return b.byteValue(); } } public short getShortProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Short s = (Short) getJmsContentHeaderProperties().getHeaders().get(SHORT_PROPERTY_PREFIX + propertyName); + if (s == null) { return Short.valueOf(null).shortValue(); } else { - Short s = (Short) getJmsContentHeaderProperties().getHeaders().get(SHORT_PROPERTY_PREFIX + propertyName); - if (s == null) - { - return Short.valueOf(null).shortValue(); - } - else - { - return s.shortValue(); - } + return s.shortValue(); } } public int getIntProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Integer i = (Integer) getJmsContentHeaderProperties().getHeaders().get(INT_PROPERTY_PREFIX + propertyName); + if (i == null) { return Integer.valueOf(null).intValue(); } else { - Integer i = (Integer) getJmsContentHeaderProperties().getHeaders().get(INT_PROPERTY_PREFIX + propertyName); - if (i == null) - { - return Integer.valueOf(null).intValue(); - } - else - { - return i.intValue(); - } + return i.intValue(); } } public long getLongProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + Long l = (Long) getJmsContentHeaderProperties().getHeaders().get(LONG_PROPERTY_PREFIX + propertyName); + if (l == null) { - return Long.valueOf(null).longValue(); + // temp - the spec says do this but this throws a NumberFormatException + //return Long.valueOf(null).longValue(); + return 0; } else { - Long l = (Long) getJmsContentHeaderProperties().getHeaders().get(LONG_PROPERTY_PREFIX + propertyName); - if (l == null) - { - // temp - the spec says do this but this throws a NumberFormatException - //return Long.valueOf(null).longValue(); - return 0; - } - else - { - return l.longValue(); - } + return l.longValue(); } } public float getFloatProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + final Float f = (Float) getJmsContentHeaderProperties().getHeaders().get(FLOAT_PROPERTY_PREFIX + propertyName); + if (f == null) { return Float.valueOf(null).floatValue(); } else { - final Float f = (Float) getJmsContentHeaderProperties().getHeaders().get(FLOAT_PROPERTY_PREFIX + propertyName); - if (f == null) - { - return Float.valueOf(null).floatValue(); - } - else - { - return f.floatValue(); - } + return f.floatValue(); } } public double getDoubleProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) + final Double d = (Double) getJmsContentHeaderProperties().getHeaders().get(DOUBLE_PROPERTY_PREFIX + propertyName); + if (d == null) { return Double.valueOf(null).doubleValue(); } else { - final Double d = (Double) getJmsContentHeaderProperties().getHeaders().get(DOUBLE_PROPERTY_PREFIX + propertyName); - if (d == null) - { - return Double.valueOf(null).doubleValue(); - } - else - { - return d.shortValue(); - } + return d.shortValue(); } } public String getStringProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return null; - } - else - { - return (String) getJmsContentHeaderProperties().getHeaders().get(STRING_PROPERTY_PREFIX + propertyName); - } + return (String) getJmsContentHeaderProperties().getHeaders().get(STRING_PROPERTY_PREFIX + propertyName); } public Object getObjectProperty(String propertyName) throws JMSException @@ -533,14 +471,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms getJmsContentHeaderProperties().getHeaders().put(STRING_PROPERTY_PREFIX + propertyName, value); } - private void createPropertyMapIfRequired() - { - if (getJmsContentHeaderProperties().getHeaders() == null) - { - getJmsContentHeaderProperties().setHeaders(new FieldTable()); - } - } - public void setObjectProperty(String string, Object object) throws JMSException { //todo this should be changed to something else.. the Header doesn't support objects. @@ -588,58 +518,55 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo())); buf.append("\nAMQ message number: ").append(_deliveryTag); buf.append("\nProperties:"); - if (getJmsContentHeaderProperties().getHeaders() == null) + final Iterator it = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); + if (!it.hasNext()) { buf.append("<NONE>"); } - else + while (it.hasNext()) { - final Iterator it = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); - while (it.hasNext()) + final Map.Entry entry = (Map.Entry) it.next(); + final String propertyName = (String) entry.getKey(); + if (propertyName == null) { - final Map.Entry entry = (Map.Entry) it.next(); - final String propertyName = (String) entry.getKey(); - if (propertyName == null) - { - buf.append("\nInternal error: Property with NULL key defined"); - } - else + buf.append("\nInternal error: Property with NULL key defined"); + } + else + { + buf.append('\n').append(propertyName.substring(1)); + + char typeIdentifier = propertyName.charAt(0); + switch (typeIdentifier) { - buf.append('\n').append(propertyName.substring(1)); - - char typeIdentifier = propertyName.charAt(0); - switch (typeIdentifier) - { - case org.apache.qpid.client.message.AbstractJMSMessage.BOOLEAN_PROPERTY_PREFIX: - buf.append("<boolean> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.BYTE_PROPERTY_PREFIX: - buf.append("<byte> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.SHORT_PROPERTY_PREFIX: - buf.append("<short> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.INT_PROPERTY_PREFIX: - buf.append("<int> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.LONG_PROPERTY_PREFIX: - buf.append("<long> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.FLOAT_PROPERTY_PREFIX: - buf.append("<float> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.DOUBLE_PROPERTY_PREFIX: - buf.append("<double> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.STRING_PROPERTY_PREFIX: - buf.append("<string> "); - break; - default: - buf.append("<unknown type (identifier " + - typeIdentifier + ") "); - } - buf.append(String.valueOf(entry.getValue())); + case org.apache.qpid.client.message.AbstractJMSMessage.BOOLEAN_PROPERTY_PREFIX: + buf.append("<boolean> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.BYTE_PROPERTY_PREFIX: + buf.append("<byte> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.SHORT_PROPERTY_PREFIX: + buf.append("<short> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.INT_PROPERTY_PREFIX: + buf.append("<int> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.LONG_PROPERTY_PREFIX: + buf.append("<long> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.FLOAT_PROPERTY_PREFIX: + buf.append("<float> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.DOUBLE_PROPERTY_PREFIX: + buf.append("<double> "); + break; + case org.apache.qpid.client.message.AbstractJMSMessage.STRING_PROPERTY_PREFIX: + buf.append("<string> "); + break; + default: + buf.append("<unknown type (identifier " + + typeIdentifier + ") "); } + buf.append(String.valueOf(entry.getValue())); } } return buf.toString(); @@ -672,38 +599,33 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms throw new IllegalArgumentException("Property name must not be the empty string"); } - createPropertyMapIfRequired(); + // Call to ensure that the it has been set. + getJmsContentHeaderProperties().getHeaders(); } public FieldTable populateHeadersFromMessageProperties() { - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return null; - } - else - { - // - // We need to convert every property into a String representation - // Note that type information is preserved in the property name - // - final FieldTable table = new FieldTable(); - final Iterator entries = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); - while (entries.hasNext()) + // + // We need to convert every property into a String representation + // Note that type information is preserved in the property name + // + final FieldTable table = new FieldTable(); + final Iterator entries = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); + while (entries.hasNext()) + { + final Map.Entry entry = (Map.Entry) entries.next(); + final String propertyName = (String) entry.getKey(); + if (propertyName == null) { - final Map.Entry entry = (Map.Entry) entries.next(); - final String propertyName = (String) entry.getKey(); - if (propertyName == null) - { - continue; - } - else - { - table.put(propertyName, entry.getValue().toString()); - } + continue; + } + else + { + table.put(propertyName, entry.getValue().toString()); } - return table; } + return table; + } public BasicContentHeaderProperties getJmsContentHeaderProperties() diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java new file mode 100644 index 0000000000..71b4fb3784 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PropertyValueTest.java @@ -0,0 +1,243 @@ +/* + * + * 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.test.unit.basic; + +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.message.JMSTextMessage; +import org.apache.qpid.test.VMBrokerSetup; +import org.apache.log4j.Logger; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import javax.jms.*; + +import junit.framework.TestCase; +import junit.framework.Assert; + +public class PropertyValueTest extends TestCase implements MessageListener +{ + + private static final Logger _logger = Logger.getLogger(PropertyValueTest.class); + + private AMQConnection _connection; + private Destination _destination; + private AMQSession _session; + private final List<JMSTextMessage> received = new ArrayList<JMSTextMessage>(); + private final List<String> messages = new ArrayList<String>(); + private int _count = 1;//100; + public String _connectionString = "vm://:1"; + + protected void setUp() throws Exception + { + super.setUp(); + try + { + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + } + catch (Exception e) + { + fail("Unable to initialilse connection: " + e); + } + } + + protected void tearDown() throws Exception + { + super.tearDown(); + } + + private void init(AMQConnection connection) throws Exception + { + Destination destination = new AMQQueue(randomize("PropertyValueTest"), true); + init(connection, destination); + } + + private void init(AMQConnection connection, Destination destination) throws Exception + { + _connection = connection; + _destination = destination; + _session = (AMQSession) connection.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); + + //set up a slow consumer + _session.createConsumer(destination).setMessageListener(this); + connection.start(); + } + + public void test() throws Exception + { + int count = _count; + send(count); + waitFor(count); + check(); + System.out.println("Completed without failure"); + _connection.close(); + } + + void send(int count) throws JMSException + { + //create a publisher + MessageProducer producer = _session.createProducer(_destination); + for (int i = 0; i < count; i++) + { + String text = "Message " + i; + messages.add(text); + Message m = _session.createTextMessage(text); + + m.setBooleanProperty("Bool", true); +// m.setByteProperty("Byte", (byte) Byte.MAX_VALUE); +// m.setDoubleProperty("Double", (double) Double.MAX_VALUE); +// m.setFloatProperty("Float", (float) Float.MAX_VALUE); +// m.setIntProperty("Int", (int) Integer.MAX_VALUE); + m.setJMSCorrelationID("Correlation"); + m.setJMSPriority(100); + m.setJMSReplyTo(_session.createQueue("TestReply")); +// m.setJMSType("Test"); + m.setLongProperty("UnsignedInt", (long) 4294967295L); +// m.setLongProperty("Long", (long) Long.MAX_VALUE); + +// m.setShortProperty("Short", (short) Short.MAX_VALUE); + m.setStringProperty("String", "Test"); + + _logger.info("Sending Msg:" + m); + producer.send(m); + } + } + + void waitFor(int count) throws InterruptedException + { + synchronized(received) + { + while (received.size() < count) + { + received.wait(); + } + } + } + + void check() throws JMSException + { + List<String> actual = new ArrayList<String>(); + for (JMSTextMessage m : received) + { + actual.add(m.getText()); + + //Check Properties + + Assert.assertEquals("Check Boolean properties are correctly transported", + true, m.getBooleanProperty("Bool")); +// Assert.assertEquals("Check Byte properties are correctly transported", +// (byte) Byte.MAX_VALUE, m.getByteProperty("Byte")); +// Assert.assertEquals("Check Double properties are correctly transported", +// (double) Double.MAX_VALUE, m.getDoubleProperty("Double")); +// Assert.assertEquals("Check Float properties are correctly transported", +// (float) Float.MAX_VALUE, m.getFloatProperty("Float")); +// Assert.assertEquals("Check Int properties are correctly transported", +// (int) Integer.MAX_VALUE, m.getIntProperty("Int")); + Assert.assertEquals("Check CorrelationID properties are correctly transported", + "Correlation", m.getJMSCorrelationID()); +// Assert.assertEquals("Check Priority properties are correctly transported", +// 100, m.getJMSPriority()); + Assert.assertEquals("Check ReplyTo properties are correctly transported", + _session.createQueue("TestReply"), m.getJMSReplyTo()); +// Assert.assertEquals("Check Type properties are correctly transported", +// "Test", m.getJMSType()); +// Assert.assertEquals("Check Short properties are correctly transported", +// (short) Short.MAX_VALUE, m.getShortProperty("Short")); + Assert.assertEquals("Check UnsignedInt properties are correctly transported", + (long) 4294967295L, m.getLongProperty("UnsignedInt")); +// Assert.assertEquals("Check Long properties are correctly transported", +// (long)Long.MAX_VALUE, m.getLongProperty("Long")); + Assert.assertEquals("Check String properties are correctly transported", + "Test", m.getStringProperty("String")); + } + + assertEqual(messages.iterator(), actual.iterator()); + } + + private static void assertEqual(Iterator expected, Iterator actual) + { + List<String> errors = new ArrayList<String>(); + while (expected.hasNext() && actual.hasNext()) + { + try + { + assertEqual(expected.next(), actual.next()); + } + catch (Exception e) + { + errors.add(e.getMessage()); + } + } + while (expected.hasNext()) + { + errors.add("Expected " + expected.next() + " but no more actual values."); + } + while (actual.hasNext()) + { + errors.add("Found " + actual.next() + " but no more expected values."); + } + if (!errors.isEmpty()) + { + throw new RuntimeException(errors.toString()); + } + } + + private static void assertEqual(Object expected, Object actual) + { + if (!expected.equals(actual)) + { + throw new RuntimeException("Expected '" + expected + "' found '" + actual + "'"); + } + } + + public void onMessage(Message message) + { + synchronized(received) + { + received.add((JMSTextMessage) message); + received.notify(); + } + } + + private static String randomize(String in) + { + return in + System.currentTimeMillis(); + } + + public static void main(String[] argv) throws Exception + { + PropertyValueTest test = new PropertyValueTest(); + test._connectionString = argv.length == 0 ? "vm://:1" : argv[0]; + test.setUp(); + if (argv.length > 1) + { + test._count = Integer.parseInt(argv[1]); + } + test.test(); + } + + public static junit.framework.Test suite() + { + return new VMBrokerSetup(new junit.framework.TestSuite(PropertyValueTest.class)); + } +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java index e337e9fd05..6a4c385033 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java +++ b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java @@ -435,7 +435,7 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties if (_headers == null) { - _headers = new FieldTable(); + setHeaders(new FieldTable()); } return _headers; |