diff options
author | Martin Ritchie <ritchiem@apache.org> | 2006-12-18 13:02:27 +0000 |
---|---|---|
committer | Martin Ritchie <ritchiem@apache.org> | 2006-12-18 13:02:27 +0000 |
commit | 67175fa993f364f8debf0fd8cc3b15633a022bcf (patch) | |
tree | b192a3c735e4840e2c3f0faed959270c3b6c85af | |
parent | 3df6475c3538b5fe8c31178529c268c3c82467c0 (diff) | |
download | qpid-python-67175fa993f364f8debf0fd8cc3b15633a022bcf.tar.gz |
AMQSession - Modified to correctly throw : InvalidSelector
PropertiesFileInitialContextFactory.java - augmented to load properties file from PROVIDER_URL if it is specified.
Trunk Merges
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/jmsselectors@488262 13f79535-47bb-0310-9956-ffa450edef68
158 files changed, 5943 insertions, 1872 deletions
diff --git a/java/client/example/pom.xml b/java/client/example/pom.xml new file mode 100644 index 0000000000..ac0081c00b --- /dev/null +++ b/java/client/example/pom.xml @@ -0,0 +1,94 @@ +<!-- + 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-example</artifactId> + <packaging>jar</packaging> + <version>1.0-incubating-M2-SNAPSHOT</version> + <name>Qpid Example</name> + <url>http://cwiki.apache.org/confluence/display/qpid</url> + + <parent> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid</artifactId> + <version>1.0-incubating-M2-SNAPSHOT</version> + </parent> + + <properties> + <topDirectoryLocation>..</topDirectoryLocation> + <amqj.logging.level>warn</amqj.logging.level> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-common</artifactId> + </dependency> + <dependency> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-client</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-jms_1.1_spec</artifactId> + </dependency> + + <dependency> + <groupId>jmscts</groupId> + <artifactId>jmscts</artifactId> + <version>0.5-b2</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>jms</groupId> + <artifactId>jms</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemProperties> + <property> + <name>amqj.noAutoCreateVMBroker</name> + <value>true</value> + </property> + <property> + <name>amqj.logging.level</name> + <value>${amqj.logging.level}</value> + </property> + <property> + <name>log4j.configuration</name> + <value>file:///${basedir}/src/main/java/log4j.properties</value> + </property> + </systemProperties> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/java/client/src/test/java/org/apache/qpid/example/log4j.xml b/java/client/example/src/main/java/org/apache/qpid/example/log4j.xml index de64423a51..de64423a51 100644 --- a/java/client/src/test/java/org/apache/qpid/example/log4j.xml +++ b/java/client/example/src/main/java/org/apache/qpid/example/log4j.xml diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java index b199d41432..b199d41432 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageFactory.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java index 88bcbbbccb..88bcbbbccb 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/FileMessageFactory.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/MessageFactoryException.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MessageFactoryException.java index 34360d6708..34360d6708 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/MessageFactoryException.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MessageFactoryException.java diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java index 8784d340da..8784d340da 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorPublisher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java index 233c3fea0a..233c3fea0a 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/MonitorPublisher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/Publisher.java index be42e0e413..2bde4ec35c 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/Publisher.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/Publisher.java @@ -75,7 +75,7 @@ public class Publisher //lookup the example queue and use it //Queue is non-exclusive and not deleted when last consumer detaches - _destination = _session.createQueue((String)ctx.lookup("MyQueue")); + _destination = (Queue) ctx.lookup("MyQueue"); //create a message producer _producer = _session.createProducer(_destination); diff --git a/java/client/src/test/java/org/apache/qpid/example/publisher/UndeliveredMessageException.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/UndeliveredMessageException.java index 3335833c2d..3335833c2d 100644 --- a/java/client/src/test/java/org/apache/qpid/example/publisher/UndeliveredMessageException.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/UndeliveredMessageException.java diff --git a/java/client/src/test/java/org/apache/qpid/example/shared/ConnectionException.java b/java/client/example/src/main/java/org/apache/qpid/example/shared/ConnectionException.java index 8723983862..8723983862 100644 --- a/java/client/src/test/java/org/apache/qpid/example/shared/ConnectionException.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/shared/ConnectionException.java diff --git a/java/client/src/test/java/org/apache/qpid/example/shared/ContextException.java b/java/client/example/src/main/java/org/apache/qpid/example/shared/ContextException.java index 787cecd541..787cecd541 100644 --- a/java/client/src/test/java/org/apache/qpid/example/shared/ContextException.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/shared/ContextException.java diff --git a/java/client/src/test/java/org/apache/qpid/example/shared/FileUtils.java b/java/client/example/src/main/java/org/apache/qpid/example/shared/FileUtils.java index 54446cb6a7..54446cb6a7 100644 --- a/java/client/src/test/java/org/apache/qpid/example/shared/FileUtils.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/shared/FileUtils.java diff --git a/java/client/src/test/java/org/apache/qpid/example/shared/InitialContextHelper.java b/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java index b39892b688..b39892b688 100644 --- a/java/client/src/test/java/org/apache/qpid/example/shared/InitialContextHelper.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java diff --git a/java/client/src/test/java/org/apache/qpid/example/shared/Statics.java b/java/client/example/src/main/java/org/apache/qpid/example/shared/Statics.java index c056f8a7da..c056f8a7da 100644 --- a/java/client/src/test/java/org/apache/qpid/example/shared/Statics.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/shared/Statics.java diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/example.properties b/java/client/example/src/main/java/org/apache/qpid/example/shared/example.properties index 82de41908f..7f513341a2 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/example.properties +++ b/java/client/example/src/main/java/org/apache/qpid/example/shared/example.properties @@ -5,7 +5,7 @@ java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextF # register some connection factories # connectionfactory.[jndiname] = [ConnectionURL] -connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='vm://:1' +connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' # register some queues in JNDI using the form # queue.[jndiName] = [physicalName] diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java index 9c195aef40..1d2e5e0e66 100644 --- a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/MonitoredSubscriber.java @@ -39,7 +39,7 @@ public class MonitoredSubscriber extends Subscriber { super(); //lookup queue name and append suffix - _monitorDestinationName = _destinationName + Statics.MONITOR_QUEUE_SUFFIX; + _monitorDestinationName = _destination.toString() + Statics.MONITOR_QUEUE_SUFFIX; } /** diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java index d2f27da052..d2f27da052 100644 --- a/java/client/src/test/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/MonitoredSubscriptionWrapper.java diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/Subscriber.java index 34c7d6c7bb..4e92a6c678 100644 --- a/java/client/src/test/java/org/apache/qpid/example/subscriber/Subscriber.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/Subscriber.java @@ -45,7 +45,7 @@ public class Subscriber protected static AMQConnectionFactory _connectionFactory; - protected String _destinationName; + protected Destination _destination; public Subscriber() { @@ -58,8 +58,8 @@ public class Subscriber //then create a connection using the AMQConnectionFactory _connectionFactory = (AMQConnectionFactory) ctx.lookup("local"); - //lookup queue name - _destinationName = (String) ctx.lookup("MyQueue"); + //lookup queue from context + _destination = (Destination) ctx.lookup("MyQueue"); } catch (Exception e) @@ -79,7 +79,6 @@ public class Subscriber public ExampleMessageListener(String name) { _name = name; - } /** @@ -127,11 +126,8 @@ public class Subscriber //create a transactional session Session session = _connection.createSession(true, Session.AUTO_ACKNOWLEDGE); - //Queue is non-exclusive and not deleted when last consumer detaches - Destination destination = session.createQueue(_destinationName); - //Create a consumer with a destination of our queue which will use defaults for prefetch etc - _consumer = session.createConsumer(destination); + _consumer = session.createConsumer(_destination); //give the message listener a name of it's own _consumer.setMessageListener(new ExampleMessageListener("MessageListener " + System.currentTimeMillis())); @@ -161,15 +157,6 @@ public class Subscriber } /** - * Set destination (queue or topic) name - * @param name - */ - public void setDestinationName(String name) - { - _destinationName = name; - } - - /** * Stop consuming and close connection */ public void stop() diff --git a/java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java index 32a0ef685c..32a0ef685c 100644 --- a/java/client/src/test/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java +++ b/java/client/example/src/main/java/org/apache/qpid/example/subscriber/SubscriptionWrapper.java diff --git a/java/client/pom.xml b/java/client/pom.xml index 25372772af..a280430ece 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -38,7 +38,6 @@ <amqj.logging.level>warn</amqj.logging.level> </properties> - <dependencies> <dependency> <groupId>org.apache.qpid</groupId> @@ -49,7 +48,6 @@ <artifactId>qpid-broker</artifactId> </dependency> - <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> @@ -72,7 +70,6 @@ <artifactId>mina-filter-ssl</artifactId> </dependency> - <dependency> <groupId>jmscts</groupId> <artifactId>jmscts</artifactId> @@ -110,19 +107,13 @@ </property> <property> <name>amqj.logging.level</name> - <value>WARN</value> + <value>${amqj.logging.level}</value> </property> <property> <name>log4j.configuration</name> <value>file:///${basedir}/src/main/java/log4j.properties</value> </property> </systemProperties> - <includes> - <include>**/test/unit/**/*Test.java</include> - </includes> - <excludes> - <exclude>**/JNDIReferenceableTest.java</exclude> - </excludes> </configuration> </plugin> </plugins> diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index 98db26d0c4..8b2387b9a0 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -44,6 +44,7 @@ import org.apache.qpid.jms.FailoverPolicy; import org.apache.qpid.url.URLSyntaxException; import javax.jms.*; +import javax.jms.IllegalStateException; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; @@ -53,6 +54,7 @@ import java.net.ConnectException; import java.nio.channels.UnresolvedAddressException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; @@ -92,7 +94,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect /** * Maps from session id (Integer) to AMQSession instance */ - private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap + private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap private String _clientName; @@ -142,7 +144,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect String clientName, String virtualHost) throws AMQException, URLSyntaxException { this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + + username + ":" + password + "@" + + (clientName==null?"":clientName) + virtualHost + "?brokerlist='" + broker + "'")); } @@ -157,11 +160,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { this(new AMQConnectionURL(useSSL ? ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + + username + ":" + password + "@" + + (clientName==null?"":clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'" + "," + ConnectionURL.OPTIONS_SSL + "='true'" : ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + + username + ":" + password + "@" + + (clientName==null?"":clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'" + "," + ConnectionURL.OPTIONS_SSL + "='false'" )); @@ -537,14 +542,17 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public void setClientID(String clientID) throws JMSException { checkNotClosed(); - _clientName = clientID; + // in AMQP it is not possible to change the client ID. If one is not specified + // upon connection construction, an id is generated automatically. Therefore + // we can always throw an exception. + throw new IllegalStateException("Client name cannot be changed after being set"); } public ConnectionMetaData getMetaData() throws JMSException { checkNotClosed(); - // TODO Auto-generated method stub - return null; + return QpidConnectionMetaData.instance(); + } public ExceptionListener getExceptionListener() throws JMSException @@ -583,7 +591,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public void stop() throws JMSException { checkNotClosed(); - if (_started) { for (Iterator i = _sessions.values().iterator(); i.hasNext();) @@ -872,7 +879,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect } else { - je = new JMSException("Exception thrown against " + toString() + ": " + cause); + if (cause instanceof AMQException) + { + je = new JMSException(Integer.toString(((AMQException)cause).getErrorCode()) ,"Exception thrown against " + toString() + ": " + cause); + } + else + { + je = new JMSException("Exception thrown against " + toString() + ": " + cause); + } if (cause instanceof Exception) { je.setLinkedException((Exception) cause); @@ -920,8 +934,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect void deregisterSession(int channelId) { _sessions.remove(channelId); - } - + } + /** * For all sessions, and for all consumers in those sessions, resubscribe. This is called during failover handling. * The caller must hold the failover mutex before calling this method. diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java index 6401e3b23f..c6f3f9c492 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java @@ -7,9 +7,9 @@ * 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 @@ -79,13 +79,19 @@ public abstract class AMQDestination implements Destination, Referenceable protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, boolean isExclusive, boolean isAutoDelete, String queueName) { + this(exchangeName, exchangeClass, destinationName, isExclusive, isAutoDelete, queueName, false); + } + + protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, boolean isExclusive, + boolean isAutoDelete, String queueName, boolean isDurable) + { if (destinationName == null) { - throw new IllegalArgumentException("Destination name must not be null"); + throw new IllegalArgumentException("Destination exchange must not be null"); } if (exchangeName == null) { - throw new IllegalArgumentException("Exchange name must not be null"); + throw new IllegalArgumentException("Exchange exchange must not be null"); } if (exchangeClass == null) { @@ -97,9 +103,13 @@ public abstract class AMQDestination implements Destination, Referenceable _isExclusive = isExclusive; _isAutoDelete = isAutoDelete; _queueName = queueName; + _isDurable = isDurable; } - public abstract String getEncodedName(); + public String getEncodedName() + { + return toURL(); + } public boolean isDurable() { @@ -244,7 +254,7 @@ public abstract class AMQDestination implements Destination, Referenceable return false; } if ((_queueName == null && that._queueName != null) || - (_queueName != null && !_queueName.equals(that._queueName))) + (_queueName != null && !_queueName.equals(that._queueName))) { return false; } @@ -282,4 +292,26 @@ public abstract class AMQDestination implements Destination, Referenceable AMQConnectionFactory.class.getName(), null); // factory location } + + public static Destination createDestination(BindingURL binding) + { + String type = binding.getExchangeClass(); + + if (type.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS)) + { + return new AMQQueue(binding); + } + else if (type.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS)) + { + return new AMQTopic(binding); + } + else if (type.equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS)) + { + return new AMQHeadersExchange(binding); + } + else + { + throw new IllegalArgumentException("Unknown Exchange Class:" + type + " in binding:" + binding); + } + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java b/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java index c5bae6e1fa..c6d21c0ea7 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java @@ -38,11 +38,6 @@ public class AMQHeadersExchange extends AMQDestination super(queueName, ExchangeDefaults.HEADERS_EXCHANGE_CLASS, queueName, true, true, null); } - public String getEncodedName() - { - return getDestinationName(); - } - public String getRoutingKey() { return getDestinationName(); diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQQueue.java b/java/client/src/main/java/org/apache/qpid/client/AMQQueue.java index 8304a29e4d..6c0da6112a 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQQueue.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQQueue.java @@ -75,11 +75,7 @@ public class AMQQueue extends AMQDestination implements Queue autoDelete, queueName); } - public String getEncodedName() - { - return 'Q' + getQueueName(); - } - + public String getRoutingKey() { return getQueueName(); diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index edaf793bd6..978aefd477 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -7,9 +7,9 @@ * 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 @@ -23,11 +23,16 @@ package org.apache.qpid.client; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.AMQUndeliveredException; +import org.apache.qpid.AMQInvalidSelectorException; +import org.apache.qpid.server.handler.ExchangeBoundHandler; +import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.client.failover.FailoverSupport; import org.apache.qpid.client.message.AbstractJMSMessage; +import org.apache.qpid.client.message.JMSStreamMessage; import org.apache.qpid.client.message.MessageFactoryRegistry; import org.apache.qpid.client.message.UnprocessedMessage; import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQMethodEvent; import org.apache.qpid.client.util.FlowControllingBlockingQueue; import org.apache.qpid.framing.*; import org.apache.qpid.jms.Session; @@ -35,6 +40,7 @@ import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.URLSyntaxException; + import javax.jms.*; import javax.jms.IllegalStateException; import java.io.Serializable; @@ -44,6 +50,8 @@ import java.util.Iterator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; public class AMQSession extends Closeable implements Session, QueueSession, TopicSession { @@ -64,6 +72,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private int _defaultPrefetchLowMark = DEFAULT_PREFETCH_LOW_MARK; /** + * Used to reference durable subscribers so they requests for unsubscribe can be handled + * correctly. Note this only keeps a record of subscriptions which have been created + * in the current instance. It does not remember subscriptions between executions of the + * client + */ + private final ConcurrentHashMap<String, TopicSubscriberAdaptor> _subscriptions = + new ConcurrentHashMap<String, TopicSubscriberAdaptor>(); + private final ConcurrentHashMap<BasicMessageConsumer, String> _reverseSubscriptionMap = + new ConcurrentHashMap<BasicMessageConsumer, String>(); + + /** * Used in the consume method. We generate the consume tag on the client so that we can use the nowait * feature. */ @@ -89,6 +108,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private Map _consumers = new ConcurrentHashMap(); /** + * Maps from destination to count of JMSMessageConsumers + */ + private ConcurrentHashMap<Destination, AtomicInteger> _destinationConsumerCount = + new ConcurrentHashMap<Destination, AtomicInteger>(); + + /** * Default value for immediate flag used by producers created by this session is false, i.e. a consumer does not * need to be attached to a queue */ @@ -114,6 +139,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ private volatile AtomicBoolean _stopped = new AtomicBoolean(true); + private final AtomicLong _lastDeliveryTag = new AtomicLong(); + + /** * Responsible for decoding a message fragment and passing it to the appropriate message consumer. */ @@ -152,10 +180,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi if (consumer == null) { _logger.warn("Received a message from queue " + message.deliverBody.consumerTag + " without a handler - ignoring..."); + _logger.warn("Consumers that exist: " + _consumers); + _logger.warn("Session hashcode: " + System.identityHashCode(this)); } else { + consumer.notifyMessage(message, _channelId); + } } else @@ -177,17 +209,15 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { _connection.exceptionReceived(new AMQNoConsumersException("Error: " + reason, bouncedMessage)); } + else if (errorCode == AMQConstant.NO_ROUTE.getCode()) + { + _connection.exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage)); + } else { - if (errorCode == AMQConstant.NO_ROUTE.getCode()) - { - _connection.exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage)); - } - else - { - _connection.exceptionReceived(new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage)); - } + _connection.exceptionReceived(new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage)); } + } catch (Exception e) { @@ -278,7 +308,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi this(con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow); } - AMQConnection getAMQConnection() + public AMQConnection getAMQConnection() { return _connection; } @@ -367,8 +397,19 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public StreamMessage createStreamMessage() throws JMSException { - checkNotClosed(); - throw new UnsupportedOperationException("Stream messages not supported"); + synchronized(_connection.getFailoverMutex()) + { + checkNotClosed(); + + try + { + return (StreamMessage) _messageFactoryRegistry.createMessage(JMSStreamMessage.MIME_TYPE); + } + catch (AMQException e) + { + throw new JMSException("Unable to create text message: " + e); + } + } } public TextMessage createTextMessage() throws JMSException @@ -480,7 +521,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } catch (AMQException e) { - throw new JMSException("Error closing session: " + e); + JMSException jmse = new JMSException("Error closing session: " + e); + jmse.setLinkedException(e); + throw jmse; } finally { @@ -658,6 +701,27 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _connection.getProtocolHandler().writeFrame(BasicRecoverBody.createAMQFrame(_channelId, false)); } + + public void acknowledge() throws JMSException + { + if (getAMQConnection().isClosed()) + { + throw new javax.jms.IllegalStateException("Connection is already closed"); + } + if (isClosed()) + { + throw new javax.jms.IllegalStateException("Session is already closed"); + } + acknowledgeMessage(_lastDeliveryTag.get(), true); + + } + + void setLastDeliveredMessage(AbstractJMSMessage message) + { + _lastDeliveryTag.set(message.getDeliveryTag()); + } + + public MessageListener getMessageListener() throws JMSException { checkNotClosed(); @@ -715,10 +779,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public Object operation() throws JMSException { checkNotClosed(); - - return new BasicMessageProducer(_connection, (AMQDestination) destination, _transacted, _channelId, - AMQSession.this, _connection.getProtocolHandler(), - getNextProducerId(), immediate, mandatory, waitUntilSent); + long producerId = getNextProducerId(); + BasicMessageProducer producer = new BasicMessageProducer(_connection, (AMQDestination) destination, _transacted, _channelId, + AMQSession.this, _connection.getProtocolHandler(), + producerId, immediate, mandatory, waitUntilSent); + registerProducer(producerId, producer); + return producer; } }.execute(_connection); } @@ -732,6 +798,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public QueueReceiver createQueueReceiver(Destination destination) throws JMSException { + checkValidDestination(destination); AMQQueue dest = (AMQQueue) destination; BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(destination); return new QueueReceiverAdaptor(dest, consumer); @@ -747,6 +814,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public QueueReceiver createQueueReceiver(Destination destination, String messageSelector) throws JMSException { + checkValidDestination(destination); AMQQueue dest = (AMQQueue) destination; BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(destination, messageSelector); @@ -755,18 +823,39 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public MessageConsumer createConsumer(Destination destination) throws JMSException { - return createConsumer(destination, _defaultPrefetchHighMark, _defaultPrefetchLowMark, false, false, null); + checkValidDestination(destination); + return createConsumerImpl(destination, + _defaultPrefetchHighMark, + _defaultPrefetchLowMark, + false, + false, + null, + null); } public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException { - return createConsumer(destination, _defaultPrefetchHighMark, _defaultPrefetchLowMark, false, false, messageSelector); + checkValidDestination(destination); + return createConsumerImpl(destination, + _defaultPrefetchHighMark, + _defaultPrefetchLowMark, + false, + false, + messageSelector, + null); } public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) throws JMSException { - return createConsumer(destination, _defaultPrefetchHighMark, _defaultPrefetchLowMark, noLocal, false, messageSelector); + checkValidDestination(destination); + return createConsumerImpl(destination, + _defaultPrefetchHighMark, + _defaultPrefetchLowMark, + noLocal, + false, + messageSelector, + null); } public MessageConsumer createConsumer(Destination destination, @@ -775,7 +864,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi boolean exclusive, String selector) throws JMSException { - return createConsumer(destination, prefetch, prefetch, noLocal, exclusive, selector, null); + checkValidDestination(destination); + return createConsumerImpl(destination, prefetch, prefetch, noLocal, exclusive, selector, null); } @@ -786,7 +876,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi boolean exclusive, String selector) throws JMSException { - return createConsumer(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, null); + checkValidDestination(destination); + return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, null); } public MessageConsumer createConsumer(Destination destination, @@ -796,6 +887,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi String selector, FieldTable rawSelector) throws JMSException { + checkValidDestination(destination); return createConsumerImpl(destination, prefetch, prefetch, noLocal, exclusive, selector, rawSelector); } @@ -808,6 +900,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi String selector, FieldTable rawSelector) throws JMSException { + checkValidDestination(destination); return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, rawSelector); } @@ -820,6 +913,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi final String selector, final FieldTable rawSelector) throws JMSException { + checkTemporaryDestination(destination); + return (org.apache.qpid.jms.MessageConsumer) new FailoverSupport() { public Object operation() throws JMSException @@ -829,16 +924,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi AMQDestination amqd = (AMQDestination) destination; final AMQProtocolHandler protocolHandler = _connection.getProtocolHandler(); - + // TODO: construct the rawSelector from the selector string if rawSelector == null final FieldTable ft = FieldTableFactory.newFieldTable(); - - // Add headers for headers exchange + //if (rawSelector != null) + // ft.put("headers", rawSelector.getDataAsBytes()); if (rawSelector != null) { ft.putAll(rawSelector); } - - BasicMessageConsumer consumer = new BasicMessageConsumer(_channelId, _connection, amqd, selector, noLocal, _messageFactoryRegistry, AMQSession.this, protocolHandler, ft, prefetchHigh, prefetchLow, exclusive, @@ -846,7 +939,13 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { - registerConsumer(consumer); + registerConsumer(consumer, false); + } + catch (AMQInvalidSelectorException ise) + { + JMSException ex = new InvalidSelectorException(ise.getMessage()); + ex.setLinkedException(ise); + throw ex; } catch (AMQException e) { @@ -855,11 +954,46 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi throw ex; } + synchronized(destination) + { + _destinationConsumerCount.putIfAbsent(destination, new AtomicInteger()); + _destinationConsumerCount.get(destination).incrementAndGet(); + } + return consumer; } }.execute(_connection); } + private void checkTemporaryDestination(Destination destination) + throws JMSException + { + if ((destination instanceof TemporaryDestination)) + { + _logger.debug("destination is temporary"); + final TemporaryDestination tempDest = (TemporaryDestination) destination; + if (tempDest.getSession() != this) + { + _logger.debug("destination is on different session"); + throw new JMSException("Cannot consume from a temporary destination created onanother session"); + } + if (tempDest.isDeleted()) + { + _logger.debug("destination is deleted"); + throw new JMSException("Cannot consume from a deleted destination"); + } + } + } + + + public boolean hasConsumer(Destination destination) + { + AtomicInteger counter = _destinationConsumerCount.get(destination); + + return (counter != null) && (counter.get() != 0); + } + + public void declareExchange(String name, String type) { declareExchange(name, type, _connection.getProtocolHandler()); @@ -917,51 +1051,56 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi protocolHandler.writeFrame(queueBind); } -// /** -// * Register to consume from the queue. -// * -// * @param queueName -// * @return the consumer tag generated by the broker -// */ -// private String consumeFromQueue(String queueName, AMQProtocolHandler protocolHandler, int prefetchHigh, int prefetchLow, -// boolean noLocal, boolean exclusive, int acknowledgeMode) throws AMQException -// { -// return consumeFromQueue(queueName, protocolHandler, prefetchHigh, prefetchLow, noLocal, exclusive, acknowledgeMode, null); -// } - /** * Register to consume from the queue. * * @param queueName * @return the consumer tag generated by the broker */ - private String consumeFromQueue(String queueName, AMQProtocolHandler protocolHandler, int prefetchHigh, int prefetchLow, - boolean noLocal, boolean exclusive, int acknowledgeMode, String messageSelector) throws AMQException + private void consumeFromQueue(BasicMessageConsumer consumer, String queueName, AMQProtocolHandler protocolHandler, + boolean nowait, String messageSelector) throws AMQException { //fixme prefetch values are not used here. Do we need to have them as parametsrs? //need to generate a consumer tag on the client so we can exploit the nowait flag String tag = Integer.toString(_nextTag++); - FieldTable ft = FieldTableFactory.newFieldTable(); - + FieldTable arguments = FieldTableFactory.newFieldTable(); if (messageSelector != null) { //fixme move literal value to a common class. - ft.put("x-filter-jms-selector", messageSelector); + arguments.put("x-filter-jms-selector", messageSelector); } - AMQFrame jmsConsume = BasicConsumeBody.createAMQFrame(_channelId, 0, - queueName, tag, noLocal, - acknowledgeMode == Session.NO_ACKNOWLEDGE, - exclusive, true, ft); - + consumer.setConsumerTag(tag); + // we must register the consumer in the map before we actually start listening + _consumers.put(tag, consumer); - protocolHandler.writeFrame(jmsConsume); - return tag; + try + { + AMQFrame jmsConsume = BasicConsumeBody.createAMQFrame(_channelId, 0, + queueName, tag, consumer.isNoLocal(), + consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, + consumer.isExclusive(), nowait, arguments); + if (nowait) + { + protocolHandler.writeFrame(jmsConsume); + } + else + { + protocolHandler.syncWrite(jmsConsume, BasicConsumeOkBody.class); + } + } + catch (AMQException e) + { + // clean-up the map in the event of an error + _consumers.remove(tag); + throw e; + } } public Queue createQueue(String queueName) throws JMSException { + checkNotClosed(); if (queueName.indexOf('/') == -1) { return new AMQQueue(queueName); @@ -991,6 +1130,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public QueueReceiver createReceiver(Queue queue) throws JMSException { + checkNotClosed(); AMQQueue dest = (AMQQueue) queue; BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest); return new QueueReceiverAdaptor(dest, consumer); @@ -1006,6 +1146,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException { + checkNotClosed(); AMQQueue dest = (AMQQueue) queue; BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest, messageSelector); @@ -1014,12 +1155,15 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public QueueSender createSender(Queue queue) throws JMSException { + checkNotClosed(); //return (QueueSender) createProducer(queue); return new QueueSenderAdapter(createProducer(queue), queue); } public Topic createTopic(String topicName) throws JMSException { + checkNotClosed(); + if (topicName.indexOf('/') == -1) { return new AMQTopic(topicName); @@ -1049,6 +1193,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public TopicSubscriber createSubscriber(Topic topic) throws JMSException { + checkNotClosed(); + checkValidTopic(topic); AMQTopic dest = new AMQTopic(topic.getTopicName()); return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest)); } @@ -1064,21 +1210,61 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException { + checkNotClosed(); + checkValidTopic(topic); AMQTopic dest = new AMQTopic(topic.getTopicName()); return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal)); } - /** - * Note, currently this does not handle reuse of the same name with different topics correctly. - * If a name is reused in creating a new subscriber with a different topic/selecto or no-local - * flag then the subcriber will receive messages matching the old subscription AND the new one. - * The spec states that the new one should replace the old one. - * TODO: fix it. - */ public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException { - AMQTopic dest = new AMQTopic((AMQTopic) topic, _connection.getClientID(), name); - return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest)); + checkNotClosed(); + checkValidTopic(topic); + AMQTopic dest = AMQTopic.createDurableTopic((AMQTopic) topic, name, _connection); + TopicSubscriberAdaptor subscriber = _subscriptions.get(name); + if (subscriber != null) + { + if (subscriber.getTopic().equals(topic)) + { + throw new IllegalStateException("Already subscribed to topic " + topic + " with subscription exchange " + + name); + } + else + { + unsubscribe(name); + } + } + else + { + // if the queue is bound to the exchange but NOT for this topic, then the JMS spec + // says we must trash the subscription. + if (isQueueBound(dest.getQueueName()) && + !isQueueBound(dest.getQueueName(), topic.getTopicName())) + { + deleteQueue(dest.getQueueName()); + } + } + + subscriber = new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest)); + + _subscriptions.put(name, subscriber); + _reverseSubscriptionMap.put(subscriber.getMessageConsumer(), name); + + return subscriber; + } + + void deleteQueue(String queueName) throws JMSException + { + try + { + AMQFrame queueDeleteFrame = QueueDeleteBody.createAMQFrame(_channelId, 0, queueName, false, + false, true); + _connection.getProtocolHandler().syncWrite(queueDeleteFrame, QueueDeleteOkBody.class); + } + catch (AMQException e) + { + throw new JMSAMQException(e); + } } /** @@ -1087,43 +1273,92 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException { - AMQTopic dest = new AMQTopic((AMQTopic) topic, _connection.getClientID(), name); + checkNotClosed(); + checkValidTopic(topic); + AMQTopic dest = AMQTopic.createDurableTopic((AMQTopic) topic, name, _connection); BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal); - return new TopicSubscriberAdaptor(dest, consumer); + TopicSubscriberAdaptor subscriber = new TopicSubscriberAdaptor(dest, consumer); + _subscriptions.put(name, subscriber); + _reverseSubscriptionMap.put(subscriber.getMessageConsumer(), name); + return subscriber; } public TopicPublisher createPublisher(Topic topic) throws JMSException { - //return (TopicPublisher) createProducer(topic); - return new TopicPublisherAdapter(createProducer(topic), topic); + checkNotClosed(); + return new TopicPublisherAdapter((BasicMessageProducer) createProducer(topic), topic); } public QueueBrowser createBrowser(Queue queue) throws JMSException { + checkNotClosed(); + checkValidQueue(queue); throw new UnsupportedOperationException("Queue browsing not supported"); } public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException { + checkNotClosed(); + checkValidQueue(queue); throw new UnsupportedOperationException("Queue browsing not supported"); } public TemporaryQueue createTemporaryQueue() throws JMSException { - return new AMQTemporaryQueue(); + checkNotClosed(); + return new AMQTemporaryQueue(this); } public TemporaryTopic createTemporaryTopic() throws JMSException { - return new AMQTemporaryTopic(); + checkNotClosed(); + return new AMQTemporaryTopic(this); } public void unsubscribe(String name) throws JMSException { - //send a queue.delete for the subscription - String queue = _connection.getClientID() + ":" + name; - AMQFrame frame = QueueDeleteBody.createAMQFrame(_channelId, 0, queue, false, false, true); - _connection.getProtocolHandler().writeFrame(frame); + checkNotClosed(); + TopicSubscriberAdaptor subscriber = _subscriptions.get(name); + if (subscriber != null) + { + // send a queue.delete for the subscription + deleteQueue(AMQTopic.getDurableTopicQueueName(name, _connection)); + _subscriptions.remove(name); + _reverseSubscriptionMap.remove(subscriber); + } + else + { + if (isQueueBound(AMQTopic.getDurableTopicQueueName(name, _connection))) + { + deleteQueue(AMQTopic.getDurableTopicQueueName(name, _connection)); + } + else + { + throw new InvalidDestinationException("Unknown subscription exchange:" + name); + } + } + } + + boolean isQueueBound(String queueName) throws JMSException + { + return isQueueBound(queueName, null); + } + + boolean isQueueBound(String queueName, String routingKey) throws JMSException + { + AMQFrame boundFrame = ExchangeBoundBody.createAMQFrame(_channelId, ExchangeDefaults.TOPIC_EXCHANGE_NAME, + routingKey, queueName); + AMQMethodEvent response = null; + try + { + response = _connection.getProtocolHandler().syncWrite(boundFrame, ExchangeBoundOkBody.class); + } + catch (AMQException e) + { + throw new JMSAMQException(e); + } + ExchangeBoundOkBody responseBody = (ExchangeBoundOkBody) response.getMethod(); + return (responseBody.replyCode == ExchangeBoundHandler.OK); } private void checkTransacted() throws JMSException @@ -1152,7 +1387,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { if (_logger.isDebugEnabled()) { - _logger.debug("Message received in session with channel id " + _channelId); + _logger.debug("Message(" + message.contentHeader.properties.toString() + ") received in session with channel id " + _channelId); + } _queue.add(message); @@ -1229,7 +1465,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi * @param consumer * @throws AMQException */ - void registerConsumer(BasicMessageConsumer consumer) throws AMQException + void registerConsumer(BasicMessageConsumer consumer, boolean nowait) throws AMQException { AMQDestination amqd = consumer.getDestination(); @@ -1241,33 +1477,40 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi bindQueue(amqd, queueName, protocolHandler, consumer.getRawSelectorFieldTable()); - String consumerTag = null; try { - consumerTag = consumeFromQueue(queueName, protocolHandler, consumer.getPrefetchHigh(), consumer.getPrefetchLow(), - consumer.isNoLocal(), consumer.isExclusive(), consumer.getAcknowledgeMode(), - consumer.getMessageSelector()); - - consumer.setConsumerTag(consumerTag); - _consumers.put(consumerTag, consumer); + consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer.getMessageSelector()); } catch (JMSException e) { - // getMessageSelector throws JMSEx but it is simply a string return so won't happen. + throw new AMQException(e.getMessage(), e); } - } /** * Called by the MessageConsumer when closing, to deregister the consumer from the * map from consumerTag to consumer instance. * - * @param consumerTag the consumer tag, that was broker-generated + * @param consumer the consum */ - void deregisterConsumer(String consumerTag) + void deregisterConsumer(BasicMessageConsumer consumer) { - _consumers.remove(consumerTag); + _consumers.remove(consumer.getConsumerTag()); + String subscriptionName = _reverseSubscriptionMap.remove(consumer); + if (subscriptionName != null) + { + _subscriptions.remove(subscriptionName); + } + + Destination dest = consumer.getDestination(); + synchronized(dest) + { + if (_destinationConsumerCount.get(dest).decrementAndGet() == 0) + { + _destinationConsumerCount.remove(dest); + } + } } private void registerProducer(long producerId, MessageProducer producer) @@ -1315,7 +1558,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi for (Iterator it = consumers.iterator(); it.hasNext();) { BasicMessageConsumer consumer = (BasicMessageConsumer) it.next(); - registerConsumer(consumer); + registerConsumer(consumer, true); } } @@ -1332,4 +1575,35 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi AMQFrame channelFlowFrame = ChannelFlowBody.createAMQFrame(_channelId, true); _connection.getProtocolHandler().writeFrame(channelFlowFrame); } + + /* + * I could have combined the last 3 methods, but this way it improves readability + */ + private void checkValidTopic(Topic topic) throws JMSException + { + if (topic == null) + { + throw new javax.jms.InvalidDestinationException("Invalid Topic"); + } + if ((topic instanceof TemporaryDestination) && ((TemporaryDestination) topic).getSession() != this) + { + throw new JMSException("Cannot create a subscription on a temporary topic created in another session"); + } + } + + private void checkValidQueue(Queue queue) throws InvalidDestinationException + { + if (queue == null) + { + throw new javax.jms.InvalidDestinationException("Invalid Queue"); + } + } + + private void checkValidDestination(Destination destination) throws InvalidDestinationException + { + if (destination == null) + { + throw new javax.jms.InvalidDestinationException("Invalid Queue"); + } + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java index 0b12bfb728..81fee69f90 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryQueue.java @@ -26,22 +26,45 @@ import javax.jms.TemporaryQueue; /** * AMQ implementation of a TemporaryQueue. */ -final class AMQTemporaryQueue extends AMQQueue implements TemporaryQueue { +final class AMQTemporaryQueue extends AMQQueue implements TemporaryQueue, TemporaryDestination +{ + + + private final AMQSession _session; + private boolean _deleted; /** * Create a new instance of an AMQTemporaryQueue */ - public AMQTemporaryQueue() { - super("TempQueue" + Long.toString(System.currentTimeMillis()), - null, true, true); + public AMQTemporaryQueue(AMQSession session) + { + super("TempQueue" + Long.toString(System.currentTimeMillis()), true); + _session = session; } /** * @see javax.jms.TemporaryQueue#delete() */ - public void delete() throws JMSException { - throw new UnsupportedOperationException("Delete not supported, " + - "will auto-delete when connection closed"); + public synchronized void delete() throws JMSException + { + if(_session.hasConsumer(this)) + { + throw new JMSException("Temporary Queue has consumers so cannot be deleted"); + } + _deleted = true; + + // Currently TemporaryQueue is set to be auto-delete which means that the queue will be deleted + // by the server when there are no more subscriptions to that queue. This is probably not + // quite right for JMSCompliance. + } + + public AMQSession getSession() + { + return _session; + } + + public boolean isDeleted() + { + return _deleted; } - } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java index 0ba5cb3c3a..241a9abc9b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQTemporaryTopic.java @@ -26,15 +26,18 @@ import javax.jms.TemporaryTopic; /** * AMQ implementation of TemporaryTopic. */ -class AMQTemporaryTopic extends AMQTopic implements TemporaryTopic +class AMQTemporaryTopic extends AMQTopic implements TemporaryTopic, TemporaryDestination { + private final AMQSession _session; + private boolean _deleted; /** * Create new temporary topic. */ - public AMQTemporaryTopic() + public AMQTemporaryTopic(AMQSession session) { super("TempQueue" + Long.toString(System.currentTimeMillis())); + _session = session; } /** @@ -42,8 +45,25 @@ class AMQTemporaryTopic extends AMQTopic implements TemporaryTopic */ public void delete() throws JMSException { - throw new UnsupportedOperationException("Delete not supported, " + - "will auto-delete when connection closed"); + if(_session.hasConsumer(this)) + { + throw new JMSException("Temporary Topic has consumers so cannot be deleted"); + } + + _deleted = true; + // Currently TemporaryQueue is set to be auto-delete which means that the queue will be deleted + // by the server when there are no more subscriptions to that queue. This is probably not + // quite right for JMSCompliance. + } + + public AMQSession getSession() + { + return _session; + } + + public boolean isDeleted() + { + return _deleted; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java index 89727f65b7..39304f3f4c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java @@ -7,9 +7,9 @@ * 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 @@ -40,30 +40,30 @@ public class AMQTopic extends AMQDestination implements Topic public AMQTopic(String name) { - super(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, name, true, true, null); - _isDurable = false; + this(name, true, null, false); } - /** - * Constructor for use in creating a topic to represent a durable subscription - * @param topic - * @param clientId - * @param subscriptionName - */ - public AMQTopic(AMQTopic topic, String clientId, String subscriptionName) + public AMQTopic(String name, boolean isAutoDelete, String queueName, boolean isDurable) { - super(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, topic.getDestinationName(), true, false, clientId + ":" + subscriptionName); - _isDurable = true; + super(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, name, true, isAutoDelete, + queueName, isDurable); } - public String getTopicName() throws JMSException + public static AMQTopic createDurableTopic(AMQTopic topic, String subscriptionName, AMQConnection connection) + throws JMSException { - return super.getDestinationName(); + return new AMQTopic(topic.getDestinationName(), false, getDurableTopicQueueName(subscriptionName, connection), + true); } - public String getEncodedName() + public static String getDurableTopicQueueName(String subscriptionName, AMQConnection connection) throws JMSException { - return 'T' + getDestinationName(); + return connection.getClientID() + ":" + subscriptionName; + } + + public String getTopicName() throws JMSException + { + return super.getDestinationName(); } public String getRoutingKey() diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTopicSessionAdaptor.java b/java/client/src/main/java/org/apache/qpid/client/AMQTopicSessionAdaptor.java index 73613b6923..0f50c330fb 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQTopicSessionAdaptor.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQTopicSessionAdaptor.java @@ -7,9 +7,9 @@ * 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 @@ -33,136 +33,169 @@ public class AMQTopicSessionAdaptor implements TopicSession _session = (AMQSession) session; } - public Topic createTopic(String string) throws JMSException { + public Topic createTopic(String string) throws JMSException + { return _session.createTopic(string); } - public TopicSubscriber createSubscriber(Topic topic) throws JMSException { + public TopicSubscriber createSubscriber(Topic topic) throws JMSException + { return _session.createSubscriber(topic); } - public TopicSubscriber createSubscriber(Topic topic, String string, boolean b) throws JMSException { + public TopicSubscriber createSubscriber(Topic topic, String string, boolean b) throws JMSException + { return _session.createSubscriber(topic, string, b); } - public TopicSubscriber createDurableSubscriber(Topic topic, String string) throws JMSException { + public TopicSubscriber createDurableSubscriber(Topic topic, String string) throws JMSException + { return _session.createDurableSubscriber(topic, string); } - public TopicSubscriber createDurableSubscriber(Topic topic, String string, String string1, boolean b) throws JMSException { + public TopicSubscriber createDurableSubscriber(Topic topic, String string, String string1, boolean b) throws JMSException + { return _session.createDurableSubscriber(topic, string, string1, b); } - public TopicPublisher createPublisher(Topic topic) throws JMSException { + public TopicPublisher createPublisher(Topic topic) throws JMSException + { return _session.createPublisher(topic); } - public TemporaryTopic createTemporaryTopic() throws JMSException { + public TemporaryTopic createTemporaryTopic() throws JMSException + { return _session.createTemporaryTopic(); } - public void unsubscribe(String string) throws JMSException { + public void unsubscribe(String string) throws JMSException + { _session.unsubscribe(string); } - public BytesMessage createBytesMessage() throws JMSException { + public BytesMessage createBytesMessage() throws JMSException + { return _session.createBytesMessage(); } - public MapMessage createMapMessage() throws JMSException { + public MapMessage createMapMessage() throws JMSException + { return _session.createMapMessage(); } - public Message createMessage() throws JMSException { + public Message createMessage() throws JMSException + { return _session.createMessage(); } - public ObjectMessage createObjectMessage() throws JMSException { + public ObjectMessage createObjectMessage() throws JMSException + { return _session.createObjectMessage(); } - public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException { + public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException + { return _session.createObjectMessage(); } - public StreamMessage createStreamMessage() throws JMSException { + public StreamMessage createStreamMessage() throws JMSException + { return _session.createStreamMessage(); } - public TextMessage createTextMessage() throws JMSException { + public TextMessage createTextMessage() throws JMSException + { return _session.createTextMessage(); } - public TextMessage createTextMessage(String string) throws JMSException { - return _session.createTextMessage(); + public TextMessage createTextMessage(String string) throws JMSException + { + return _session.createTextMessage(string); } - public boolean getTransacted() throws JMSException { + public boolean getTransacted() throws JMSException + { return _session.getTransacted(); } - public int getAcknowledgeMode() throws JMSException { + public int getAcknowledgeMode() throws JMSException + { return _session.getAcknowledgeMode(); } - public void commit() throws JMSException { + public void commit() throws JMSException + { _session.commit(); } - public void rollback() throws JMSException { + public void rollback() throws JMSException + { _session.rollback(); } - public void close() throws JMSException { + public void close() throws JMSException + { _session.close(); } - public void recover() throws JMSException { + public void recover() throws JMSException + { _session.recover(); } - public MessageListener getMessageListener() throws JMSException { + public MessageListener getMessageListener() throws JMSException + { return _session.getMessageListener(); } - public void setMessageListener(MessageListener messageListener) throws JMSException { + public void setMessageListener(MessageListener messageListener) throws JMSException + { _session.setMessageListener(messageListener); } - public void run() { + public void run() + { _session.run(); } - public MessageProducer createProducer(Destination destination) throws JMSException { + public MessageProducer createProducer(Destination destination) throws JMSException + { return _session.createProducer(destination); } - public MessageConsumer createConsumer(Destination destination) throws JMSException { + public MessageConsumer createConsumer(Destination destination) throws JMSException + { return _session.createConsumer(destination); } - public MessageConsumer createConsumer(Destination destination, String string) throws JMSException { + public MessageConsumer createConsumer(Destination destination, String string) throws JMSException + { return _session.createConsumer(destination, string); } - public MessageConsumer createConsumer(Destination destination, String string, boolean b) throws JMSException { + public MessageConsumer createConsumer(Destination destination, String string, boolean b) throws JMSException + { return _session.createConsumer(destination, string, b); } //The following methods cannot be called from a TopicSession as per JMS spec - public Queue createQueue(String string) throws JMSException { + public Queue createQueue(String string) throws JMSException + { throw new IllegalStateException("Cannot call createQueue from TopicSession"); } - public QueueBrowser createBrowser(Queue queue) throws JMSException { + public QueueBrowser createBrowser(Queue queue) throws JMSException + { throw new IllegalStateException("Cannot call createBrowser from TopicSession"); } - public QueueBrowser createBrowser(Queue queue, String string) throws JMSException { + public QueueBrowser createBrowser(Queue queue, String string) throws JMSException + { throw new IllegalStateException("Cannot call createBrowser from TopicSession"); } - public TemporaryQueue createTemporaryQueue() throws JMSException { + public TemporaryQueue createTemporaryQueue() throws JMSException + { throw new IllegalStateException("Cannot call createTemporaryQueue from TopicSession"); } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java index f97ea6bf1e..9f9038fddd 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java @@ -7,9 +7,9 @@ * 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 @@ -159,11 +159,13 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public String getMessageSelector() throws JMSException { + checkPreConditions(); return _messageSelector; } public MessageListener getMessageListener() throws JMSException { + checkPreConditions(); return (MessageListener) _messageListener.get(); } @@ -179,7 +181,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public void setMessageListener(MessageListener messageListener) throws JMSException { - checkNotClosed(); + checkPreConditions(); //if the current listener is non-null and the session is not stopped, then //it is an error to call this method. @@ -212,10 +214,10 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { //handle case where connection has already been started, and the dispatcher is blocked //doing a put on the _synchronousQueue - Object msg = _synchronousQueue.poll(); - if (msg != null) + AbstractJMSMessage jmsMsg = (AbstractJMSMessage)_synchronousQueue.poll(); + if (jmsMsg != null) { - AbstractJMSMessage jmsMsg = (AbstractJMSMessage) msg; + _session.setLastDeliveredMessage(jmsMsg); messageListener.onMessage(jmsMsg); postDeliver(jmsMsg); } @@ -277,8 +279,8 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public Message receive(long l) throws JMSException { - checkNotClosed(); - + checkPreConditions(); + acquireReceiving(); try @@ -295,12 +297,15 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer final AbstractJMSMessage m = returnMessageOrThrow(o); if (m != null) { + _session.setLastDeliveredMessage(m); postDeliver(m); } + return m; } catch (InterruptedException e) { + _logger.warn("Interrupted: " + e, e); return null; } finally @@ -311,7 +316,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public Message receiveNoWait() throws JMSException { - checkNotClosed(); + checkPreConditions(); acquireReceiving(); @@ -321,8 +326,10 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer final AbstractJMSMessage m = returnMessageOrThrow(o); if (m != null) { + _session.setLastDeliveredMessage(m); postDeliver(m); } + return m; } finally @@ -421,6 +428,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { //we do not need a lock around the test above, and the dispatch below as it is invalid //for an application to alter an installed listener while the session is started + _session.setLastDeliveredMessage(jmsMessage); getMessageListener().onMessage(jmsMessage); postDeliver(jmsMessage); } @@ -457,8 +465,9 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer } } - private void postDeliver(AbstractJMSMessage msg) + private void postDeliver(AbstractJMSMessage msg) throws JMSException { + msg.setJMSDestination(_destination); switch (_acknowledgeMode) { case Session.DUPS_OK_ACKNOWLEDGE: @@ -520,7 +529,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer */ private void deregisterConsumer() { - _session.deregisterConsumer(_consumerTag); + _session.deregisterConsumer(this); } public String getConsumerTag() @@ -532,4 +541,17 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { _consumerTag = consumerTag; } + + public AMQSession getSession() { + return _session; + } + + private void checkPreConditions() throws JMSException{ + + this.checkNotClosed(); + + if(_session == null || _session.isClosed()){ + throw new javax.jms.IllegalStateException("Invalid Session"); + } + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java index 14cafc3558..e11d70cf41 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java @@ -7,9 +7,9 @@ * 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 @@ -28,11 +28,9 @@ import org.apache.qpid.client.message.JMSBytesMessage; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.*; -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; +import javax.jms.*; import java.io.UnsupportedEncodingException; +import java.util.Enumeration; public class BasicMessageProducer extends Closeable implements org.apache.qpid.jms.MessageProducer { @@ -102,6 +100,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j private final boolean _mandatory; private final boolean _waitUntilSent; + private static final ContentBody[] NO_CONTENT_BODIES = new ContentBody[0]; protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId, AMQSession session, AMQProtocolHandler protocolHandler, @@ -143,6 +142,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void setDisableMessageID(boolean b) throws JMSException { + checkPreConditions(); checkNotClosed(); // IGNORED } @@ -156,7 +156,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void setDisableMessageTimestamp(boolean b) throws JMSException { - checkNotClosed(); + checkPreConditions(); _disableTimestamps = b; } @@ -168,11 +168,11 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void setDeliveryMode(int i) throws JMSException { - checkNotClosed(); + checkPreConditions(); if (i != DeliveryMode.NON_PERSISTENT && i != DeliveryMode.PERSISTENT) { throw new JMSException("DeliveryMode must be either NON_PERSISTENT or PERSISTENT. Value of " + i + - " is illegal"); + " is illegal"); } _deliveryMode = i; } @@ -185,7 +185,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void setPriority(int i) throws JMSException { - checkNotClosed(); + checkPreConditions(); if (i < 0 || i > 9) { throw new IllegalArgumentException("Priority of " + i + " is illegal. Value must be in range 0 to 9"); @@ -201,7 +201,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void setTimeToLive(long l) throws JMSException { - checkNotClosed(); + checkPreConditions(); if (l < 0) { throw new IllegalArgumentException("Time to live must be non-negative - supplied value was " + l); @@ -229,27 +229,36 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void send(Message message) throws JMSException { + checkPreConditions(); + checkInitialDestination(); + + synchronized (_connection.getFailoverMutex()) { - sendImpl(_destination, (AbstractJMSMessage) message, _deliveryMode, _messagePriority, _timeToLive, + sendImpl(_destination, message, _deliveryMode, _messagePriority, _timeToLive, _mandatory, _immediate); } } public void send(Message message, int deliveryMode) throws JMSException { + checkPreConditions(); + checkInitialDestination(); + synchronized (_connection.getFailoverMutex()) { - sendImpl(_destination, (AbstractJMSMessage) message, deliveryMode, _messagePriority, _timeToLive, + sendImpl(_destination, message, deliveryMode, _messagePriority, _timeToLive, _mandatory, _immediate); } } public void send(Message message, int deliveryMode, boolean immediate) throws JMSException { + checkPreConditions(); + checkInitialDestination(); synchronized (_connection.getFailoverMutex()) { - sendImpl(_destination, (AbstractJMSMessage) message, deliveryMode, _messagePriority, _timeToLive, + sendImpl(_destination, message, deliveryMode, _messagePriority, _timeToLive, _mandatory, immediate); } } @@ -257,20 +266,23 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j public void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { + checkPreConditions(); + checkInitialDestination(); synchronized (_connection.getFailoverMutex()) { - sendImpl(_destination, (AbstractJMSMessage)message, deliveryMode, priority, timeToLive, _mandatory, + sendImpl(_destination, message, deliveryMode, priority, timeToLive, _mandatory, _immediate); } } public void send(Destination destination, Message message) throws JMSException { - checkNotClosed(); + checkPreConditions(); + checkDestination(destination); synchronized (_connection.getFailoverMutex()) { validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, _deliveryMode, _messagePriority, _timeToLive, + sendImpl((AMQDestination) destination, message, _deliveryMode, _messagePriority, _timeToLive, _mandatory, _immediate); } } @@ -279,11 +291,12 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j int priority, long timeToLive) throws JMSException { - checkNotClosed(); + checkPreConditions(); + checkDestination(destination); synchronized (_connection.getFailoverMutex()) { validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, + sendImpl((AMQDestination) destination, message, deliveryMode, priority, timeToLive, _mandatory, _immediate); } } @@ -292,11 +305,12 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j int priority, long timeToLive, boolean mandatory) throws JMSException { - checkNotClosed(); + checkPreConditions(); + checkDestination(destination); synchronized (_connection.getFailoverMutex()) { validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, + sendImpl((AMQDestination) destination, message, deliveryMode, priority, timeToLive, mandatory, _immediate); } } @@ -305,11 +319,12 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j int priority, long timeToLive, boolean mandatory, boolean immediate) throws JMSException { - checkNotClosed(); + checkPreConditions(); + checkDestination(destination); synchronized (_connection.getFailoverMutex()) { validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, + sendImpl((AMQDestination) destination, message, deliveryMode, priority, timeToLive, mandatory, immediate); } } @@ -319,26 +334,158 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j boolean immediate, boolean waitUntilSent) throws JMSException { - checkNotClosed(); + checkPreConditions(); + checkDestination(destination); synchronized (_connection.getFailoverMutex()) { validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, + sendImpl((AMQDestination) destination, message, deliveryMode, priority, timeToLive, mandatory, immediate, waitUntilSent); } } + + private AbstractJMSMessage convertToNativeMessage(Message message) throws JMSException + { + if (message instanceof AbstractJMSMessage) + { + return (AbstractJMSMessage) message; + } + else + { + AbstractJMSMessage newMessage; + + if (message instanceof BytesMessage) + { + BytesMessage bytesMessage = (BytesMessage) message; + bytesMessage.reset(); + + JMSBytesMessage nativeMsg = (JMSBytesMessage) _session.createBytesMessage(); + + + byte[] buf = new byte[1024]; + + int len; + + while ((len = bytesMessage.readBytes(buf)) != -1) + { + nativeMsg.writeBytes(buf, 0, len); + } + + newMessage = nativeMsg; + } + else if (message instanceof MapMessage) + { + MapMessage origMessage = (MapMessage) message; + MapMessage nativeMessage = _session.createMapMessage(); + + Enumeration mapNames = origMessage.getMapNames(); + while (mapNames.hasMoreElements()) + { + String name = (String) mapNames.nextElement(); + nativeMessage.setObject(name, origMessage.getObject(name)); + } + newMessage = (AbstractJMSMessage) nativeMessage; + } + else if (message instanceof ObjectMessage) + { + ObjectMessage origMessage = (ObjectMessage) message; + ObjectMessage nativeMessage = _session.createObjectMessage(); + + nativeMessage.setObject(origMessage.getObject()); + + newMessage = (AbstractJMSMessage) nativeMessage; + } + else if (message instanceof TextMessage) + { + TextMessage origMessage = (TextMessage) message; + TextMessage nativeMessage = _session.createTextMessage(); + + nativeMessage.setText(origMessage.getText()); + + newMessage = (AbstractJMSMessage) nativeMessage; + } + else if (message instanceof StreamMessage) + { + StreamMessage origMessage = (StreamMessage) message; + StreamMessage nativeMessage = _session.createStreamMessage(); + + + try + { + origMessage.reset(); + while (true) + { + nativeMessage.writeObject(origMessage.readObject()); + } + } + catch (MessageEOFException e) + { + ;// + } + newMessage = (AbstractJMSMessage) nativeMessage; + } + else + { + newMessage = (AbstractJMSMessage) _session.createMessage(); + + } + + Enumeration propertyNames = message.getPropertyNames(); + while (propertyNames.hasMoreElements()) + { + String propertyName = String.valueOf(propertyNames.nextElement()); + if (!propertyName.startsWith("JMSX_")) + { + Object value = message.getObjectProperty(propertyName); + newMessage.setObjectProperty(propertyName, value); + } + } + + newMessage.setJMSDeliveryMode(message.getJMSDeliveryMode()); + + + int priority = message.getJMSPriority(); + if (priority < 0) + { + priority = 0; + } + else if (priority > 9) + { + priority = 9; + } + + newMessage.setJMSPriority(priority); + if (message.getJMSReplyTo() != null) + { + newMessage.setJMSReplyTo(message.getJMSReplyTo()); + } + newMessage.setJMSType(message.getJMSType()); + + + if (newMessage != null) + { + return newMessage; + } + else + { + throw new JMSException("Unable to send message, due to class conversion error: " + message.getClass().getName()); + } + } + } + + private void validateDestination(Destination destination) throws JMSException { if (!(destination instanceof AMQDestination)) { throw new JMSException("Unsupported destination class: " + - (destination != null ? destination.getClass() : null)); + (destination != null ? destination.getClass() : null)); } - declareDestination((AMQDestination)destination); + declareDestination((AMQDestination) destination); } - protected void sendImpl(AMQDestination destination, AbstractJMSMessage message, int deliveryMode, int priority, + protected void sendImpl(AMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive, boolean mandatory, boolean immediate) throws JMSException { sendImpl(destination, message, deliveryMode, priority, timeToLive, mandatory, immediate, _waitUntilSent); @@ -346,8 +493,9 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j /** * The caller of this method must hold the failover mutex. + * * @param destination - * @param message + * @param origMessage * @param deliveryMode * @param priority * @param timeToLive @@ -355,9 +503,12 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j * @param immediate * @throws JMSException */ - protected void sendImpl(AMQDestination destination, AbstractJMSMessage message, int deliveryMode, int priority, + protected void sendImpl(AMQDestination destination, Message origMessage, int deliveryMode, int priority, long timeToLive, boolean mandatory, boolean immediate, boolean wait) throws JMSException { + checkTemporaryDestination(destination); + + AbstractJMSMessage message = convertToNativeMessage(origMessage); AMQFrame publishFrame = BasicPublishBody.createAMQFrame(_channelId, 0, destination.getExchangeName(), destination.getRoutingKey(), mandatory, immediate); @@ -367,17 +518,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j currentTime = System.currentTimeMillis(); message.setJMSTimestamp(currentTime); } - // - // Very nasty temporary hack for GRM-206. Will be altered ASAP. - // - if (message instanceof JMSBytesMessage) - { - JMSBytesMessage msg = (JMSBytesMessage) message; - if (!msg.isReadable()) - { - msg.reset(); - } - } + message.prepareForSending(); ByteBuffer payload = message.getData(); BasicContentHeaderProperties contentHeaderProperties = message.getJmsContentHeaderProperties(); @@ -398,7 +539,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j contentHeaderProperties.setDeliveryMode((byte) deliveryMode); contentHeaderProperties.setPriority((byte) priority); - int size = payload.limit(); + int size = (payload != null) ? payload.limit() : 0; ContentBody[] contentBodies = createContentBodies(payload); AMQFrame[] frames = new AMQFrame[2 + contentBodies.length]; for (int i = 0; i < contentBodies.length; i++) @@ -423,24 +564,52 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j frames[1] = contentHeaderFrame; CompositeAMQDataBlock compositeFrame = new CompositeAMQDataBlock(frames); _protocolHandler.writeFrame(compositeFrame, wait); + + + if (message != origMessage) + { + _logger.warn("Updating original message"); + origMessage.setJMSPriority(message.getJMSPriority()); + origMessage.setJMSTimestamp(message.getJMSTimestamp()); + _logger.warn("Setting JMSExpiration:" + message.getJMSExpiration()); + origMessage.setJMSExpiration(message.getJMSExpiration()); + origMessage.setJMSMessageID(message.getJMSMessageID()); + } + } + + private void checkTemporaryDestination(AMQDestination destination) throws JMSException + { + if(destination instanceof TemporaryDestination) + { + _logger.debug("destination is temporary destination"); + TemporaryDestination tempDest = (TemporaryDestination) destination; + if(tempDest.getSession().isClosed()) + { + _logger.debug("session is closed"); + throw new JMSException("Session for temporary destination has been closed"); + } + if(tempDest.isDeleted()) + { + _logger.debug("destination is deleted"); + throw new JMSException("Cannot send to a deleted temporary destination"); + } + } } /** * Create content bodies. This will split a large message into numerous bodies depending on the negotiated * maximum frame size. + * * @param payload * @return the array of content bodies */ private ContentBody[] createContentBodies(ByteBuffer payload) { - if (payload == null) + if (payload == null || payload.remaining() == 0) { - return null; - } - else if (payload.remaining() == 0) - { - return new ContentBody[0]; + return NO_CONTENT_BODIES; } + // we substract one from the total frame maximum size to account for the end of frame marker in a body frame // (0xCE byte). int dataLength = payload.remaining(); @@ -460,8 +629,8 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j for (int i = 0; i < bodies.length; i++) { bodies[i] = new ContentBody(); - payload.position((int)framePayloadMax * i); - int length = (remaining >= framePayloadMax) ? (int)framePayloadMax : (int)remaining; + payload.position((int) framePayloadMax * i); + int length = (remaining >= framePayloadMax) ? (int) framePayloadMax : (int) remaining; payload.limit(payload.position() + length); bodies[i].payload = payload.slice(); remaining -= length; @@ -481,4 +650,43 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j checkNotClosed(); _encoding = encoding; } + + private void checkPreConditions() throws javax.jms.IllegalStateException, JMSException + { + checkNotClosed(); + + if (_session == null || _session.isClosed()) + { + throw new javax.jms.IllegalStateException("Invalid Session"); + } + } + + private void checkInitialDestination() + { + if (_destination == null) + { + throw new UnsupportedOperationException("Destination is null"); + } + } + + private void checkDestination(Destination suppliedDestination) throws InvalidDestinationException + { + if (_destination != null && suppliedDestination != null) + { + throw new UnsupportedOperationException("This message producer was created with a Destination, therefore you cannot use an unidentified Destination"); + } + + if (suppliedDestination == null) + { + throw new InvalidDestinationException("Supplied Destination was invalid"); + } + + + } + + + public AMQSession getSession() + { + return _session; + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java b/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java new file mode 100644 index 0000000000..34ec49436e --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/JMSAMQException.java @@ -0,0 +1,34 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed 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.client; + +import org.apache.qpid.AMQException; + +import javax.jms.JMSException; + +/** + * @author Apache Software Foundation + */ +public class JMSAMQException extends JMSException +{ + public JMSAMQException(AMQException s) + { + super(s.getMessage(), String.valueOf(s.getErrorCode())); + setLinkedException(s); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java b/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java new file mode 100644 index 0000000000..10a65c2ad8 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java @@ -0,0 +1,50 @@ +package org.apache.qpid.client; + +import java.util.Enumeration; + +import javax.jms.ConnectionMetaData; +import javax.jms.JMSException; + +public class QpidConnectionMetaData implements ConnectionMetaData { + + private static QpidConnectionMetaData _instance = new QpidConnectionMetaData(); + + private QpidConnectionMetaData(){ + } + + public static QpidConnectionMetaData instance(){ + return _instance; + } + + public int getJMSMajorVersion() throws JMSException { + return 1; + } + + public int getJMSMinorVersion() throws JMSException { + return 1; + } + + public String getJMSProviderName() throws JMSException { + return "Apache Qpid"; + } + + public String getJMSVersion() throws JMSException { + return "1.1"; + } + + public Enumeration getJMSXPropertyNames() throws JMSException { + return null; + } + + public int getProviderMajorVersion() throws JMSException { + return 0; + } + + public int getProviderMinorVersion() throws JMSException { + return 9; + } + + public String getProviderVersion() throws JMSException { + return "Incubating-M1"; + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java b/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java index 57e458d833..aeb2afa118 100644 --- a/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java +++ b/java/client/src/main/java/org/apache/qpid/client/QueueReceiverAdaptor.java @@ -39,31 +39,37 @@ public class QueueReceiverAdaptor implements QueueReceiver { public String getMessageSelector() throws JMSException { + checkPreConditions(); return _consumer.getMessageSelector(); } public MessageListener getMessageListener() throws JMSException { + checkPreConditions(); return _consumer.getMessageListener(); } public void setMessageListener(MessageListener messageListener) throws JMSException { + checkPreConditions(); _consumer.setMessageListener(messageListener); } public Message receive() throws JMSException { + checkPreConditions(); return _consumer.receive(); } public Message receive(long l) throws JMSException { + checkPreConditions(); return _consumer.receive(l); } public Message receiveNoWait() throws JMSException { + checkPreConditions(); return _consumer.receiveNoWait(); } @@ -79,8 +85,26 @@ public class QueueReceiverAdaptor implements QueueReceiver { */ public Queue getQueue() throws JMSException { + checkPreConditions(); return _queue; } + private void checkPreConditions() throws javax.jms.IllegalStateException { + BasicMessageConsumer msgConsumer = (BasicMessageConsumer)_consumer; + + if (msgConsumer.isClosed() ){ + throw new javax.jms.IllegalStateException("Consumer is closed"); + } + + if(_queue == null){ + throw new UnsupportedOperationException("Queue is null"); + } + + AMQSession session = msgConsumer.getSession(); + + if(session == null || session.isClosed()){ + throw new javax.jms.IllegalStateException("Invalid Session"); + } + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java b/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java index cfdea2ad15..c8de298ba1 100644 --- a/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java +++ b/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java @@ -1,6 +1,7 @@ package org.apache.qpid.client; import javax.jms.Destination; +import javax.jms.IllegalStateException; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageProducer; @@ -9,96 +10,136 @@ import javax.jms.QueueSender; public class QueueSenderAdapter implements QueueSender { - private MessageProducer delegate; - private Queue queue; + private MessageProducer _delegate; + private Queue _queue; + private boolean closed = false; public QueueSenderAdapter(MessageProducer msgProducer, Queue queue){ - delegate = msgProducer; - this.queue = queue; + _delegate = msgProducer; + _queue = queue; } public Queue getQueue() throws JMSException { - return queue; + checkPreConditions(); + return _queue; } public void send(Message msg) throws JMSException { - delegate.send(msg); + checkPreConditions(); + _delegate.send(msg); } public void send(Queue queue, Message msg) throws JMSException { - delegate.send(queue, msg); + checkPreConditions(queue); + _delegate.send(queue, msg); } public void publish(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException { - - delegate.send(msg, deliveryMode,priority,timeToLive); + checkPreConditions(); + _delegate.send(msg, deliveryMode,priority,timeToLive); } public void send(Queue queue,Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException { - - delegate.send(queue,msg, deliveryMode,priority,timeToLive); + checkPreConditions(queue); + _delegate.send(queue,msg, deliveryMode,priority,timeToLive); } public void close() throws JMSException { - delegate.close(); + _delegate.close(); + closed = true; } public int getDeliveryMode() throws JMSException { - return delegate.getDeliveryMode(); + checkPreConditions(); + return _delegate.getDeliveryMode(); } public Destination getDestination() throws JMSException { - return delegate.getDestination(); + checkPreConditions(); + return _delegate.getDestination(); } public boolean getDisableMessageID() throws JMSException { - return delegate.getDisableMessageID(); + checkPreConditions(); + return _delegate.getDisableMessageID(); } public boolean getDisableMessageTimestamp() throws JMSException { - return delegate.getDisableMessageTimestamp(); + checkPreConditions(); + return _delegate.getDisableMessageTimestamp(); } public int getPriority() throws JMSException { - return delegate.getPriority(); + checkPreConditions(); + return _delegate.getPriority(); } public long getTimeToLive() throws JMSException { - return delegate.getTimeToLive(); + checkPreConditions(); + return _delegate.getTimeToLive(); } public void send(Destination dest, Message msg) throws JMSException { - delegate.send(dest,msg); + checkPreConditions((Queue)dest); + _delegate.send(dest,msg); } public void send(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException { - delegate.send(msg, deliveryMode,priority,timeToLive); + checkPreConditions(); + _delegate.send(msg, deliveryMode,priority,timeToLive); } public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException { - delegate.send(dest,msg, deliveryMode,priority,timeToLive); + checkPreConditions((Queue)dest); + _delegate.send(dest,msg, deliveryMode,priority,timeToLive); } public void setDeliveryMode(int deliveryMode) throws JMSException { - delegate.setDeliveryMode(deliveryMode); + checkPreConditions(); + _delegate.setDeliveryMode(deliveryMode); } public void setDisableMessageID(boolean disableMessageID) throws JMSException { - delegate.setDisableMessageID(disableMessageID); + checkPreConditions(); + _delegate.setDisableMessageID(disableMessageID); } public void setDisableMessageTimestamp(boolean disableMessageTimestamp) throws JMSException { - delegate.setDisableMessageTimestamp(disableMessageTimestamp); + checkPreConditions(); + _delegate.setDisableMessageTimestamp(disableMessageTimestamp); } public void setPriority(int priority) throws JMSException { - delegate.setPriority(priority); + checkPreConditions(); + _delegate.setPriority(priority); } public void setTimeToLive(long timeToLive) throws JMSException { - delegate.setTimeToLive(timeToLive); + checkPreConditions(); + _delegate.setTimeToLive(timeToLive); + } + + private void checkPreConditions() throws IllegalStateException, IllegalStateException + { + checkPreConditions(_queue); + } + + private void checkPreConditions(Queue queue) throws IllegalStateException, IllegalStateException { + if (closed){ + throw new javax.jms.IllegalStateException("Publisher is closed"); + } + + if(queue == null){ + throw new UnsupportedOperationException("Queue is null"); + } + + AMQSession session = ((BasicMessageProducer) _delegate).getSession(); + + if(session == null || session.isClosed()){ + throw new javax.jms.IllegalStateException("Invalid Session"); + } } } diff --git a/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java b/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java new file mode 100644 index 0000000000..8c11672a65 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/TemporaryDestination.java @@ -0,0 +1,17 @@ +package org.apache.qpid.client;
+
+import javax.jms.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Provides support for covenience interface implemented by both AMQTemporaryTopic and AMQTemporaryQueue
+ * so that operations related to their "temporary-ness" can be abstracted out.
+ */
+interface TemporaryDestination extends Destination
+{
+
+ public void delete() throws JMSException;
+ public AMQSession getSession();
+ public boolean isDeleted();
+
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java b/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java index 53a42e5185..803f2e03a4 100644 --- a/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java +++ b/java/client/src/main/java/org/apache/qpid/client/TopicPublisherAdapter.java @@ -1,107 +1,174 @@ package org.apache.qpid.client; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageProducer; -import javax.jms.Topic; -import javax.jms.TopicPublisher; - -public class TopicPublisherAdapter implements TopicPublisher { - - private MessageProducer delegate; - private Topic topic; - - public TopicPublisherAdapter(MessageProducer msgProducer, Topic topic){ - delegate = msgProducer; - this.topic = topic; - } - - public Topic getTopic() throws JMSException { - return topic; - } - - public void publish(Message msg) throws JMSException { - delegate.send(msg); - } - - public void publish(Topic topic, Message msg) throws JMSException { - delegate.send(topic,msg); - } - - public void publish(Message msg, int deliveryMode, int priority, long timeToLive) - throws JMSException { - delegate.send(msg, deliveryMode,priority,timeToLive); - } - - public void publish(Topic topic, Message msg, int deliveryMode, int priority, long timeToLive) - throws JMSException { - delegate.send(topic,msg, deliveryMode,priority,timeToLive); - } - - public void close() throws JMSException { - delegate.close(); - } +import javax.jms.*; +import javax.jms.IllegalStateException; + +public class TopicPublisherAdapter implements TopicPublisher +{ + + private BasicMessageProducer _delegate; + private Topic _topic; + + public TopicPublisherAdapter(BasicMessageProducer msgProducer, Topic topic) + { + _delegate = msgProducer; + _topic = topic; + } + + public Topic getTopic() throws JMSException + { + checkPreConditions(); + return _topic; + } + + public void publish(Message msg) throws JMSException + { + checkPreConditions(); + checkTopic(_topic); + _delegate.send(msg); + } + + public void publish(Topic topic, Message msg) throws JMSException + { + checkPreConditions(); + checkTopic(topic); + _delegate.send(topic, msg); + } + + public void publish(Message msg, int deliveryMode, int priority, long timeToLive) + throws JMSException + { + checkPreConditions(); + checkTopic(_topic); + _delegate.send(msg, deliveryMode, priority, timeToLive); + } public int getDeliveryMode() throws JMSException { - return delegate.getDeliveryMode(); + checkPreConditions(); + return _delegate.getDeliveryMode(); } - public Destination getDestination() throws JMSException { - return delegate.getDestination(); - } + public void publish(Topic topic, Message msg, int deliveryMode, int priority, long timeToLive) + throws JMSException + { + checkPreConditions(); + checkTopic(topic); + _delegate.send(topic, msg, deliveryMode, priority, timeToLive); + } + + public void close() throws JMSException + { + _delegate.close(); + } public boolean getDisableMessageID() throws JMSException { - return delegate.getDisableMessageID(); + checkPreConditions(); + return _delegate.getDisableMessageID(); } public boolean getDisableMessageTimestamp() throws JMSException { - return delegate.getDisableMessageTimestamp(); + checkPreConditions(); + return _delegate.getDisableMessageTimestamp(); } - - public int getPriority() throws JMSException { - return delegate.getPriority(); - } - - public long getTimeToLive() throws JMSException { - return delegate.getTimeToLive(); - } - - public void send(Message msg) throws JMSException { - delegate.send(msg); - } - - public void send(Destination dest, Message msg) throws JMSException { - delegate.send(dest,msg); - } - - public void send(Message msg, int deliveryMode, int priority, long timeToLive) - throws JMSException { - delegate.send(msg, deliveryMode,priority,timeToLive); - } - - public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException { - delegate.send(dest,msg, deliveryMode,priority,timeToLive); - } - - public void setDeliveryMode(int deliveryMode) throws JMSException { - delegate.setDeliveryMode(deliveryMode); - } - - public void setDisableMessageID(boolean disableMessageID) throws JMSException { - delegate.setDisableMessageID(disableMessageID); - } - - public void setDisableMessageTimestamp(boolean disableMessageTimestamp) throws JMSException { - delegate.setDisableMessageTimestamp(disableMessageTimestamp); - } - - public void setPriority(int priority) throws JMSException { - delegate.setPriority(priority); - } - - public void setTimeToLive(long timeToLive) throws JMSException { - delegate.setTimeToLive(timeToLive); - } - + + public Destination getDestination() throws JMSException + { + checkPreConditions(); + return _delegate.getDestination(); + } + + public int getPriority() throws JMSException { + checkPreConditions(); + return _delegate.getPriority(); + } + + public long getTimeToLive() throws JMSException { + checkPreConditions(); + return _delegate.getTimeToLive(); + } + + public void send(Message msg) throws JMSException + { + checkPreConditions(); + checkTopic(_topic); + _delegate.send(msg); + } + + public void send(Destination dest, Message msg) throws JMSException + { + checkPreConditions(); + checkTopic(_topic); + _delegate.send(dest, msg); + } + + public void send(Message msg, int deliveryMode, int priority, long timeToLive) + throws JMSException + { + checkPreConditions(); + checkTopic(_topic); + _delegate.send(msg, deliveryMode, priority, timeToLive); + } + + public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException + { + checkPreConditions(); + checkTopic(dest); + _delegate.send(dest, msg, deliveryMode, priority, timeToLive); + } + + public void setDeliveryMode(int deliveryMode) throws JMSException + { + checkPreConditions(); + _delegate.setDeliveryMode(deliveryMode); + } + + public void setDisableMessageID(boolean disableMessageID) throws JMSException + { + checkPreConditions(); + _delegate.setDisableMessageID(disableMessageID); + } + + public void setDisableMessageTimestamp(boolean disableMessageTimestamp) throws JMSException + { + checkPreConditions(); + _delegate.setDisableMessageTimestamp(disableMessageTimestamp); + } + + public void setPriority(int priority) throws JMSException + { + checkPreConditions(); + _delegate.setPriority(priority); + } + + public void setTimeToLive(long timeToLive) throws JMSException + { + checkPreConditions(); + _delegate.setTimeToLive(timeToLive); + } + + private void checkPreConditions() throws IllegalStateException + { + if (_delegate.isClosed()) + { + throw new javax.jms.IllegalStateException("Publisher is _closed"); + } + + AMQSession session = _delegate.getSession(); + if (session == null || session.isClosed()) + { + throw new javax.jms.IllegalStateException("Invalid Session"); + } + } + + private void checkTopic(Destination topic) throws InvalidDestinationException + { + if (topic == null) + { + throw new UnsupportedOperationException("Topic is null"); + } + if (!(topic instanceof Topic)) + { + throw new InvalidDestinationException("Destination " + topic + " is not a topic"); + } + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java b/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java index c776a9943e..dbc7b72813 100644 --- a/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java +++ b/java/client/src/main/java/org/apache/qpid/client/TopicSubscriberAdaptor.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.client; +import javax.jms.IllegalStateException; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; @@ -34,46 +35,54 @@ import javax.jms.TopicSubscriber; class TopicSubscriberAdaptor implements TopicSubscriber { private final Topic _topic; - private final MessageConsumer _consumer; + private final BasicMessageConsumer _consumer; private final boolean _noLocal; - TopicSubscriberAdaptor(Topic topic, MessageConsumer consumer, boolean noLocal) + TopicSubscriberAdaptor(Topic topic, BasicMessageConsumer consumer, boolean noLocal) { _topic = topic; _consumer = consumer; _noLocal = noLocal; } + TopicSubscriberAdaptor(Topic topic, BasicMessageConsumer consumer) { this(topic, consumer, consumer.isNoLocal()); } + public Topic getTopic() throws JMSException { + checkPreConditions(); return _topic; } public boolean getNoLocal() throws JMSException { + checkPreConditions(); return _noLocal; } public String getMessageSelector() throws JMSException { + checkPreConditions(); return _consumer.getMessageSelector(); } public MessageListener getMessageListener() throws JMSException { + checkPreConditions(); return _consumer.getMessageListener(); } public void setMessageListener(MessageListener messageListener) throws JMSException { + checkPreConditions(); _consumer.setMessageListener(messageListener); } public Message receive() throws JMSException { + checkPreConditions(); return _consumer.receive(); } @@ -84,6 +93,7 @@ class TopicSubscriberAdaptor implements TopicSubscriber public Message receiveNoWait() throws JMSException { + checkPreConditions(); return _consumer.receiveNoWait(); } @@ -91,4 +101,28 @@ class TopicSubscriberAdaptor implements TopicSubscriber { _consumer.close(); } + + private void checkPreConditions() throws javax.jms.IllegalStateException{ + BasicMessageConsumer msgConsumer = (BasicMessageConsumer)_consumer; + + if (msgConsumer.isClosed() ){ + throw new javax.jms.IllegalStateException("Consumer is closed"); + } + + if(_topic == null){ + throw new UnsupportedOperationException("Topic is null"); + } + + AMQSession session = msgConsumer.getSession(); + + if(session == null || session.isClosed()){ + throw new javax.jms.IllegalStateException("Invalid Session"); + } + } + + BasicMessageConsumer getMessageConsumer() + { + return _consumer; + } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java index 2bd93f1508..fd2968cdfd 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java @@ -23,6 +23,7 @@ package org.apache.qpid.client.handler; import org.apache.log4j.Logger; import org.apache.qpid.AMQChannelClosedException; import org.apache.qpid.AMQException; +import org.apache.qpid.AMQInvalidSelectorException; import org.apache.qpid.client.AMQNoConsumersException; import org.apache.qpid.client.AMQNoRouteException; import org.apache.qpid.protocol.AMQConstant; @@ -46,7 +47,7 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException { - _logger.debug("ChannelClose method received"); + _logger.debug("ChannelClose method received"); ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); int errorCode = method.replyCode; @@ -65,17 +66,21 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener { throw new AMQNoConsumersException("Error: " + reason, null); } + else if (errorCode == AMQConstant.NO_ROUTE.getCode()) + { + throw new AMQNoRouteException("Error: " + reason, null); + } + else if (errorCode == AMQConstant.INVALID_SELECTOR.getCode()) + { + _logger.info("Broker responded with Invalid Selector."); + + throw new AMQInvalidSelectorException(reason); + } else { - if (errorCode == AMQConstant.NO_ROUTE.getCode()) - { - throw new AMQNoRouteException("Error: " + reason, null); - } - else - { - throw new AMQChannelClosedException(errorCode, "Error: " + reason); - } + throw new AMQChannelClosedException(errorCode, "Error: " + reason); } + } evt.getProtocolSession().channelClosed(evt.getChannelId(), errorCode, reason); } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java index dd9fd651c1..e812f41f4c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java @@ -23,6 +23,7 @@ package org.apache.qpid.client.handler; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.AMQConnectionClosedException; +import org.apache.qpid.AMQInvalidSelectorException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.client.protocol.AMQMethodEvent; import org.apache.qpid.client.state.AMQState; diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java new file mode 100644 index 0000000000..858726745e --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed 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.client.handler; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.protocol.AMQMethodEvent; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.ExchangeBoundOkBody; + +/** + * @author Apache Software Foundation + */ +public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ExchangeBoundOkMethodHandler.class); + private static final ExchangeBoundOkMethodHandler _instance = new ExchangeBoundOkMethodHandler(); + + public static ExchangeBoundOkMethodHandler getInstance() + { + return _instance; + } + + private ExchangeBoundOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + if (_logger.isDebugEnabled()) + { + ExchangeBoundOkBody body = (ExchangeBoundOkBody) evt.getMethod(); + _logger.debug("Received Exchange.Bound-Ok message, response code: " + body.replyCode + " text: " + + body.replyText); + } + } +} + diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java new file mode 100644 index 0000000000..3271a715a2 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed 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.client.handler; + +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.protocol.AMQMethodEvent; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.QueueDeleteOkBody; +import org.apache.log4j.Logger; + +/** + * @author Apache Software Foundation + */ +public class QueueDeleteOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(QueueDeleteOkMethodHandler.class); + private static final QueueDeleteOkMethodHandler _instance = new QueueDeleteOkMethodHandler(); + + public static QueueDeleteOkMethodHandler getInstance() + { + return _instance; + } + + private QueueDeleteOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + if (_logger.isDebugEnabled()) + { + QueueDeleteOkBody body = (QueueDeleteOkBody) evt.getMethod(); + _logger.debug("Received Queue.Delete-Ok message, message count: " + body.messageCount); + } + } +} + diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java index edabed90b3..dd82eb13c1 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessage.java @@ -7,9 +7,9 @@ * 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 @@ -23,6 +23,8 @@ package org.apache.qpid.client.message; import org.apache.qpid.framing.ContentHeaderProperties; import org.apache.qpid.client.AMQSession; +import javax.jms.JMSException; + public class AMQMessage { protected ContentHeaderProperties _contentHeaderProperties; @@ -67,5 +69,13 @@ public class AMQMessage public long getDeliveryTag() { return _deliveryTag; - } + } + + /** + * Invoked prior to sending the message. Allows the message to be modified if necessary before + * sending. + */ + public void prepareForSending() throws JMSException + { + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java new file mode 100644 index 0000000000..6935cde491 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java @@ -0,0 +1,143 @@ +/* + * + * 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.client.message; + +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; + +import javax.jms.JMSException; +import javax.jms.MessageEOFException; +import java.io.IOException; +import java.nio.charset.Charset; + +/** + * @author Apache Software Foundation + */ +public abstract class AbstractBytesMessage extends AbstractJMSMessage +{ + + /** + * The default initial size of the buffer. The buffer expands automatically. + */ + private static final int DEFAULT_BUFFER_INITIAL_SIZE = 1024; + + AbstractBytesMessage() + { + this(null); + } + + /** + * Construct a bytes message with existing data. + * + * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is + * set to auto expand + */ + AbstractBytesMessage(ByteBuffer data) + { + super(data); // this instanties a content header + getJmsContentHeaderProperties().setContentType(getMimeType()); + + if (_data == null) + { + allocateInitialBuffer(); + } + } + + private void allocateInitialBuffer() + { + _data = ByteBuffer.allocate(DEFAULT_BUFFER_INITIAL_SIZE); + _data.setAutoExpand(true); + } + + AbstractBytesMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data) + throws AMQException + { + // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea + super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, data); + getJmsContentHeaderProperties().setContentType(getMimeType()); + } + + public void clearBodyImpl() throws JMSException + { + allocateInitialBuffer(); + } + + public String toBodyString() throws JMSException + { + checkReadable(); + try + { + return getText(); + } + catch (IOException e) + { + throw new JMSException(e.toString()); + } + } + + /** + * We reset the stream before and after reading the data. This means that toString() will always output + * the entire message and also that the caller can then immediately start reading as if toString() had + * never been called. + * + * @return + * @throws IOException + */ + private String getText() throws IOException + { + // this will use the default platform encoding + if (_data == null) + { + return null; + } + int pos = _data.position(); + _data.rewind(); + // one byte left is for the end of frame marker + if (_data.remaining() == 0) + { + // this is really redundant since pos must be zero + _data.position(pos); + return null; + } + else + { + String data = _data.getString(Charset.forName("UTF8").newDecoder()); + _data.position(pos); + return data; + } + } + + /** + * Check that there is at least a certain number of bytes available to read + * + * @param len the number of bytes + * @throws javax.jms.MessageEOFException if there are less than len bytes available to read + */ + protected void checkAvailable(int len) throws MessageEOFException + { + if (_data.remaining() < len) + { + throw new MessageEOFException("Unable to read " + len + " bytes"); + } + } +} 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 aaf0320afb..75e84fee96 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 @@ -7,9 +7,9 @@ * 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 @@ -23,24 +23,27 @@ package org.apache.qpid.client.message; import org.apache.commons.collections.map.ReferenceMap; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; +import org.apache.qpid.url.BindingURL; +import org.apache.qpid.url.AMQBindingURL; +import org.apache.qpid.url.URLSyntaxException; import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQTopic; import org.apache.qpid.client.JmsNotImplementedException; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; +import org.apache.qpid.framing.JMSPropertyFieldTable; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageNotReadableException; import javax.jms.MessageNotWriteableException; +import javax.jms.MessageFormatException; import java.util.Collections; import java.util.Enumeration; -import java.util.Iterator; import java.util.Map; -public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms.Message +public abstract class AbstractJMSMessage extends AMQMessage implements org.apache.qpid.jms.Message { private static final Map _destinationCache = Collections.synchronizedMap(new ReferenceMap()); @@ -49,7 +52,8 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms protected ByteBuffer _data; private boolean _readableProperties = false; private boolean _readableMessage = false; - + private Destination _destination; + protected AbstractJMSMessage(ByteBuffer data) { super(new BasicContentHeaderProperties()); @@ -58,8 +62,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms { _data.acquire(); } - // ContentHeaderProperties are just created and so are empty - //_readableProperties = (_contentHeaderProperties != null); + _readableProperties = false; _readableMessage = (data != null); } @@ -137,19 +140,16 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms Destination dest = (Destination) _destinationCache.get(replyToEncoding); if (dest == null) { - char destType = replyToEncoding.charAt(0); - if (destType == 'Q') - { - dest = new AMQQueue(replyToEncoding.substring(1)); - } - else if (destType == 'T') + try { - dest = new AMQTopic(replyToEncoding.substring(1)); + BindingURL binding = new AMQBindingURL(replyToEncoding); + dest = AMQDestination.createDestination(binding); } - else + catch (URLSyntaxException e) { throw new JMSException("Illegal value in JMS_ReplyTo property: " + replyToEncoding); } + _destinationCache.put(replyToEncoding, dest); } return dest; @@ -164,7 +164,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms } if (!(destination instanceof AMQDestination)) { - throw new IllegalArgumentException("ReplyTo destination my be an AMQ destination - passed argument was type " + + throw new IllegalArgumentException("ReplyTo destination may only be an AMQDestination - passed argument was type " + destination.getClass()); } final AMQDestination amqd = (AMQDestination) destination; @@ -177,12 +177,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public Destination getJMSDestination() throws JMSException { // TODO: implement this once we have sorted out how to figure out the exchange class - throw new JmsNotImplementedException(); + return _destination; } public void setJMSDestination(Destination destination) throws JMSException { - throw new JmsNotImplementedException(); + _destination = destination; } public int getJMSDeliveryMode() throws JMSException @@ -207,14 +207,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public String getJMSType() throws JMSException { - //fixme wrong QPID-152 - return getMimeType(); + return getJmsContentHeaderProperties().getType(); } 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 + getJmsContentHeaderProperties().setType(string); } public long getJMSExpiration() throws JMSException @@ -239,7 +237,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public void clearProperties() throws JMSException { - getJmsContentHeaderProperties().getHeaders().clear(); + getJmsContentHeaderProperties().getJMSHeaders().clear(); _readableProperties = false; } @@ -254,150 +252,163 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms public boolean propertyExists(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().propertyExists(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().propertyExists(propertyName); } public boolean getBooleanProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - if (getJmsContentHeaderProperties() == null) - { - System.out.println("HEADERS ARE NULL"); - } - - - return getJmsContentHeaderProperties().getHeaders().getBoolean(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getBoolean(propertyName); } public byte getByteProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getByte(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getByte(propertyName); } public short getShortProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getShort(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getShort(propertyName); } public int getIntProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getInteger(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getInteger(propertyName); } public long getLongProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getLong(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getLong(propertyName); } public float getFloatProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getFloat(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getFloat(propertyName); } public double getDoubleProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getDouble(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getDouble(propertyName); } public String getStringProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getString(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getString(propertyName); } public Object getObjectProperty(String propertyName) throws JMSException { checkPropertyName(propertyName); - return getJmsContentHeaderProperties().getHeaders().getObject(propertyName); + return getJmsContentHeaderProperties().getJMSHeaders().getObject(propertyName); } public Enumeration getPropertyNames() throws JMSException { - return getJmsContentHeaderProperties().getHeaders().getPropertyNames(); + return getJmsContentHeaderProperties().getJMSHeaders().getPropertyNames(); } public void setBooleanProperty(String propertyName, boolean b) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setBoolean(propertyName, b); + getJmsContentHeaderProperties().getJMSHeaders().setBoolean(propertyName, b); } public void setByteProperty(String propertyName, byte b) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setByte(propertyName, new Byte(b)); + getJmsContentHeaderProperties().getJMSHeaders().setByte(propertyName, new Byte(b)); } public void setShortProperty(String propertyName, short i) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setShort(propertyName, new Short(i)); + getJmsContentHeaderProperties().getJMSHeaders().setShort(propertyName, new Short(i)); } public void setIntProperty(String propertyName, int i) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setInteger(propertyName, new Integer(i)); + getJmsContentHeaderProperties().getJMSHeaders().setInteger(propertyName, new Integer(i)); } public void setLongProperty(String propertyName, long l) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setLong(propertyName, new Long(l)); + getJmsContentHeaderProperties().getJMSHeaders().setLong(propertyName, new Long(l)); } public void setFloatProperty(String propertyName, float f) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setFloat(propertyName, new Float(f)); + getJmsContentHeaderProperties().getJMSHeaders().setFloat(propertyName, new Float(f)); } public void setDoubleProperty(String propertyName, double v) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setDouble(propertyName, new Double(v)); + getJmsContentHeaderProperties().getJMSHeaders().setDouble(propertyName, new Double(v)); } public void setStringProperty(String propertyName, String value) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setString(propertyName, value); + getJmsContentHeaderProperties().getJMSHeaders().setString(propertyName, value); } public void setObjectProperty(String propertyName, Object object) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().setObject(propertyName, object); + getJmsContentHeaderProperties().getJMSHeaders().setObject(propertyName, object); } - public void acknowledge() throws JMSException + protected void removeProperty(String propertyName) throws JMSException + { + checkPropertyName(propertyName); + getJmsContentHeaderProperties().getJMSHeaders().remove(propertyName); + } + + public void acknowledgeThis() throws JMSException { // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge // is not specified. In our case, we only set the session field where client acknowledge mode is specified. if (_session != null) { + if (_session.getAMQConnection().isClosed()) + { + throw new javax.jms.IllegalStateException("Connection is already closed"); + } + // we set multiple to true here since acknowledgement implies acknowledge of all previous messages // received on the session _session.acknowledgeMessage(_deliveryTag, true); } } + public void acknowledge() throws JMSException + { + if(_session != null) + { + _session.acknowledge(); + } + } + /** * This forces concrete classes to implement clearBody() @@ -425,23 +436,15 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms buf.append("\nJMS priority: ").append(getJMSPriority()); buf.append("\nJMS delivery mode: ").append(getJMSDeliveryMode()); buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo())); - buf.append("\nJMS Type: ").append(String.valueOf(getJMSType())); - buf.append("\nJMS CorrelationID: ").append(String.valueOf(getJMSCorrelationID())); - buf.append("\nJMS Destination: NOT IMPLEMENTED");//.append(String.valueOf(getJMSDestination())); - buf.append("\nJMS MessageID: ").append(String.valueOf(getJMSMessageID())); - buf.append("\nJMS Redelivered: ").append(String.valueOf(getJMSRedelivered())); - buf.append("\nProperty Names: ").append(String.valueOf(getPropertyNames())); - buf.append("\nAMQ message number: ").append(_deliveryTag); - buf.append("\nProperties:"); - if (getJmsContentHeaderProperties().getHeaders().isEmpty()) + if (getJmsContentHeaderProperties().getJMSHeaders().isEmpty()) { buf.append("<NONE>"); } else { - buf.append('\n').append(getJmsContentHeaderProperties().getHeaders()); + buf.append('\n').append(getJmsContentHeaderProperties().getJMSHeaders()); } return buf.toString(); } @@ -471,34 +474,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms { throw new IllegalArgumentException("Property name must not be the empty string"); } - - // Call to ensure that the it has been set. - getJmsContentHeaderProperties().getHeaders(); - } - - public FieldTable populateHeadersFromMessageProperties() - { - // - // We need to convert every property into a String representation - // Note that type information is preserved in the property name - // - final FieldTable table = FieldTableFactory.newFieldTable(); - 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) - { - continue; - } - else - { - table.put(propertyName, entry.getValue().toString()); - } - } - return table; - } public BasicContentHeaderProperties getJmsContentHeaderProperties() @@ -512,7 +487,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms // position beyond the start if (_data != null) { - _data.rewind(); + reset(); } return _data; } @@ -551,9 +526,16 @@ public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms return !_readableMessage; } - public void reset() throws JMSException + public void reset() { - _readableMessage = true; + if (_readableMessage) + { + _data.rewind(); + } + else + { + _data.flip(); + _readableMessage = true; + } } - } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java index 6e1958e40a..debabfd559 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java @@ -7,9 +7,9 @@ * 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 @@ -20,29 +20,24 @@ */ package org.apache.qpid.client.message; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.AMQException; import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.ContentHeaderBody; +import javax.jms.BytesMessage; import javax.jms.JMSException; -import javax.jms.MessageNotReadableException; -import javax.jms.MessageNotWriteableException; +import javax.jms.MessageFormatException; import javax.jms.MessageEOFException; -import java.io.*; -import java.nio.charset.Charset; import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CharsetDecoder; +import java.nio.CharBuffer; -public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.BytesMessage +public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessage { private static final String MIME_TYPE = "application/octet-stream"; - - /** - * The default initial size of the buffer. The buffer expands automatically. - */ - private static final int DEFAULT_BUFFER_INITIAL_SIZE = 1024; - JMSBytesMessage() { this(null); @@ -57,71 +52,12 @@ public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.Byt JMSBytesMessage(ByteBuffer data) { super(data); // this instanties a content header - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - - if (_data == null) - { - _data = ByteBuffer.allocate(DEFAULT_BUFFER_INITIAL_SIZE); - _data.setAutoExpand(true); - } } JMSBytesMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data) throws AMQException { - // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea - super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, data); - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - } - - public void clearBodyImpl() throws JMSException - { - _data.clear(); - } - - public String toBodyString() throws JMSException - { - checkReadable(); - try - { - return getText(); - } - catch (IOException e) - { - throw new JMSException(e.toString()); - } - } - - /** - * We reset the stream before and after reading the data. This means that toString() will always output - * the entire message and also that the caller can then immediately start reading as if toString() had - * never been called. - * - * @return - * @throws IOException - */ - private String getText() throws IOException - { - // this will use the default platform encoding - if (_data == null) - { - return null; - } - int pos = _data.position(); - _data.rewind(); - // one byte left is for the end of frame marker - if (_data.remaining() == 0) - { - // this is really redundant since pos must be zero - _data.position(pos); - return null; - } - else - { - String data = _data.getString(Charset.forName("UTF8").newDecoder()); - _data.position(pos); - return data; - } + super(messageNbr, contentHeader, data); } public String getMimeType() @@ -135,21 +71,6 @@ public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.Byt return _data.limit(); } - - /** - * Check that there is at least a certain number of bytes available to read - * - * @param len the number of bytes - * @throws MessageEOFException if there are less than len bytes available to read - */ - private void checkAvailable(int len) throws MessageEOFException - { - if (_data.remaining() < len) - { - throw new MessageEOFException("Unable to read " + len + " bytes"); - } - } - public boolean readBoolean() throws JMSException { checkReadable(); @@ -231,10 +152,27 @@ public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.Byt checkReadable(); // we check only for one byte since theoretically the string could be only a // single byte when using UTF-8 encoding - checkAvailable(1); + try { - return _data.getString(Charset.forName("UTF-8").newDecoder()); + short length = readShort(); + if(length == 0) + { + return ""; + } + else + { + CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); + ByteBuffer encodedString = _data.slice(); + encodedString.limit(length); + _data.position(_data.position()+length); + CharBuffer string = decoder.decode(encodedString.buf()); + + return string.toString(); + } + + + } catch (CharacterCodingException e) { @@ -339,7 +277,15 @@ public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.Byt checkWritable(); try { - _data.putString(string, Charset.forName("UTF-8").newEncoder()); + CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder(); + java.nio.ByteBuffer encodedString = encoder.encode(CharBuffer.wrap(string)); + + _data.putShort((short)encodedString.limit()); + _data.put(encodedString); + + //_data.putString(string, Charset.forName("UTF-8").newEncoder()); + // we must add the null terminator manually + //_data.put((byte)0); } catch (CharacterCodingException e) { @@ -368,13 +314,51 @@ public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.Byt { throw new NullPointerException("Argument must not be null"); } - _data.putObject(object); - } - - public void reset() throws JMSException - { - super.reset(); - _data.flip(); + Class clazz = object.getClass(); + if (clazz == Byte.class) + { + writeByte((Byte) object); + } + else if (clazz == Boolean.class) + { + writeBoolean((Boolean) object); + } + else if (clazz == byte[].class) + { + writeBytes((byte[]) object); + } + else if (clazz == Short.class) + { + writeShort((Short) object); + } + else if (clazz == Character.class) + { + writeChar((Character) object); + } + else if (clazz == Integer.class) + { + writeInt((Integer) object); + } + else if (clazz == Long.class) + { + writeLong((Long) object); + } + else if (clazz == Float.class) + { + writeFloat((Float) object); + } + else if (clazz == Double.class) + { + writeDouble((Double) object); + } + else if (clazz == String.class) + { + writeUTF((String) object); + } + else + { + throw new MessageFormatException("Only primitives plus byte arrays and String are valid types"); + } } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java index 5282dce4c9..f69bed0fc0 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessage.java @@ -21,65 +21,75 @@ package org.apache.qpid.client.message; import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.PropertyFieldTable; import org.apache.qpid.framing.FieldTableFactory; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.EncodingUtils; +import org.apache.qpid.framing.JMSPropertyFieldTable; +import org.apache.qpid.framing.AMQFrameDecodingException; import org.apache.qpid.AMQException; +import org.apache.log4j.Logger; import javax.jms.JMSException; +import javax.jms.MessageFormatException; import java.util.Enumeration; -public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessage +public class JMSMapMessage extends JMSBytesMessage implements javax.jms.MapMessage { + private static final Logger _logger = Logger.getLogger(JMSMapMessage.class); + public static final String MIME_TYPE = "jms/map-message"; - private PropertyFieldTable _map; + private JMSPropertyFieldTable _properties; JMSMapMessage() throws JMSException { - this(null, null); + this(null); } - JMSMapMessage(ByteBuffer data, String encoding) throws JMSException + JMSMapMessage(ByteBuffer data) throws JMSException { super(data); // this instantiates a content header - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - getJmsContentHeaderProperties().setEncoding(encoding); - _map = new PropertyFieldTable(); + _properties = new JMSPropertyFieldTable(); } - - JMSMapMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, ByteBuffer data) + JMSMapMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data) throws AMQException { - super(deliveryTag, contentHeader, data); - contentHeader.setContentType(MIME_TYPE); + super(messageNbr, contentHeader, data); - try + if (data != null) { - _map = FieldTableFactory.newFieldTable(getText()); + + long tableSize = EncodingUtils.readInteger(_data); + try + { + _properties = new JMSPropertyFieldTable(_data, tableSize); + } + catch (JMSException e) + { + Exception error = e.getLinkedException(); + if (error instanceof AMQFrameDecodingException) + { + throw(AMQFrameDecodingException) error; + } + else + { + throw new AMQException(e.getMessage(), e); + } + } } - catch (JMSException e) + else { - throw new AMQException(e.getMessage(), e); + _properties = new JMSPropertyFieldTable(); } } - // AbstractJMSMessage Interface - - public void clearBodyImpl() throws JMSException - { - if (_data != null) - { - _data.release(); - } - _data = null; - } public String toBodyString() throws JMSException { - return _map.toString(); + return _properties.toString(); } public String getMimeType() @@ -87,175 +97,143 @@ public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessag return MIME_TYPE; } - // MapMessage Interface - public boolean getBoolean(String string) throws JMSException + public ByteBuffer getData() { - Boolean b = _map.getBoolean(string); + //What if _data is null? + _properties.writeToBuffer(_data); + return super.getData(); + } - if (b == null) - { - b = Boolean.valueOf(_map.getString(string)); - } + @Override + public void clearBodyImpl() throws JMSException + { + super.clearBodyImpl(); + _properties.clear(); + } - return b; + public boolean getBoolean(String string) throws JMSException + { + return _properties.getBoolean(string); } public byte getByte(String string) throws JMSException { - Byte b = _map.getByte(string); - if (b == null) - { - b = Byte.valueOf(_map.getString(string)); - } - return b; + return _properties.getByte(string); } public short getShort(String string) throws JMSException { - Short s = _map.getShort(string); - - if (s == null) - { - s = Short.valueOf(getByte(string)); - } - - return s; + return _properties.getShort(string); } public char getChar(String string) throws JMSException { - return _map.getCharacter(string); - } + Character result = _properties.getCharacter(string); - public int getInt(String string) throws JMSException - { - Integer i = _map.getInteger(string); - - if (i == null) + if (result == null) + { + throw new NullPointerException("getChar couldn't find " + string + " item."); + } + else { - i = Integer.valueOf(getShort(string)); + return result; } + } - return i; + public int getInt(String string) throws JMSException + { + return _properties.getInteger(string); } public long getLong(String string) throws JMSException { - Long l = _map.getLong(string); - - if (l == null) - { - l = Long.valueOf(getInt(string)); - } - - return l; + return _properties.getLong(string); } public float getFloat(String string) throws JMSException { - Float f = _map.getFloat(string); - - if (f == null) - { - f = Float.valueOf(_map.getString(string)); - } - - return f; + return _properties.getFloat(string); } public double getDouble(String string) throws JMSException { - Double d = _map.getDouble(string); - - if (d == null) - { - d = Double.valueOf(getFloat(string)); - } - - return d; + return _properties.getDouble(string); } public String getString(String string) throws JMSException { - String s = _map.getString(string); - - if (s == null) - { - Object o = _map.getObject(string); - s = o.toString(); - } - - return s; + return _properties.getString(string); } public byte[] getBytes(String string) throws JMSException { - return _map.getBytes(string); + return _properties.getBytes(string); } public Object getObject(String string) throws JMSException { - return _map.getObject(string); + return _properties.getObject(string); } public Enumeration getMapNames() throws JMSException { - return _map.getPropertyNames(); + return _properties.getMapNames(); } + public void setBoolean(String string, boolean b) throws JMSException { checkWritable(); - _map.setBoolean(string, b); + _properties.setBoolean(string, b); } public void setByte(String string, byte b) throws JMSException { checkWritable(); - _map.setByte(string, b); + _properties.setByte(string, b); } public void setShort(String string, short i) throws JMSException { checkWritable(); - _map.setShort(string, i); + _properties.setShort(string, i); } public void setChar(String string, char c) throws JMSException { checkWritable(); - _map.setChar(string, c); + _properties.setChar(string, c); } public void setInt(String string, int i) throws JMSException { checkWritable(); - _map.setInteger(string, i); + _properties.setInteger(string, i); } public void setLong(String string, long l) throws JMSException { checkWritable(); - _map.setLong(string, l); + _properties.setLong(string, l); } public void setFloat(String string, float v) throws JMSException { checkWritable(); - _map.setFloat(string, v); + _properties.setFloat(string, v); } public void setDouble(String string, double v) throws JMSException { checkWritable(); - _map.setDouble(string, v); + _properties.setDouble(string, v); } public void setString(String string, String string1) throws JMSException { checkWritable(); - _map.setString(string, string1); + _properties.setString(string, string1); } public void setBytes(String string, byte[] bytes) throws JMSException @@ -266,35 +244,18 @@ public class JMSMapMessage extends JMSTextMessage implements javax.jms.MapMessag public void setBytes(String string, byte[] bytes, int i, int i1) throws JMSException { checkWritable(); - _map.setBytes(string, bytes, i, i1); + _properties.setBytes(string, bytes, i, i1); } public void setObject(String string, Object object) throws JMSException { checkWritable(); - _map.setObject(string, object); + _properties.setObject(string, object); } public boolean itemExists(String string) throws JMSException { - return _map.itemExists(string); - } - - public ByteBuffer getData() - { - - try - { - setText(toString()); - return super.getData(); - } - catch (JMSException e) - { - // should never occur according to setText - //fixme -- what to do if it does occur. - } - - return ByteBuffer.allocate(0); + return _properties.itemExists(string); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java index 8d17f2bbf0..38b8b67ff9 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSMapMessageFactory.java @@ -36,6 +36,6 @@ public class JMSMapMessageFactory extends AbstractJMSMessageFactory protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader) throws AMQException { - return new JMSMapMessage(deliveryTag, (BasicContentHeaderProperties) contentHeader.properties, data); + return new JMSMapMessage(deliveryTag, contentHeader, data); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java index 61f326d52b..4fb070d2ff 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java @@ -7,9 +7,9 @@ * 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 @@ -20,18 +20,17 @@ */ package org.apache.qpid.client.message; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.AMQException; import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; -import javax.jms.ObjectMessage; import javax.jms.JMSException; import javax.jms.MessageFormatException; -import javax.jms.MessageNotWriteableException; +import javax.jms.ObjectMessage; import java.io.*; -import java.nio.charset.Charset; import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage { @@ -73,6 +72,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag _data.release(); } _data = null; + } public String toBodyString() throws JMSException @@ -94,18 +94,23 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); _data.setAutoExpand(true); } + else + { + _data.rewind(); + } + try { ObjectOutputStream out = new ObjectOutputStream(_data.asOutputStream()); out.writeObject(serializable); out.flush(); out.close(); - _data.rewind(); } catch (IOException e) { throw new MessageFormatException("Message not serializable: " + e); } + } public Serializable getObject() throws JMSException @@ -118,15 +123,18 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag try { + _data.rewind(); in = new ObjectInputStream(_data.asInputStream()); return (Serializable) in.readObject(); } catch (IOException e) - { - throw new MessageFormatException("Could not deserialize message: " + e); + { + e.printStackTrace(); + throw new MessageFormatException("Could not deserialize message: " + e); } catch (ClassNotFoundException e) { + e.printStackTrace(); throw new MessageFormatException("Could not deserialize message: " + e); } finally diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java new file mode 100644 index 0000000000..c2dfdc1b65 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java @@ -0,0 +1,785 @@ +/* + * + * 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.client.message; + +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.ContentHeaderBody; + +import javax.jms.*; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; + +/** + * @author Apache Software Foundation + */ +public class JMSStreamMessage extends AbstractBytesMessage implements StreamMessage +{ + public static final String MIME_TYPE="jms/stream-message"; + + private static final byte BOOLEAN_TYPE = (byte) 1; + + private static final byte BYTE_TYPE = (byte) 2; + + private static final byte BYTEARRAY_TYPE = (byte) 3; + + private static final byte SHORT_TYPE = (byte) 4; + + private static final byte CHAR_TYPE = (byte) 5; + + private static final byte INT_TYPE = (byte) 6; + + private static final byte LONG_TYPE = (byte) 7; + + private static final byte FLOAT_TYPE = (byte) 8; + + private static final byte DOUBLE_TYPE = (byte) 9; + + private static final byte STRING_TYPE = (byte) 10; + + private static final byte NULL_STRING_TYPE = (byte) 11; + + /** + * This is set when reading a byte array. The readBytes(byte[]) method supports multiple calls to read + * a byte array in multiple chunks, hence this is used to track how much is left to be read + */ + private int _byteArrayRemaining = -1; + + JMSStreamMessage() + { + this(null); + } + + /** + * Construct a stream message with existing data. + * + * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is + * set to auto expand + */ + JMSStreamMessage(ByteBuffer data) + { + super(data); // this instanties a content header + } + + + JMSStreamMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data) + throws AMQException + { + super(messageNbr, contentHeader, data); + } + + public String getMimeType() + { + return MIME_TYPE; + } + + private byte readWireType() throws MessageFormatException, MessageEOFException, + MessageNotReadableException + { + checkReadable(); + checkAvailable(1); + return _data.get(); + } + + private void writeTypeDiscriminator(byte type) throws MessageNotWriteableException + { + checkWritable(); + _data.put(type); + } + + public boolean readBoolean() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + boolean result; + try + { + switch (wireType) + { + case BOOLEAN_TYPE: + checkAvailable(1); + result = readBooleanImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Boolean.parseBoolean(readStringImpl()); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a boolean"); + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private boolean readBooleanImpl() + { + return _data.get() != 0; + } + + public byte readByte() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + byte result; + try + { + switch (wireType) + { + case BYTE_TYPE: + checkAvailable(1); + result = readByteImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Byte.parseByte(readStringImpl()); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a byte"); + } + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + return result; + } + + private byte readByteImpl() + { + return _data.get(); + } + + public short readShort() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + short result; + try + { + switch (wireType) + { + case SHORT_TYPE: + checkAvailable(2); + result = readShortImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Short.parseShort(readStringImpl()); + break; + case BYTE_TYPE: + checkAvailable(1); + result = readByteImpl(); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a short"); + } + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + return result; + } + + private short readShortImpl() + { + return _data.getShort(); + } + + /** + * Note that this method reads a unicode character as two bytes from the stream + * + * @return the character read from the stream + * @throws JMSException + */ + public char readChar() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + try + { + if(wireType == NULL_STRING_TYPE){ + throw new NullPointerException(); + } + + if (wireType != CHAR_TYPE) + { + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a char"); + } + else + { + checkAvailable(2); + return readCharImpl(); + } + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private char readCharImpl() + { + return _data.getChar(); + } + + public int readInt() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + int result; + try + { + switch (wireType) + { + case INT_TYPE: + checkAvailable(4); + result = readIntImpl(); + break; + case SHORT_TYPE: + checkAvailable(2); + result = readShortImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Integer.parseInt(readStringImpl()); + break; + case BYTE_TYPE: + checkAvailable(1); + result = readByteImpl(); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to an int"); + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private int readIntImpl() + { + return _data.getInt(); + } + + public long readLong() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + long result; + try + { + switch (wireType) + { + case LONG_TYPE: + checkAvailable(8); + result = readLongImpl(); + break; + case INT_TYPE: + checkAvailable(4); + result = readIntImpl(); + break; + case SHORT_TYPE: + checkAvailable(2); + result = readShortImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Long.parseLong(readStringImpl()); + break; + case BYTE_TYPE: + checkAvailable(1); + result = readByteImpl(); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a long"); + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private long readLongImpl() + { + return _data.getLong(); + } + + public float readFloat() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + float result; + try + { + switch (wireType) + { + case FLOAT_TYPE: + checkAvailable(4); + result = readFloatImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Float.parseFloat(readStringImpl()); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a float"); + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private float readFloatImpl() + { + return _data.getFloat(); + } + + public double readDouble() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + double result; + try + { + switch (wireType) + { + case DOUBLE_TYPE: + checkAvailable(8); + result = readDoubleImpl(); + break; + case FLOAT_TYPE: + checkAvailable(4); + result = readFloatImpl(); + break; + case STRING_TYPE: + checkAvailable(1); + result = Double.parseDouble(readStringImpl()); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a double"); + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private double readDoubleImpl() + { + return _data.getDouble(); + } + + public String readString() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + String result; + try + { + switch (wireType) + { + case STRING_TYPE: + checkAvailable(1); + result = readStringImpl(); + break; + case NULL_STRING_TYPE: + result = null; + throw new NullPointerException("data is null"); + case BOOLEAN_TYPE: + checkAvailable(1); + result = String.valueOf(readBooleanImpl()); + break; + case LONG_TYPE: + checkAvailable(8); + result = String.valueOf(readLongImpl()); + break; + case INT_TYPE: + checkAvailable(4); + result = String.valueOf(readIntImpl()); + break; + case SHORT_TYPE: + checkAvailable(2); + result = String.valueOf(readShortImpl()); + break; + case BYTE_TYPE: + checkAvailable(1); + result = String.valueOf(readByteImpl()); + break; + case FLOAT_TYPE: + checkAvailable(4); + result = String.valueOf(readFloatImpl()); + break; + case DOUBLE_TYPE: + checkAvailable(8); + result = String.valueOf(readDoubleImpl()); + break; + case CHAR_TYPE: + checkAvailable(2); + result = String.valueOf(readCharImpl()); + break; + default: + _data.position(position); + throw new MessageFormatException("Unable to convert " + wireType + " to a String"); + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + private String readStringImpl() throws JMSException + { + try + { + return _data.getString(Charset.forName("UTF-8").newDecoder()); + } + catch (CharacterCodingException e) + { + JMSException je = new JMSException("Error decoding byte stream as a UTF8 string: " + e); + je.setLinkedException(e); + throw je; + } + } + + public int readBytes(byte[] bytes) throws JMSException + { + if (bytes == null) + { + throw new IllegalArgumentException("byte array must not be null"); + } + checkReadable(); + // first call + if (_byteArrayRemaining == -1) + { + // type discriminator checked separately so you get a MessageFormatException rather than + // an EOF even in the case where both would be applicable + checkAvailable(1); + byte wireType = readWireType(); + if (wireType != BYTEARRAY_TYPE) + { + throw new MessageFormatException("Unable to convert " + wireType + " to a byte array"); + } + checkAvailable(4); + int size = _data.getInt(); + // size of -1 indicates null + if (size == -1) + { + return -1; + } + else + { + if (size > _data.remaining()) + { + throw new MessageEOFException("Byte array has stated size " + size + " but message only contains " + + _data.remaining() + " bytes"); + } + else + { + _byteArrayRemaining = size; + } + } + } + else if (_byteArrayRemaining == 0) + { + _byteArrayRemaining = -1; + return -1; + } + + int returnedSize = readBytesImpl(bytes); + if (returnedSize < bytes.length) + { + _byteArrayRemaining = -1; + } + return returnedSize; + } + + private int readBytesImpl(byte[] bytes) + { + int count = (_byteArrayRemaining >= bytes.length ? bytes.length : _byteArrayRemaining); + _byteArrayRemaining -= count; + + if (count == 0) + { + return 0; + } + else + { + _data.get(bytes, 0, count); + return count; + } + } + + public Object readObject() throws JMSException + { + int position = _data.position(); + byte wireType = readWireType(); + Object result = null; + try + { + switch (wireType) + { + case BOOLEAN_TYPE: + checkAvailable(1); + result = readBooleanImpl(); + break; + case BYTE_TYPE: + checkAvailable(1); + result = readByteImpl(); + break; + case BYTEARRAY_TYPE: + checkAvailable(4); + int size = _data.getInt(); + if (size == -1) + { + result = null; + } + else + { + _byteArrayRemaining = size; + result = new byte[size]; + readBytesImpl(new byte[size]); + } + break; + case SHORT_TYPE: + checkAvailable(2); + result = readShortImpl(); + break; + case CHAR_TYPE: + checkAvailable(2); + result = readCharImpl(); + break; + case INT_TYPE: + checkAvailable(4); + result = readIntImpl(); + break; + case LONG_TYPE: + checkAvailable(8); + result = readLongImpl(); + break; + case FLOAT_TYPE: + checkAvailable(4); + result = readFloatImpl(); + break; + case DOUBLE_TYPE: + checkAvailable(8); + result = readDoubleImpl(); + break; + case NULL_STRING_TYPE: + result = null; + break; + case STRING_TYPE: + checkAvailable(1); + result = readStringImpl(); + break; + } + return result; + } + catch (RuntimeException e) + { + _data.position(position); + throw e; + } + } + + public void writeBoolean(boolean b) throws JMSException + { + writeTypeDiscriminator(BOOLEAN_TYPE); + _data.put(b ? (byte) 1 : (byte) 0); + } + + public void writeByte(byte b) throws JMSException + { + writeTypeDiscriminator(BYTE_TYPE); + _data.put(b); + } + + public void writeShort(short i) throws JMSException + { + writeTypeDiscriminator(SHORT_TYPE); + _data.putShort(i); + } + + public void writeChar(char c) throws JMSException + { + writeTypeDiscriminator(CHAR_TYPE); + _data.putChar(c); + } + + public void writeInt(int i) throws JMSException + { + writeTypeDiscriminator(INT_TYPE); + _data.putInt(i); + } + + public void writeLong(long l) throws JMSException + { + writeTypeDiscriminator(LONG_TYPE); + _data.putLong(l); + } + + public void writeFloat(float v) throws JMSException + { + writeTypeDiscriminator(FLOAT_TYPE); + _data.putFloat(v); + } + + public void writeDouble(double v) throws JMSException + { + writeTypeDiscriminator(DOUBLE_TYPE); + _data.putDouble(v); + } + + public void writeString(String string) throws JMSException + { + if (string == null) + { + writeTypeDiscriminator(NULL_STRING_TYPE); + } + else + { + writeTypeDiscriminator(STRING_TYPE); + try + { + _data.putString(string, Charset.forName("UTF-8").newEncoder()); + // we must write the null terminator ourselves + _data.put((byte)0); + } + catch (CharacterCodingException e) + { + JMSException ex = new JMSException("Unable to encode string: " + e); + ex.setLinkedException(e); + throw ex; + } + } + } + + public void writeBytes(byte[] bytes) throws JMSException + { + writeBytes(bytes, 0, bytes == null?0:bytes.length); + } + + public void writeBytes(byte[] bytes, int offset, int length) throws JMSException + { + writeTypeDiscriminator(BYTEARRAY_TYPE); + if (bytes == null) + { + _data.putInt(-1); + } + else + { + _data.putInt(length); + _data.put(bytes, offset, length); + } + } + + public void writeObject(Object object) throws JMSException + { + checkWritable(); + Class clazz = null; + if (object == null) + { + // string handles the output of null values + clazz = String.class; + } + else + { + clazz = object.getClass(); + } + + if (clazz == Byte.class) + { + writeByte((Byte) object); + } + else if (clazz == Boolean.class) + { + writeBoolean((Boolean) object); + } + else if (clazz == byte[].class) + { + writeBytes((byte[]) object); + } + else if (clazz == Short.class) + { + writeShort((Short) object); + } + else if (clazz == Character.class) + { + writeChar((Character) object); + } + else if (clazz == Integer.class) + { + writeInt((Integer) object); + } + else if (clazz == Long.class) + { + writeLong((Long) object); + } + else if (clazz == Float.class) + { + writeFloat((Float) object); + } + else if (clazz == Double.class) + { + writeDouble((Double) object); + } + else if (clazz == String.class) + { + writeString((String) object); + } + else + { + throw new MessageFormatException("Only primitives plus byte arrays and String are valid types"); + } + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java new file mode 100644 index 0000000000..aae9f0cdb2 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessageFactory.java @@ -0,0 +1,41 @@ +/* + * + * 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.client.message; + +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.AMQException; + +import javax.jms.JMSException; + +public class JMSStreamMessageFactory extends AbstractJMSMessageFactory +{ + protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader) throws + AMQException + { + return new JMSStreamMessage(deliveryTag, contentHeader, data); + } + + public AbstractJMSMessage createMessage() throws JMSException + { + return new JMSStreamMessage(); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java index 3061d5a59c..76f8a1c32f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java @@ -7,9 +7,9 @@ * 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 @@ -35,6 +35,11 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text private String _decodedValue; + /** + * This constant represents the name of a property that is set when the message payload is null. + */ + private static final String PAYLOAD_NULL_PROPERTY = "JMS_QPID_NULL"; + JMSTextMessage() throws JMSException { this(null, null); @@ -91,31 +96,34 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text return MIME_TYPE; } - public void setText(String string) throws JMSException + public void setText(String text) throws JMSException { checkWritable(); - + clearBody(); try { - _data = ByteBuffer.allocate(string.length()); - _data.limit(string.length()); - //_data.sweep(); - _data.setAutoExpand(true); - if (getJmsContentHeaderProperties().getEncoding() == null) - { - _data.put(string.getBytes()); - } - else - { - _data.put(string.getBytes(getJmsContentHeaderProperties().getEncoding())); + if (text != null) + { + _data = ByteBuffer.allocate(text.length()); + _data.limit(text.length()) ; + //_data.sweep(); + _data.setAutoExpand(true); + if (getJmsContentHeaderProperties().getEncoding() == null) + { + _data.put(text.getBytes()); + } + else + { + _data.put(text.getBytes(getJmsContentHeaderProperties().getEncoding())); + } } - _decodedValue = string; + _decodedValue = text; } catch (UnsupportedEncodingException e) { // should never occur - JMSException jmse = new JMSException("Unable to decode string data"); + JMSException jmse = new JMSException("Unable to decode text data"); jmse.setLinkedException(e); } } @@ -133,6 +141,11 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text else { _data.rewind(); + + if (propertyExists(PAYLOAD_NULL_PROPERTY) && getBooleanProperty(PAYLOAD_NULL_PROPERTY)) + { + return null; + } if (getJmsContentHeaderProperties().getEncoding() != null) { try @@ -162,4 +175,18 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text return _decodedValue; } } + + @Override + public void prepareForSending() throws JMSException + { + super.prepareForSending(); + if (_data == null) + { + setBooleanProperty(PAYLOAD_NULL_PROPERTY, true); + } + else + { + removeProperty(PAYLOAD_NULL_PROPERTY); + } + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java index 31c9c2ed91..348988f06d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java @@ -103,6 +103,7 @@ public class MessageFactoryRegistry mf.registerFactory("text/xml", new JMSTextMessageFactory()); mf.registerFactory("application/octet-stream", new JMSBytesMessageFactory()); mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory()); + mf.registerFactory(JMSStreamMessage.MIME_TYPE, new JMSStreamMessageFactory()); mf.registerFactory(null, new JMSBytesMessageFactory()); return mf; } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java b/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java index 492571b6af..87b8a4e925 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java @@ -65,7 +65,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener // we only update the flag from inside the synchronized block // so that the blockForFrame method cannot "miss" an update - it // will only ever read the flag from within the synchronized block - synchronized (_lock) + synchronized(_lock) { _doneEvt = evt; _ready = ready; @@ -88,7 +88,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener */ public AMQMethodEvent blockForFrame() throws AMQException { - synchronized (_lock) + synchronized(_lock) { while (!_ready) { @@ -106,11 +106,11 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener { if (_error instanceof AMQException) { - throw (AMQException)_error; + throw(AMQException) _error; } else { - throw new AMQException("Woken up due to exception", _error); // FIXME: This will wrap FailoverException and prevent it being caught. + throw new AMQException("Woken up due to " + _error.getClass(), _error); // FIXME: This will wrap FailoverException and prevent it being caught. } } @@ -120,6 +120,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener /** * This is a callback, called by the MINA dispatcher thread only. It is also called from within this * class to avoid code repetition but again is only called by the MINA dispatcher thread. + * * @param e */ public void error(Exception e) @@ -127,7 +128,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener // set the error so that the thread that is blocking (against blockForFrame()) // can pick up the exception and rethrow to the caller _error = e; - synchronized (_lock) + synchronized(_lock) { _ready = true; _lock.notify(); diff --git a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java index ab707bb51d..887850c06e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java @@ -7,9 +7,9 @@ * 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 @@ -104,6 +104,8 @@ public class AMQStateManager implements AMQMethodListener frame2handlerMap.put(BasicDeliverBody.class, BasicDeliverMethodHandler.getInstance()); frame2handlerMap.put(BasicReturnBody.class, BasicReturnMethodHandler.getInstance()); frame2handlerMap.put(ChannelFlowOkBody.class, ChannelFlowOkMethodHandler.getInstance()); + frame2handlerMap.put(QueueDeleteOkBody.class, QueueDeleteOkMethodHandler.getInstance()); + frame2handlerMap.put(ExchangeBoundOkBody.class, ExchangeBoundOkMethodHandler.getInstance()); _state2HandlersMap.put(AMQState.CONNECTION_OPEN, frame2handlerMap); } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java b/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java index 42ae5a7b17..18e1fdad82 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/StateWaiter.java @@ -46,7 +46,7 @@ public class StateWaiter implements StateListener public void waituntilStateHasChanged() throws AMQException { - synchronized (_monitor) + synchronized(_monitor) { // // The guard is required in case we are woken up by a spurious @@ -71,22 +71,22 @@ public class StateWaiter implements StateListener _logger.debug("Throwable reached state waiter: " + _throwable); if (_throwable instanceof AMQException) { - throw (AMQException) _throwable; + throw(AMQException) _throwable; } else { - throw new AMQException("Error: " + _throwable, _throwable); // FIXME: this will wrap FailoverException in throwable which will prevent it being caught. + throw new AMQException("Error: " + _throwable, _throwable); // FIXME: this will wrap FailoverException in throwable which will prevent it being caught. } } } public void stateChanged(AMQState oldState, AMQState newState) { - synchronized (_monitor) + synchronized(_monitor) { if (_logger.isDebugEnabled()) { - _logger.debug("stateChanged called"); + _logger.debug("stateChanged called changing from :" + oldState + " to :" + newState); } if (_state == newState) { @@ -103,7 +103,7 @@ public class StateWaiter implements StateListener public void error(Throwable t) { - synchronized (_monitor) + synchronized(_monitor) { if (_logger.isDebugEnabled()) { diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java index 78d937f453..2e47ed2666 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java @@ -60,6 +60,7 @@ public class SocketTransportConnection implements ITransportConnection // once more testing of the performance of the simple allocator has been done if (!Boolean.getBoolean("amqj.enablePooledAllocator")) { + _logger.warn("Using SimpleByteBufferAllocator"); ByteBuffer.setAllocator(new SimpleByteBufferAllocator()); } diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java index 58507a75ca..e9e23aefdb 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java @@ -268,7 +268,7 @@ public class TransportConnection Object[] params = {port}; provider = (IoHandlerAdapter) Class.forName(protocolProviderClass).getConstructor(cnstr).newInstance(params); //Give the broker a second to create - _logger.info("Created Instance"); + _logger.info("Created VMBroker Instance:" + port); } catch (Exception e) { diff --git a/java/client/src/main/java/org/apache/qpid/jms/Message.java b/java/client/src/main/java/org/apache/qpid/jms/Message.java new file mode 100644 index 0000000000..d73e51d755 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/jms/Message.java @@ -0,0 +1,28 @@ +/*
+ *
+ * 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 javax.jms.*;
+
+public interface Message extends javax.jms.Message
+{
+ public void acknowledgeThis() throws JMSException;
+}
diff --git a/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java b/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java index b0641350ad..7519a0f1a4 100644 --- a/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java +++ b/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java @@ -25,6 +25,7 @@ import org.apache.qpid.client.AMQConnectionFactory; import org.apache.qpid.client.AMQHeadersExchange; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQTopic; +import org.apache.qpid.client.AMQDestination; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.BindingURL; @@ -40,11 +41,15 @@ import javax.naming.spi.InitialContextFactory; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; +import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; public class PropertiesFileInitialContextFactory implements InitialContextFactory { - protected final Logger _logger = Logger.getLogger(getClass()); + protected final Logger _logger = Logger.getLogger(PropertiesFileInitialContextFactory.class); private String CONNECTION_FACTORY_PREFIX = "connectionfactory."; private String DESTINATION_PREFIX = "destination."; @@ -55,6 +60,41 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor { Map data = new ConcurrentHashMap(); + try + { + + String file = null; + if (environment.contains(Context.PROVIDER_URL)) + { + file = (String) environment.get(Context.PROVIDER_URL); + } + else + { + file = System.getProperty(Context.PROVIDER_URL); + } + + if (file != null) + { + _logger.info("Loading Properties from:" + file); + //Load the properties specified + Properties p = new Properties(); + + p.load(new BufferedInputStream(new FileInputStream(file))); + + environment.putAll(p); + _logger.info("Loaded Context Properties:" + environment.toString()); + } + else + { + _logger.warn("No Provider URL specified."); + } + } + catch (IOException ioe) + { + _logger.warn("Unable to load property file specified in Provider_URL:" + + environment.get(Context.PROVIDER_URL)); + } + createConnectionFactories(data, environment); createDestinations(data, environment); @@ -177,21 +217,15 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor return null; } - if (binding.getExchangeClass().equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS)) - { - return createTopic(binding); - } - else if (binding.getExchangeClass().equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS)) + try { - return createQueue(binding); + return AMQDestination.createDestination(binding); } - else if (binding.getExchangeClass().equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS)) + catch (IllegalArgumentException iaw) { - return createHeaderExchange(binding); + _logger.warn("Binding: '" + binding + "' not supported"); + return null; } - - _logger.warn("Binding: '" + binding + "' not supported"); - return null; } /** diff --git a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java index 842b2d7696..2c08f1e34a 100644 --- a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java +++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindConnectionFactory.java @@ -36,7 +36,7 @@ public class JNDIBindConnectionFactory { public static final String CONNECTION_FACTORY_BINDING = "amq.ConnectionFactory"; - public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + "/IBMPerfTestsJNDI"; + public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + File.separator + "IBMPerfTestsJNDI"; public static final String PROVIDER_URL = "file://" + DEFAULT_PROVIDER_FILE_PATH; public static final String FSCONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory"; public static final String DEFAULT_CONNECTION_URL = "amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672'"; @@ -154,7 +154,7 @@ public class JNDIBindConnectionFactory } catch (NamingException e) { - + System.out.println("Operation failed: " + e); } // Perform the bind @@ -169,11 +169,11 @@ public class JNDIBindConnectionFactory } catch (NamingException amqe) { - + System.out.println("Operation failed: " + amqe); } catch (URLSyntaxException e) { - + System.out.println("Operation failed: " + e); } } diff --git a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java index 5f328a4107..07dc8c85b3 100644 --- a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java +++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindQueue.java @@ -20,24 +20,25 @@ */ package org.apache.qpid.IBMPerfTest; -import org.apache.qpid.client.AMQConnectionFactory; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.AMQQueue; -import org.apache.log4j.Logger; -import org.apache.log4j.Level; +import org.apache.qpid.client.AMQSession; +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.Queue; +import javax.jms.Session; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; -import javax.jms.*; -import java.util.Hashtable; import java.io.File; -import java.net.MalformedURLException; +import java.util.Hashtable; public class JNDIBindQueue -{ - public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + "/IBMPerfTestsJNDI"; +{ + public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + File.separator + "IBMPerfTestsJNDI"; public static final String PROVIDER_URL = "file://" + DEFAULT_PROVIDER_FILE_PATH; public static final String FSCONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory"; @@ -98,7 +99,7 @@ public class JNDIBindQueue } catch (JMSException closeE) { - + System.out.println("Connection closing failed: " + closeE); } } diff --git a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java index c31dce22cf..16bf0dcb7a 100644 --- a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java +++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/JNDIBindTopic.java @@ -20,24 +20,25 @@ */ package org.apache.qpid.IBMPerfTest; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.AMQTopic; -import org.apache.log4j.Logger; -import org.apache.log4j.Level; -import javax.jms.*; +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.Session; +import javax.jms.Topic; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; -import java.util.Hashtable; import java.io.File; -import java.net.MalformedURLException; +import java.util.Hashtable; public class JNDIBindTopic -{ - public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + "/IBMPerfTestsJNDI"; +{ + public static final String DEFAULT_PROVIDER_FILE_PATH = System.getProperty("java.io.tmpdir") + File.separator + "IBMPerfTestsJNDI"; public static final String PROVIDER_URL = "file://" + DEFAULT_PROVIDER_FILE_PATH; public static final String FSCONTEXT_FACTORY = "com.sun.jndi.fscontext.RefFSContextFactory"; @@ -99,11 +100,9 @@ public class JNDIBindTopic } catch (JMSException closeE) { - + System.out.println("Operation failed: " + closeE); } } - - } diff --git a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/README.txt b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/README.txt index 95ee9f9c77..95ee9f9c77 100644 --- a/java/client/src/test/java/org/apache/qpid/IBMPerfTest/README.txt +++ b/java/client/src/old_test/java/org/apache/qpid/IBMPerfTest/README.txt diff --git a/java/client/src/test/java/org/apache/qpid/cluster/Client.java b/java/client/src/old_test/java/org/apache/qpid/cluster/Client.java index 7a413eee3d..7a413eee3d 100644 --- a/java/client/src/test/java/org/apache/qpid/cluster/Client.java +++ b/java/client/src/old_test/java/org/apache/qpid/cluster/Client.java diff --git a/java/client/src/test/java/org/apache/qpid/codec/BasicDeliverTest.java b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java index 892b349cea..892b349cea 100644 --- a/java/client/src/test/java/org/apache/qpid/codec/BasicDeliverTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java diff --git a/java/client/src/test/java/org/apache/qpid/codec/Client.java b/java/client/src/old_test/java/org/apache/qpid/codec/Client.java index c0de5ab133..c0de5ab133 100644 --- a/java/client/src/test/java/org/apache/qpid/codec/Client.java +++ b/java/client/src/old_test/java/org/apache/qpid/codec/Client.java diff --git a/java/client/src/test/java/org/apache/qpid/codec/Server.java b/java/client/src/old_test/java/org/apache/qpid/codec/Server.java index fa4295e0b2..fa4295e0b2 100644 --- a/java/client/src/test/java/org/apache/qpid/codec/Server.java +++ b/java/client/src/old_test/java/org/apache/qpid/codec/Server.java diff --git a/java/client/src/test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java b/java/client/src/old_test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java index cac0064785..cac0064785 100644 --- a/java/client/src/test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java +++ b/java/client/src/old_test/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java diff --git a/java/client/src/test/java/org/apache/qpid/config/AbstractConfig.java b/java/client/src/old_test/java/org/apache/qpid/config/AbstractConfig.java index 04381d66a0..04381d66a0 100644 --- a/java/client/src/test/java/org/apache/qpid/config/AbstractConfig.java +++ b/java/client/src/old_test/java/org/apache/qpid/config/AbstractConfig.java diff --git a/java/client/src/test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java b/java/client/src/old_test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java index a9984eb09a..a9984eb09a 100644 --- a/java/client/src/test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java +++ b/java/client/src/old_test/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java diff --git a/java/client/src/test/java/org/apache/qpid/config/Connector.java b/java/client/src/old_test/java/org/apache/qpid/config/Connector.java index ff2377f087..ff2377f087 100644 --- a/java/client/src/test/java/org/apache/qpid/config/Connector.java +++ b/java/client/src/old_test/java/org/apache/qpid/config/Connector.java diff --git a/java/client/src/test/java/org/apache/qpid/config/ConnectorConfig.java b/java/client/src/old_test/java/org/apache/qpid/config/ConnectorConfig.java index b120ed3f12..b120ed3f12 100644 --- a/java/client/src/test/java/org/apache/qpid/config/ConnectorConfig.java +++ b/java/client/src/old_test/java/org/apache/qpid/config/ConnectorConfig.java diff --git a/java/client/src/test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java b/java/client/src/old_test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java index 44285efd96..44285efd96 100644 --- a/java/client/src/test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java +++ b/java/client/src/old_test/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java diff --git a/java/client/src/test/java/org/apache/qpid/flow/ChannelFlowTest.java b/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java index 0c57a73d5d..0c57a73d5d 100644 --- a/java/client/src/test/java/org/apache/qpid/flow/ChannelFlowTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java diff --git a/java/client/src/test/java/org/apache/qpid/fragmentation/TestLargePublisher.java b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargePublisher.java index 983186a545..983186a545 100644 --- a/java/client/src/test/java/org/apache/qpid/fragmentation/TestLargePublisher.java +++ b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargePublisher.java diff --git a/java/client/src/test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java index 03ace4a8d9..03ace4a8d9 100644 --- a/java/client/src/test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java +++ b/java/client/src/old_test/java/org/apache/qpid/fragmentation/TestLargeSubscriber.java diff --git a/java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java b/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java index 2a7cb8be30..2a7cb8be30 100644 --- a/java/client/src/test/java/org/apache/qpid/framing/FieldTableTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java diff --git a/java/client/src/test/java/org/apache/qpid/framing/content.txt b/java/client/src/old_test/java/org/apache/qpid/framing/content.txt index fd3fb28590..fd3fb28590 100644 --- a/java/client/src/test/java/org/apache/qpid/framing/content.txt +++ b/java/client/src/old_test/java/org/apache/qpid/framing/content.txt diff --git a/java/client/src/test/java/org/apache/qpid/headers/Listener.java b/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java index d97fc22a35..d97fc22a35 100644 --- a/java/client/src/test/java/org/apache/qpid/headers/Listener.java +++ b/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java diff --git a/java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java b/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java index 6f538d068c..6f538d068c 100644 --- a/java/client/src/test/java/org/apache/qpid/headers/MessageFactory.java +++ b/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java diff --git a/java/client/src/test/java/org/apache/qpid/headers/Publisher.java b/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java index a4ac5f670d..a4ac5f670d 100644 --- a/java/client/src/test/java/org/apache/qpid/headers/Publisher.java +++ b/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java diff --git a/java/client/src/test/java/org/apache/qpid/jndi/referenceable/Bind.java b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Bind.java index ee6a12c233..ee6a12c233 100644 --- a/java/client/src/test/java/org/apache/qpid/jndi/referenceable/Bind.java +++ b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Bind.java diff --git a/java/client/src/test/java/org/apache/qpid/jndi/referenceable/Lookup.java b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Lookup.java index 1c9d8b0fd5..1c9d8b0fd5 100644 --- a/java/client/src/test/java/org/apache/qpid/jndi/referenceable/Lookup.java +++ b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Lookup.java diff --git a/java/client/src/test/java/org/apache/qpid/jndi/referenceable/Unbind.java b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Unbind.java index 1acead674c..1acead674c 100644 --- a/java/client/src/test/java/org/apache/qpid/jndi/referenceable/Unbind.java +++ b/java/client/src/old_test/java/org/apache/qpid/jndi/referenceable/Unbind.java diff --git a/java/client/src/test/java/org/apache/qpid/latency/LatencyTest.java b/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java index ebc9488f68..ebc9488f68 100644 --- a/java/client/src/test/java/org/apache/qpid/latency/LatencyTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java diff --git a/java/client/src/test/java/org/apache/qpid/mina/AcceptorTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java index de3d558f7c..de3d558f7c 100644 --- a/java/client/src/test/java/org/apache/qpid/mina/AcceptorTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java diff --git a/java/client/src/test/java/org/apache/qpid/mina/BlockingAcceptorTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/BlockingAcceptorTest.java index bfe29c47e6..bfe29c47e6 100644 --- a/java/client/src/test/java/org/apache/qpid/mina/BlockingAcceptorTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/mina/BlockingAcceptorTest.java diff --git a/java/client/src/test/java/org/apache/qpid/mina/WriterTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/WriterTest.java index 910345624f..910345624f 100644 --- a/java/client/src/test/java/org/apache/qpid/mina/WriterTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/mina/WriterTest.java diff --git a/java/client/src/test/java/org/apache/qpid/multiconsumer/AMQTest.java b/java/client/src/old_test/java/org/apache/qpid/multiconsumer/AMQTest.java index 10e03d3522..10e03d3522 100644 --- a/java/client/src/test/java/org/apache/qpid/multiconsumer/AMQTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/multiconsumer/AMQTest.java diff --git a/java/client/src/test/java/org/apache/qpid/ping/TestPingClient.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingClient.java index b060498d9b..b060498d9b 100644 --- a/java/client/src/test/java/org/apache/qpid/ping/TestPingClient.java +++ b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingClient.java diff --git a/java/client/src/test/java/org/apache/qpid/ping/TestPingProducer.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingProducer.java index 458dca0d56..458dca0d56 100644 --- a/java/client/src/test/java/org/apache/qpid/ping/TestPingProducer.java +++ b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingProducer.java diff --git a/java/client/src/test/java/org/apache/qpid/ping/TestPingPublisher.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingPublisher.java index c7742be042..c7742be042 100644 --- a/java/client/src/test/java/org/apache/qpid/ping/TestPingPublisher.java +++ b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingPublisher.java diff --git a/java/client/src/test/java/org/apache/qpid/ping/TestPingSubscriber.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingSubscriber.java index 8e8c3f2e6e..8e8c3f2e6e 100644 --- a/java/client/src/test/java/org/apache/qpid/ping/TestPingSubscriber.java +++ b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingSubscriber.java diff --git a/java/client/src/test/java/org/apache/qpid/pubsub1/TestPublisher.java b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestPublisher.java index 45b241975d..45b241975d 100644 --- a/java/client/src/test/java/org/apache/qpid/pubsub1/TestPublisher.java +++ b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestPublisher.java diff --git a/java/client/src/test/java/org/apache/qpid/pubsub1/TestSubscriber.java b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestSubscriber.java index 14cf206f50..14cf206f50 100644 --- a/java/client/src/test/java/org/apache/qpid/pubsub1/TestSubscriber.java +++ b/java/client/src/old_test/java/org/apache/qpid/pubsub1/TestSubscriber.java diff --git a/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java b/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java index 7cbec7c85c..7cbec7c85c 100644 --- a/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java +++ b/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java diff --git a/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java b/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java index 5dc57364b3..74becfd9bb 100644 --- a/java/client/src/test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java +++ b/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java @@ -107,6 +107,7 @@ public class ServiceRequestingClient implements ExceptionListener } try { + m.getPropertyNames(); if (m.propertyExists("timeSent")) { long timeSent = Long.parseLong(m.getStringProperty("timeSent")); diff --git a/java/client/src/test/java/org/apache/qpid/requestreply1/VmRequestReply.java b/java/client/src/old_test/java/org/apache/qpid/requestreply1/VmRequestReply.java index 56d1ce9b6d..56d1ce9b6d 100644 --- a/java/client/src/test/java/org/apache/qpid/requestreply1/VmRequestReply.java +++ b/java/client/src/old_test/java/org/apache/qpid/requestreply1/VmRequestReply.java diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java index d89bc4a771..d89bc4a771 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/client/connection/TestManyConnections.java diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java index cdb00240b6..cdb00240b6 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java diff --git a/java/client/src/test/java/org/apache/qpid/example/shared/example.properties b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/example.properties index 82de41908f..82de41908f 100644 --- a/java/client/src/test/java/org/apache/qpid/example/shared/example.properties +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/example.properties diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Bind.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Bind.java index db871281bf..db871281bf 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Bind.java +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Bind.java diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/JNDIReferenceableTest.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/JNDIReferenceableTest.java index 4731caca98..4731caca98 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/JNDIReferenceableTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/JNDIReferenceableTest.java diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Lookup.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Lookup.java index b804ccb30c..b804ccb30c 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Lookup.java +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Lookup.java diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Unbind.java b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Unbind.java index 869bc55d8f..869bc55d8f 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Unbind.java +++ b/java/client/src/old_test/java/org/apache/qpid/test/unit/jndi/referenceabletest/Unbind.java diff --git a/java/client/src/test/java/org/apache/qpid/topic/Config.java b/java/client/src/old_test/java/org/apache/qpid/topic/Config.java index bb740f9094..bb740f9094 100644 --- a/java/client/src/test/java/org/apache/qpid/topic/Config.java +++ b/java/client/src/old_test/java/org/apache/qpid/topic/Config.java diff --git a/java/client/src/test/java/org/apache/qpid/topic/Listener.java b/java/client/src/old_test/java/org/apache/qpid/topic/Listener.java index 47c608cfe4..47c608cfe4 100644 --- a/java/client/src/test/java/org/apache/qpid/topic/Listener.java +++ b/java/client/src/old_test/java/org/apache/qpid/topic/Listener.java diff --git a/java/client/src/test/java/org/apache/qpid/topic/MessageFactory.java b/java/client/src/old_test/java/org/apache/qpid/topic/MessageFactory.java index 1520f18408..1520f18408 100644 --- a/java/client/src/test/java/org/apache/qpid/topic/MessageFactory.java +++ b/java/client/src/old_test/java/org/apache/qpid/topic/MessageFactory.java diff --git a/java/client/src/test/java/org/apache/qpid/topic/Publisher.java b/java/client/src/old_test/java/org/apache/qpid/topic/Publisher.java index d788029ee9..d788029ee9 100644 --- a/java/client/src/test/java/org/apache/qpid/topic/Publisher.java +++ b/java/client/src/old_test/java/org/apache/qpid/topic/Publisher.java diff --git a/java/client/src/test/java/org/apache/qpid/transacted/Config.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Config.java index bd104e5407..bd104e5407 100644 --- a/java/client/src/test/java/org/apache/qpid/transacted/Config.java +++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Config.java diff --git a/java/client/src/test/java/org/apache/qpid/transacted/Ping.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Ping.java index e0af4422a6..e0af4422a6 100644 --- a/java/client/src/test/java/org/apache/qpid/transacted/Ping.java +++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Ping.java diff --git a/java/client/src/test/java/org/apache/qpid/transacted/Pong.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Pong.java index 13295c137a..13295c137a 100644 --- a/java/client/src/test/java/org/apache/qpid/transacted/Pong.java +++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Pong.java diff --git a/java/client/src/test/java/org/apache/qpid/transacted/Relay.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Relay.java index cede95e5f0..cede95e5f0 100644 --- a/java/client/src/test/java/org/apache/qpid/transacted/Relay.java +++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Relay.java diff --git a/java/client/src/test/java/org/apache/qpid/transacted/Start.java b/java/client/src/old_test/java/org/apache/qpid/transacted/Start.java index 5564ed93ab..5564ed93ab 100644 --- a/java/client/src/test/java/org/apache/qpid/transacted/Start.java +++ b/java/client/src/old_test/java/org/apache/qpid/transacted/Start.java diff --git a/java/client/src/test/java/org/apache/qpid/weblogic/ServiceProvider.java b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceProvider.java index 71d806b338..71d806b338 100644 --- a/java/client/src/test/java/org/apache/qpid/weblogic/ServiceProvider.java +++ b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceProvider.java diff --git a/java/client/src/test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java index a1e15258c3..a1e15258c3 100644 --- a/java/client/src/test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java +++ b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java diff --git a/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java b/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java index c34dbf14f1..9b477c19e2 100644 --- a/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java +++ b/java/client/src/test/java/org/apache/qpid/client/message/TestMessageHelper.java @@ -38,4 +38,9 @@ public class TestMessageHelper { return new JMSMapMessage(); } + + public static JMSStreamMessage newJMSStreamMessage() + { + return new JMSStreamMessage(); + } } diff --git a/java/client/src/test/java/org/apache/qpid/cts/bin/jmscts.sh b/java/client/src/test/java/org/apache/qpid/cts/bin/jmscts.sh deleted file mode 100755 index 37b8018aaf..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/bin/jmscts.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/sh -# -# 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. -# - -# ----------------------------------------------------------------------------- -# Start/Stop Script for the JMS compliance test suite -# -# Required Environment Variables -# -# JAVA_HOME Points to the Java Development Kit installation. -# -# Optional Environment Variables -# -# JMSCTS_HOME Points to the JMS CTS installation directory. -# -# JAVA_OPTS Java runtime options used when the command is executed. -# -# -# $Id: jmscts.sh,v 1.6 2003/09/27 09:50:49 tanderson Exp $ -# --------------------------------------------------------------------------- - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false -case "`uname`" in -CYGWIN*) cygwin=true;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -if [ -z "$JAVA_HOME" ]; then - echo "The JAVA_HOME environment variable is not set." - echo "This is required to run jmscts" - exit 1 -fi -if [ ! -r "$JAVA_HOME"/bin/java ]; then - echo "The JAVA_HOME environment variable is not set correctly." - echo "This is required to run jmscts" - exit 1 -fi -_RUNJAVA="$JAVA_HOME"/bin/java - - -# Guess JMSCTS_HOME if it is not set -if [ -z "$JMSCTS_HOME" ]; then -# resolve links - $0 may be a softlink - PRG="$0" - while [ -h "$PRG" ]; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '.*/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`/"$link" - fi - done - - PRGDIR=`dirname "$PRG"` - JMSCTS_HOME=`cd "$PRGDIR/.." ; pwd` -elif [ ! -r "$JMSCTS_HOME"/bin/jmscts.sh ]; then - echo "The JMSCTS_HOME environment variable is not set correctly." - echo "This is required to run jmscts" - exit 1 -fi - -# Set CLASSPATH to empty by default. User jars can be added via the setenv.sh -# script -CLASSPATH= - -if [ -r "$JMSCTS_HOME"/bin/setenv.sh ]; then - . "$JMSCTS_HOME"/bin/setenv.sh -fi - -CLASSPATH="$CLASSPATH":"$JMSCTS_HOME"/lib/jmscts-0.5-b2.jar - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - JMSCTS_HOME=`cygpath --path --windows "$JMSCTS_HOME"` - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - -POLICY_FILE="$JMSCTS_HOME"/config/jmscts.policy - -# Configure TrAX -JAVAX_OPTS=-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl - - -# Execute the requested command - -echo "Using JMSCTS_HOME: $JMSCTS_HOME" -echo "Using JAVA_HOME: $JAVA_HOME" -echo "Using CLASSPATH: $CLASSPATH" - -if [ "$1" = "run" ]; then - - shift - exec "$_RUNJAVA" $JAVA_OPTS $JAVAX_OPTS -Djmscts.home="$JMSCTS_HOME" \ - -classpath "$CLASSPATH" \ - -Djava.security.manager -Djava.security.policy="$POLICY_FILE" \ - org.exolab.jmscts.test.ComplianceTestSuite "$@" - -elif [ "$1" = "stress" ]; then - - shift - exec "$_RUNJAVA" $JAVA_OPTS $JAVAX_OPTS -Djmscts.home="$JMSCTS_HOME" \ - -classpath "$CLASSPATH" \ - -Djava.security.manager -Djava.security.policy="$POLICY_FILE" \ - org.exolab.jmscts.stress.StressTestSuite "$@" - -elif [ "$1" = "stop" ] ; then - - shift - "$_RUNJAVA" $JAVA_OPTS $JAVAX_OPTS -Djmscts.home="$JMSCTS_HOME" \ - -classpath "$CLASSPATH" \ - -Djava.security.manager -Djava.security.policy="$POLICY_FILE" \ - org.exolab.jmscts.core.Admin -stop - -elif [ "$1" = "abort" ] ; then - - shift - exec "$_RUNJAVA" $JAVA_OPTS $JAVAX_OPTS -Djmscts.home="$JMSCTS_HOME" \ - -classpath "$CLASSPATH" \ - -Djava.security.manager -Djava.security.policy="$POLICY_FILE" \ - org.exolab.jmscts.core.Admin -abort - -elif [ "$1" = "snapshot" ] ; then - - shift - exec "$_RUNJAVA" $JAVA_OPTS $JAVAX_OPTS -Djmscts.home="$JMSCTS_HOME" \ - -classpath "$CLASSPATH" \ - -Djava.security.manager -Djava.security.policy="$POLICY_FILE" \ - org.exolab.jmscts.core.Admin -snapshot "$@" - -else - echo "usage: jmscts.sh (commands)" - echo "commands:" - echo " run Run compliance tests" - echo " stress Run stress tests" - echo " stop Stop the JMS CTS" - echo " abort Abort the JMS CTS" - echo " snapshot Take a snapshot" - exit 1 -fi diff --git a/java/client/src/test/java/org/apache/qpid/cts/bin/setenv.sh b/java/client/src/test/java/org/apache/qpid/cts/bin/setenv.sh deleted file mode 100755 index 9b9189d646..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/bin/setenv.sh +++ /dev/null @@ -1,41 +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. -# - -# --------------------------------------------------------------------------- -# Sample environment script for JMS CTS -# -# This is invoked by jmscts.sh to configure: -# . the CLASSPATH, for JMS provider jars -# . JVM options -# -# The following configures the JMS CTS for OpenJMS 0.7.6 -# --------------------------------------------------------------------------- - -# Configure the CLASSPATH -# -DISTDIR="$IBASE/amqp/dist" -LIBDIR="$IBASE/amqp/lib" - -CLASSPATH="$LIBDIR/jakarta-commons/commons-collections-3.1.jar:$LIBDIR/util-concurrent/backport-util-concurrent.jar:$LIBDIR/mina/mina-0.7.3.jar:$LIBDIR/jms/jms.jar:$LIBDIR/logging-log4j/log4j-1.2.9.jar:$DISTDIR/amqp-common.jar:$DISTDIR/amqp-jms.jar" - -# Configure JVM options -# -JAVA_OPTS=-Xmx512m -Xms512m -JAVA_OPTS="$JAVA_OPTS \ - -Damqj.logging.level=WARN" diff --git a/java/client/src/test/java/org/apache/qpid/cts/config/jmscts.policy b/java/client/src/test/java/org/apache/qpid/cts/config/jmscts.policy deleted file mode 100644 index ff8b5db5ec..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/config/jmscts.policy +++ /dev/null @@ -1,22 +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. -// -// grant all users all permissions. This is only for test cases -// and should be modified for deployment -grant { - permission java.security.AllPermission; -}; diff --git a/java/client/src/test/java/org/apache/qpid/cts/config/jmscts.properties b/java/client/src/test/java/org/apache/qpid/cts/config/jmscts.properties deleted file mode 100644 index 7177fed49d..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/config/jmscts.properties +++ /dev/null @@ -1,71 +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. -# - -# ============================================================================= -# General properties -# ----------------------------------------------------------------------------- - -# -# Username & password -# A user name and password for creating Connection instances via -# TopicConnectionFactory.createTopicConnection(...) etc -# -valid.username=guest -valid.password=guest - -# -# Invalid user name and password -# As above, but guaranteed to fail. -# -invalid.username=guest -invalid.password=guest - -# -# Message receipt timeout -# The default time to wait for messages, in milliseconds -# -org.exolab.jmscts.core.MessagingBehaviour.timeout=2000 - - -# ============================================================================= -# Compliance test properties -# ----------------------------------------------------------------------------- - -# -# Expiration interval -# Time in milliseconds to wait for the JMS provider to collect expired -# messages. -# This can be set for providers which collect expired messages periodically, -# rather than at the moment they expire. -# NOTE: for OpenJMS 0.7.6, this should be set to 5000 -org.exolab.jmscts.test.producer.ttl.ExpirationTest.expirationInterval=0 - - -# ============================================================================= -# Stress test properties -# ----------------------------------------------------------------------------- - -# -# Each of the following properties determines the no. of messages that -# will be sent by stress tests -# -org.exolab.jmscts.stress.Send0KTest.count=1000 -org.exolab.jmscts.stress.ReceiveSize0KTest.count=1000 -org.exolab.jmscts.stress.SendReceive0KTest.count=1000 -org.exolab.jmscts.stress.SendReceive2Size0KTest.count=1000 diff --git a/java/client/src/test/java/org/apache/qpid/cts/config/providers.xml b/java/client/src/test/java/org/apache/qpid/cts/config/providers.xml deleted file mode 100644 index 30c4a39c5b..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/config/providers.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.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. - - - --> - -<!-- ====================================================================== --> -<!-- Sample provider configuration file --> -<!-- --> -<!-- This configures JMS CTS to test OpenJMS --> -<!-- ====================================================================== --> - -<configuration> - - <provider> - <name>AMQP</name> - <class>org.exolab.jmscts.amqp.AMQPProvider</class> - <paths> - <path>/home/guso/harness/jmscts-0.5-b2/lib/amqp-provider-0.0a1.jar</path> - </paths> - <config> - </config> - </provider> - -</configuration> diff --git a/java/client/src/test/java/org/apache/qpid/cts/readme.txt b/java/client/src/test/java/org/apache/qpid/cts/readme.txt deleted file mode 100644 index 117e7d4954..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -The files present in the bin, config and src directories should be copied over a complete copy of jms-cts-0.5-b2. - -The path entries on the config/providers.xml and src/compile.sh files should be changed before attempting to run. - -The scripts expect a properly configured IBASE environment. Before attempting to run, the amqp provider classes must be packaged and installed. The src/compile.sh script will help to achieve that.
\ No newline at end of file diff --git a/java/client/src/test/java/org/apache/qpid/cts/src/compile.sh b/java/client/src/test/java/org/apache/qpid/cts/src/compile.sh deleted file mode 100755 index 7b8a9f03ec..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/src/compile.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -# -# 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. -# - - -JMSCTS_PATH=/home/guso/harness/jmscts-0.5-b2 - -distjms="$IBASE/amqp/dist" -lib="$IBASE/amqp/lib" -lib2="$JMSCTS_PATH/lib/" -libs="$lib/jakarta-commons/commons-collections-3.1.jar:$lib/util-concurrent/backport-util-concurrent.jar:$lib/mina/mina-0.7.3.jar:$lib/jms/jms.jar:$lib/logging-log4j/log4j-1.2.9.jar:$distjms/amqp-common.jar:$distjms/amqp-jms.jar" -libs2="$lib2/ant-1.5.3-1.jar:$lib2/junit-3.8.1.jar:$lib2/ant-optional-1.5.3-1.jar:$lib2/log4j-1.2.7.jar:$lib2/castor-0.9.5.jar:$lib2/openjms-provider-0.5-b2.jar:$lib2/commons-cli-1.0.jar:$lib2/oro-2.0.7.jar:$lib2/commons-collections-2.1.jar:$lib2/xalan-2.5.1.jar:$lib2/commons-logging-1.0.2.jar:$lib2/xdoclet-1.2b2.jar:$lib2/concurrent-1.3.2.jar:$lib2/xdoclet-xdoclet-module-1.2b2.jar:$lib2/exolabcore-0.3.7.jar:$lib2/xdoclet-xjavadoc-uc-1.2b2.jar:$lib2/jms-1.0.2a.jar:$lib2/xerces-2.3.0.jar:$lib2/jmscts-0.5-b2.jar:$lib2/xml-apis-1.0.b2.jar" - -javac -classpath $libs:$libs2 $JMSCTS_PATH/src/providers/amqp/org/exolab/jmscts/amqp/*.java -cd $JMSCTS_PATH/src/providers/amqp -jar cvf amqp-provider-0.0a1.jar org/exolab/jmscts/amqp/*.class -mv amqp-provider-0.0a1.jar $lib2 - diff --git a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java b/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java deleted file mode 100644 index 21a6816af7..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPAdministrator.java +++ /dev/null @@ -1,242 +0,0 @@ -/** - * Redistribution and use of this software and associated documentation - * ("Software"), with or without modification, are permitted provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain copyright - * statements and notices. Redistributions must also contain a - * copy of this document. - * - * 2. Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. The name "Exolab" must not be used to endorse or promote - * products derived from this Software without prior written - * permission of Exoffice Technologies. For written permission, - * please contact jima@intalio.com. - * - * 4. Products derived from this Software may not be called "Exolab" - * nor may "Exolab" appear in their names without prior written - * permission of Exoffice Technologies. Exolab is a registered - * trademark of Exoffice Technologies. - * - * 5. Due credit should be given to the Exolab Project - * (http://www.exolab.org/). - * - * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Copyright 2001, 2003 (C) Exoffice Technologies Inc. All Rights Reserved. - * - */ -package org.exolab.jmscts.amqp; - -import org.apache.qpid.client.*; -import org.exolab.jmscts.provider.Administrator; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.MessageConsumer; -import javax.jms.Session; -import javax.naming.NameNotFoundException; -import javax.naming.NamingException; -import java.net.InetAddress; -import java.util.HashMap; - -/** - * This class provides methods for obtaining and manipulating administered - * objects managed by the Sonicmq implementation of JMS - * - */ -class AMQPAdministrator implements Administrator { - // AMQ Connection configuration - private int port = 5672; - private String host = "localhost"; - private String user = "guest"; - private String pass = "guest"; - private String vhost = "/test"; - - // The cached broker connection & session - private AMQConnection _connection = null; - private Session _session = null; - - // Factory request names - private static final String QUEUE_CONNECTION_FACTORY = "QueueConnectionFactory"; - private static final String TOPIC_CONNECTION_FACTORY = "TopicConnectionFactory"; - - /** - * The cache of known administered objects - */ - private HashMap<String, Object> _directory = new HashMap<String, Object>(); - - /** - * Returns the name of the QueueConnectionFactory bound in JNDI - * - * @return the default QueueConnectionFactory name - */ - public String getQueueConnectionFactory() { - return QUEUE_CONNECTION_FACTORY; - } - - /** - * Returns the name of the TopicConnectionFactory bound in JNDI - * - * @return the default TopicConnectionFactory name - */ - public String getTopicConnectionFactory() { - return TOPIC_CONNECTION_FACTORY; - } - - /** - * Returns the name of the XAQueueConnectionFactory bound in JNDI - * - * @return the default XAQueueConnectionFactory name - */ - public String getXAQueueConnectionFactory() { - return null; - } - - /** - * Returns the name of the XATopicConnectionFactory bound in JNDI - * - * @return the default XATopicConnectionFactory name - */ - public String getXATopicConnectionFactory() { - return null; - } - - /** - * Look up the named administered object - * - * @param name the name that the administered object is bound to - * @return the administered object bound to name - * @throws NamingException if the object is not bound, or the lookup fails - */ - public Object lookup(String name) throws NamingException { - Object result = _directory.get(name); - if (result == null) { - if (name.equals(QUEUE_CONNECTION_FACTORY)) { - _directory.put(QUEUE_CONNECTION_FACTORY, new AMQConnectionFactory(host, port, user, pass, vhost)); - } else if (name.equals(TOPIC_CONNECTION_FACTORY)) { - _directory.put(TOPIC_CONNECTION_FACTORY, new AMQConnectionFactory(host, port, user, pass, vhost)); - } else { - throw new NameNotFoundException("Name not found: " + name); - } - } - return result; - } - - /** - * Create an administered destination - * - * @param name the destination name - * @param queue if true, create a queue, else create a topic - * @throws JMSException if the destination cannot be created - */ - public void createDestination(String name, boolean queue) - throws JMSException { - AMQDestination destination = null; - - try { - if (queue) { - destination = new AMQQueue(name); - createConsumer(destination); - } else { - destination = new AMQTopic(name); - createConsumer(destination); - } - - _directory.put(name, destination); - } catch (Exception exception) { - JMSException error = new JMSException(exception.getMessage()); - error.setLinkedException(exception); - throw error; - } - } - - /** - * Destroy an administered destination - * - * @param name the destination name - * @throws JMSException if the destination cannot be destroyed - */ - public void destroyDestination(String name) - throws JMSException { - - try { - Destination destination = (Destination) lookup(name); - _directory.remove(name); - } catch (NamingException exception) { - JMSException error = new JMSException(exception.getMessage()); - error.setLinkedException(exception); - throw error; - } catch (Exception exception) { - JMSException error = new JMSException(exception.getMessage()); - error.setLinkedException(exception); - throw error; - } - } - - /** - * Returns true if an administered destination exists - * - * @param name the destination name - * @throws JMSException for any internal JMS provider error - */ - public boolean destinationExists(String name) - throws JMSException { - - boolean exists = false; - try { - lookup(name); - exists = true; - } catch (NameNotFoundException ignore) { - } catch (Exception exception) { - JMSException error = new JMSException(exception.getMessage()); - error.setLinkedException(exception); - throw error; - } - return exists; - } - - public void initialise() throws JMSException { - try { - InetAddress address = InetAddress.getLocalHost(); - _connection = new AMQConnection(host, port, user, pass, - address.getHostName(), vhost); - _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - } catch (Exception exception) { - JMSException error = new JMSException(exception.getMessage()); - error.setLinkedException(exception); - throw error; - } - } - - public synchronized void cleanup() { - try { - _connection.close(); - } catch (JMSException e) { - e.printStackTrace(); - } - _connection = null; - _session = null; - _directory.clear(); - } - - MessageConsumer createConsumer(AMQDestination destination) throws JMSException - { - return ((AMQSession)_session).createConsumer(destination, /*pre-fetch*/0, false, /*exclusive*/false, null); - } -} //-- AMQPAdministrator diff --git a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java b/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java deleted file mode 100644 index 21610d39b2..0000000000 --- a/java/client/src/test/java/org/apache/qpid/cts/src/providers/amqp/org/exolab/jmscts/amqp/AMQPProvider.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Redistribution and use of this software and associated documentation - * ("Software"), with or without modification, are permitted provided - * that the following conditions are met: - * - * 1. Redistributions of source code must retain copyright - * statements and notices. Redistributions must also contain a - * copy of this document. - * - * 2. Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. The name "Exolab" must not be used to endorse or promote - * products derived from this Software without prior written - * permission of Exoffice Technologies. For written permission, - * please contact jima@intalio.com. - * - * 4. Products derived from this Software may not be called "Exolab" - * nor may "Exolab" appear in their names without prior written - * permission of Exoffice Technologies. Exolab is a registered - * trademark of Exoffice Technologies. - * - * 5. Due credit should be given to the Exolab Project - * (http://www.exolab.org/). - * - * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Copyright 2001, 2003 (C) Exoffice Technologies Inc. All Rights Reserved. - * - */ -package org.exolab.jmscts.amqp; - -import javax.jms.JMSException; - -import org.exolab.jmscts.provider.Administrator; -import org.exolab.jmscts.provider.Provider; - - -/** - * This class enables test cases to be run against the SonicMQ provider - * - * @see AMQPAdministrator - */ -public class AMQPProvider implements Provider { - - /** - * The administration interface - */ - private AMQPAdministrator _admin = new AMQPAdministrator(); - - /** - * Construct an instance of the interface to the AMQP provider - */ - public AMQPProvider() { - } - - /** - * Initialises the administation interface - * - * @throws JMSException if the administration interface can't be - * initialised - */ - public void initialise(boolean start) throws JMSException { - _admin.initialise(); - } - - /** - * Returns the administration interface - */ - public Administrator getAdministrator() { - return _admin; - } - - /** - * This method cleans up the administrator - */ - public void cleanup(boolean stop) { - _admin.cleanup(); - _admin = null; - } - -} //-- AMQPProvider diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java index 5161705ef2..295bb80306 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/ack/RecoverTest.java @@ -26,7 +26,7 @@ import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import javax.jms.*; @@ -36,18 +36,21 @@ public class RecoverTest extends TestCase { private static final Logger _logger = Logger.getLogger(RecoverTest.class); - static + protected void setUp() throws Exception { - String workdir = System.getProperty("QPID_WORK"); - if (workdir == null || workdir.equals("")) - { - String tempdir = System.getProperty("java.io.tmpdir"); - System.out.println("QPID_WORK not set using tmp directory: " + tempdir); - System.setProperty("QPID_WORK", tempdir); - } - DOMConfigurator.configure("../broker/etc/log4j.xml"); + super.setUp(); + TransportConnection.createVMBroker(1); } + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + //Thread.sleep(2000); + } + + + public void testRecoverResendsMsgs() throws Exception { Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); @@ -104,8 +107,74 @@ public class RecoverTest extends TestCase con.close(); } + + public void testRecoverResendsMsgsAckOnEarlier() throws Exception + { + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + + Session consumerSession = con.createSession(false, Session.CLIENT_ACKNOWLEDGE); + Queue queue = new AMQQueue("someQ", "someQ", false, true); + MessageConsumer consumer = consumerSession.createConsumer(queue); + //force synch to ensure the consumer has resulted in a bound queue + ((AMQSession) consumerSession).declareExchangeSynch("amq.direct", "direct"); + + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); + MessageProducer producer = producerSession.createProducer(queue); + + _logger.info("Sending four messages"); + producer.send(producerSession.createTextMessage("msg1")); + producer.send(producerSession.createTextMessage("msg2")); + producer.send(producerSession.createTextMessage("msg3")); + producer.send(producerSession.createTextMessage("msg4")); + + con2.close(); + + _logger.info("Starting connection"); + con.start(); + TextMessage tm = (TextMessage) consumer.receive(); + TextMessage tm2 = (TextMessage) consumer.receive(); + tm.acknowledge(); + _logger.info("Received 2 messages, acknowledge() first message, should acknowledge both"); + + consumer.receive(); + consumer.receive(); + _logger.info("Received all four messages. Calling recover with two outstanding messages"); + // no ack for last three messages so when I call recover I expect to get three messages back + consumerSession.recover(); + TextMessage tm3 = (TextMessage) consumer.receive(3000); + assertEquals("msg3", tm3.getText()); + + TextMessage tm4 = (TextMessage) consumer.receive(3000); + assertEquals("msg4", tm4.getText()); + + + _logger.info("Received redelivery of two messages. calling acknolwedgeThis() first of those message"); + ((org.apache.qpid.jms.Message)tm3).acknowledgeThis(); + + _logger.info("Calling recover"); + // all acked so no messages to be delivered + consumerSession.recover(); + + tm4 = (TextMessage) consumer.receive(3000); + assertEquals("msg4", tm4.getText()); + ((org.apache.qpid.jms.Message)tm4).acknowledgeThis(); + + _logger.info("Calling recover"); + // all acked so no messages to be delivered + consumerSession.recover(); + + + tm = (TextMessage) consumer.receiveNoWait(); + assertNull(tm); + _logger.info("No messages redelivered as is expected"); + + con.close(); + } + + public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(RecoverTest.class)); + return new junit.framework.TestSuite(RecoverTest.class); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java index 2983a16e6d..e6f7032aa7 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/BytesMessageTest.java @@ -26,7 +26,7 @@ import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.message.JMSBytesMessage; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import org.apache.mina.common.ByteBuffer; import java.util.ArrayList; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableInTextMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableInTextMessageTest.java deleted file mode 100644 index bccf5b4ccd..0000000000 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableInTextMessageTest.java +++ /dev/null @@ -1,160 +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.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 FieldTableInTextMessageTest extends TestCase implements MessageListener -{ - private final static Logger _logger = org.apache.log4j.Logger.getLogger(FieldTableInTextMessageTest.class); - - private AMQConnection _connection; - private Destination _destination; - private AMQSession _session; - private Message original_message = null; - private Message received_message = null; - 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("TextMessageTest"), 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 - { - send(); - waitFor(); - check(); - System.out.println("Completed without failure"); - _connection.close(); - } - - void send() throws JMSException - { - //create a publisher - MessageProducer producer = _session.createProducer(_destination); - Message message = _session.createTextMessage("Message Body"); - message.setBooleanProperty("boolan", true); - message.setByteProperty("byte", Byte.MAX_VALUE); - message.setDoubleProperty("double", Double.MAX_VALUE); - message.setFloatProperty("float", Float.MAX_VALUE); - message.setIntProperty("int", Integer.MAX_VALUE); - message.setLongProperty("long", Long.MAX_VALUE); - message.setShortProperty("short", Short.MAX_VALUE); - message.setStringProperty("String", "String"); - - - original_message = message; - _logger.info("Sending Message:" + message); - producer.send(message); - - } - - void waitFor() throws InterruptedException - { - synchronized(received_message) - { - received_message.wait(); - } - } - - void check() throws JMSException - { - _logger.info("Received Message:" + received_message); - assertEqual(original_message, received_message); - } - - private static void assertEqual(Message expected, Message actual) - { - _logger.info("Expected:" + expected); - _logger.info("Actual:" + actual); - } - - public void onMessage(Message message) - { - synchronized(received_message) - { - received_message = message; - received_message.notify(); - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] argv) throws Exception - { - FieldTableInTextMessageTest test = new FieldTableInTextMessageTest(); - test._connectionString = argv.length == 0 ? "vm://:1" : argv[0]; - test.setUp(); - test.test(); - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(FieldTableInTextMessageTest.class)); - } -} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java index c1ecef6b57..f4efd64dbb 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableMessageTest.java @@ -26,10 +26,9 @@ import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.message.JMSBytesMessage; import org.apache.qpid.framing.AMQFrameDecodingException; -import org.apache.qpid.framing.FieldTableTest; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.FieldTableFactory; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import org.apache.mina.common.ByteBuffer; import org.apache.log4j.Logger; @@ -134,7 +133,11 @@ public class FieldTableMessageTest extends TestCase implements MessageListener { ByteBuffer buffer = ((JMSBytesMessage) m).getData(); FieldTable actual = FieldTableFactory.newFieldTable(buffer, buffer.remaining()); - new FieldTableTest().assertEquivalent(_expected, actual); + for (Object o : _expected.keySet()) + { + String key = (String) o; + assertEquals("Values for " + key + " did not match", _expected.get(key), actual.get(key)); + } } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java index 5353a19d13..02a98f67d9 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MapMessageTest.java @@ -20,40 +20,42 @@ */ package org.apache.qpid.test.unit.basic; +import junit.framework.Assert; +import junit.framework.TestCase; +import org.apache.log4j.Logger; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.client.message.JMSTextMessage; import org.apache.qpid.client.message.JMSMapMessage; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.client.transport.TransportConnection; +import javax.jms.*; 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 MapMessageTest extends TestCase implements MessageListener { + + private static final Logger _logger = Logger.getLogger(MapMessageTest.class); + private AMQConnection _connection; private Destination _destination; private AMQSession _session; private final List<JMSMapMessage> received = new ArrayList<JMSMapMessage>(); - private final List<String> messages = new ArrayList<String>(); + + private static final String MESSAGE = "Message "; private int _count = 100; public String _connectionString = "vm://:1"; private byte[] _bytes = {99, 98, 97, 96, 95}; + private static final float _smallfloat = 100.0f; protected void setUp() throws Exception { super.setUp(); try { + TransportConnection.createVMBroker(1); init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); } catch (Exception e) @@ -64,7 +66,9 @@ public class MapMessageTest extends TestCase implements MessageListener protected void tearDown() throws Exception { + _logger.info("Tearing Down unit.basic.MapMessageTest"); super.tearDown(); + TransportConnection.killAllVMBrokers(); } private void init(AMQConnection connection) throws Exception @@ -90,7 +94,6 @@ public class MapMessageTest extends TestCase implements MessageListener send(count); waitFor(count); check(); - System.out.println("Completed without failure"); _connection.close(); } @@ -100,38 +103,45 @@ public class MapMessageTest extends TestCase implements MessageListener MessageProducer producer = _session.createProducer(_destination); for (int i = 0; i < count; i++) { - String text = "Message " + i; - messages.add(text); MapMessage message = _session.createMapMessage(); - message.setBoolean("odd", i / 2 == 0); - message.setByte("byte", (byte) Byte.MAX_VALUE); + setMapValues(message, i); - message.setBytes("bytes", _bytes); - message.setChar("char", (char) 'c'); - message.setDouble("double", (double) Double.MAX_VALUE); - message.setFloat("float", (float) Float.MAX_VALUE); - - message.setInt("messageNumber", i); - message.setInt("int", (int) Integer.MAX_VALUE); + producer.send(message); + } + } - message.setLong("long", (long) Long.MAX_VALUE); - message.setShort("short", (short) Short.MAX_VALUE); - message.setString("message", text); + private void setMapValues(MapMessage message, int i) throws JMSException + { + message.setBoolean("odd", i / 2 == 0); + message.setByte("byte", (byte) Byte.MAX_VALUE); + message.setBytes("bytes", _bytes); + message.setChar("char", (char) 'c'); + message.setDouble("double", (double) Double.MAX_VALUE); + message.setFloat("float", (float) Float.MAX_VALUE); + message.setFloat("smallfloat", 100); + message.setInt("messageNumber", i); + message.setInt("int", (int) Integer.MAX_VALUE); + message.setLong("long", (long) Long.MAX_VALUE); + message.setShort("short", (short) Short.MAX_VALUE); + message.setString("message", MESSAGE + i); + //Test Setting Object Values + message.setObject("object-bool", true); + message.setObject("object-byte", Byte.MAX_VALUE); + message.setObject("object-bytes", _bytes); + message.setObject("object-char", 'c'); + message.setObject("object-double", Double.MAX_VALUE); + message.setObject("object-float", Float.MAX_VALUE); + message.setObject("object-int", Integer.MAX_VALUE); + message.setObject("object-long", Long.MAX_VALUE); + message.setObject("object-short", Short.MAX_VALUE); - message.setObject("object-bool", true); - message.setObject("object-byte", Byte.MAX_VALUE); - message.setObject("object-bytes", _bytes); - message.setObject("object-char", 'c'); - message.setObject("object-double", Double.MAX_VALUE); - message.setObject("object-float", Float.MAX_VALUE); - message.setObject("object-int", Integer.MAX_VALUE); - message.setObject("object-long", Long.MAX_VALUE); - message.setObject("object-short", Short.MAX_VALUE); + //Set a null String value + message.setString("nullString", null); + // Highlight protocol problem + message.setString("emptyString", ""); - producer.send(message); - } } void waitFor(int count) throws InterruptedException @@ -152,80 +162,1014 @@ public class MapMessageTest extends TestCase implements MessageListener for (JMSMapMessage m : received) { actual.add(m.getString("message")); - assertEqual(m.getInt("messageNumber"), count); + testMapValues(m, count); - assertEqual(count / 2 == 0, m.getBoolean("odd")); - assertEqual((byte) Byte.MAX_VALUE, m.getByte("byte")); + testCorrectExceptions(m); - assertBytesEqual(_bytes, m.getBytes("bytes")); - assertEqual((char) 'c', m.getChar("char")); - assertEqual((double) Double.MAX_VALUE, m.getDouble("double")); - assertEqual((float) Float.MAX_VALUE, m.getFloat("float")); + testMessageWriteStatus(m); - assertEqual(count, m.getInt("messageNumber")); - assertEqual((int) Integer.MAX_VALUE, m.getInt("int")); - assertEqual((long) Long.MAX_VALUE, m.getLong("long")); - assertEqual((short) Short.MAX_VALUE, m.getShort("short")); + testPropertyWriteStatus(m); - assertEqual(true, m.getObject("object-bool")); - assertEqual(Byte.MAX_VALUE, m.getObject("object-byte")); - assertBytesEqual(_bytes, (byte[]) m.getObject("object-bytes")); - assertEqual('c', m.getObject("object-char")); - assertEqual(Double.MAX_VALUE, m.getObject("object-double")); - assertEqual(Float.MAX_VALUE, m.getObject("object-float")); - assertEqual(Integer.MAX_VALUE, m.getObject("object-int")); - assertEqual(Long.MAX_VALUE, m.getObject("object-long")); - assertEqual(Short.MAX_VALUE, m.getObject("object-short")); + count++; + } + } + private void testCorrectExceptions(JMSMapMessage m) throws JMSException + { + testBoolean(m); - try - { - m.setInt("testint", 3); - fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - //normal execution - } + testByte(m); - m.clearBody(); + testBytes(m); - try - { - m.setInt("testint", 3); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } + testChar(m); - //Check property write status - try - { - m.setStringProperty("test", "test"); - Assert.fail("Message should not be writeable"); - } - catch (MessageNotWriteableException mnwe) - { - //normal execution - } + testDouble(m); - m.clearProperties(); + testFloat(m); - try - { - m.setStringProperty("test", "test"); - } - catch (MessageNotWriteableException mnwe) - { - Assert.fail("Message should be writeable"); - } + testInt(m); - count++; + testLong(m); + + testShort(m); + + testString(m); + } + + private void testString(JMSMapMessage m) throws JMSException + { + + Assert.assertFalse(m.getBoolean("message")); + + try + { + m.getByte("message"); + fail("Exception Expected."); + } + catch (NumberFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("message"); + fail("Exception Expected."); + } + catch (NumberFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getChar("message"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + try + { + m.getInt("message"); + fail("Exception Expected."); + } + catch (NumberFormatException nfe) + { + //normal execution + } + try + { + m.getLong("message"); + fail("Exception Expected."); + } + catch (NumberFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getFloat("message"); + fail("Exception Expected."); + } + catch (NumberFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("message"); + fail("Exception Expected."); + } + catch (NumberFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("message"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals(MESSAGE + m.getInt("messageNumber"), m.getString("message")); + } + + private void testShort(JMSMapMessage m) throws JMSException + { + + //Try bad reads + try + { + m.getBoolean("short"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("short"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals(Short.MAX_VALUE, m.getShort("short")); + + //Try bad reads + try + { + m.getChar("short"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + Assert.assertEquals(Short.MAX_VALUE, m.getInt("short")); + + Assert.assertEquals(Short.MAX_VALUE, m.getLong("short")); + + //Try bad reads + try + { + m.getFloat("short"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("short"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("short"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + Short.MAX_VALUE, m.getString("short")); + } + + private void testLong(JMSMapMessage m) throws JMSException + { + + //Try bad reads + try + { + m.getBoolean("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getChar("long"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + try + { + m.getInt("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals(Long.MAX_VALUE, m.getLong("long")); + + //Try bad reads + try + { + m.getFloat("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("long"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + Long.MAX_VALUE, m.getString("long")); + } + + private void testDouble(JMSMapMessage m) throws JMSException + { + + //Try bad reads + try + { + m.getBoolean("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getChar("double"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + try + { + m.getInt("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + try + { + m.getLong("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getFloat("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + + Assert.assertEquals(Double.MAX_VALUE, m.getDouble("double")); + + //Try bad reads + try + { + m.getBytes("double"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + Double.MAX_VALUE, m.getString("double")); + } + + + private void testFloat(JMSMapMessage m) throws JMSException + { + + //Try bad reads + try + { + m.getBoolean("float"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("float"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("float"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getChar("float"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + try + { + m.getInt("float"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + try + { + m.getLong("float"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + + Assert.assertEquals(Float.MAX_VALUE, m.getFloat("float")); + + Assert.assertEquals(_smallfloat, (float) m.getDouble("smallfloat")); + + //Try bad reads + try + { + m.getBytes("float"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + Float.MAX_VALUE, m.getString("float")); + } + + + private void testInt(JMSMapMessage m) throws JMSException + { + + //Try bad reads + try + { + m.getBoolean("int"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("int"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("int"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getChar("int"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + Assert.assertEquals(Integer.MAX_VALUE, m.getInt("int")); + + Assert.assertEquals(Integer.MAX_VALUE, (int) m.getLong("int")); + + //Try bad reads + try + { + m.getFloat("int"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("int"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("int"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + Integer.MAX_VALUE, m.getString("int")); + } + + + private void testChar(JMSMapMessage m) throws JMSException + { + + //Try bad reads + try + { + m.getBoolean("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals('c', m.getChar("char")); + + try + { + m.getInt("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + try + { + m.getLong("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getFloat("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("char"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + 'c', m.getString("char")); + } + + private void testBytes(JMSMapMessage m) throws JMSException + { + //Try bad reads + try + { + m.getBoolean("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getByte("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getShort("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getChar("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + try + { + m.getInt("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + try + { + m.getLong("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getFloat("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution } + //Try bad reads + try + { + m.getDouble("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + + assertBytesEqual(_bytes, m.getBytes("bytes")); + + try + { + m.getString("bytes"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + + } + + private void testByte(JMSMapMessage m) throws JMSException + { + //Try bad reads + try + { + m.getBoolean("byte"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals(Byte.MAX_VALUE, m.getByte("byte")); + + Assert.assertEquals((short) Byte.MAX_VALUE, m.getShort("byte")); + + //Try bad reads + try + { + m.getChar("byte"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + + //Reading a byte as an int is ok + Assert.assertEquals((short) Byte.MAX_VALUE, m.getInt("byte")); + + Assert.assertEquals((short) Byte.MAX_VALUE, m.getLong("byte")); + + //Try bad reads + try + { + m.getFloat("byte"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("byte"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("byte"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + Byte.MAX_VALUE, m.getString("byte")); + + } + + private void testBoolean(JMSMapMessage m) throws JMSException + { + + Assert.assertEquals((m.getInt("messageNumber") / 2) == 0, m.getBoolean("odd")); + + //Try bad reads + try + { + m.getByte("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + //Try bad reads + try + { + m.getShort("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getChar("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException npe) + { + //normal execution + } + //Try bad reads + try + { + m.getInt("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getLong("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getFloat("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getDouble("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + //Try bad reads + try + { + m.getBytes("odd"); + fail("Exception Expected."); + } + catch (MessageFormatException nfe) + { + //normal execution + } + + Assert.assertEquals("" + ((m.getInt("messageNumber") / 2) == 0), m.getString("odd")); + } + + + private void testPropertyWriteStatus(JMSMapMessage m) throws JMSException + { + //Check property write status + try + { + m.setStringProperty("test", "test"); + Assert.fail("Message should not be writeable"); + } + catch (MessageNotWriteableException mnwe) + { + //normal execution + } + + m.clearProperties(); + + try + { + m.setStringProperty("test", "test"); + } + catch (MessageNotWriteableException mnwe) + { + Assert.fail("Message should be writeable"); + } + } + + private void testMessageWriteStatus(JMSMapMessage m) throws JMSException + { + try + { + m.setInt("testint", 3); + fail("Message should not be writeable"); + } + catch (MessageNotWriteableException mnwe) + { + //normal execution + } + + m.clearBody(); + + try + { + m.setInt("testint", 3); + } + catch (MessageNotWriteableException mnwe) + { + Assert.fail("Message should be writeable"); + } + } + + private void testMapValues(JMSMapMessage m, int count) throws JMSException + { + //Test get<Primiative> + + //Boolean + assertEqual(count / 2 == 0, m.getBoolean("odd")); + assertEqual("" + (count / 2 == 0), m.getString("odd")); + + //Byte + assertEqual(Byte.MAX_VALUE, m.getByte("byte")); + assertEqual("" + Byte.MAX_VALUE, m.getString("byte")); + + //Bytes + assertBytesEqual(_bytes, m.getBytes("bytes")); + + //Char + assertEqual('c', m.getChar("char")); + + //Double + assertEqual(Double.MAX_VALUE, m.getDouble("double")); + assertEqual("" + Double.MAX_VALUE, m.getString("double")); + + //Float + assertEqual(Float.MAX_VALUE, m.getFloat("float")); + assertEqual(_smallfloat, (float) m.getDouble("smallfloat")); + assertEqual("" + Float.MAX_VALUE, m.getString("float")); + + //Integer + assertEqual(Integer.MAX_VALUE, m.getInt("int")); + assertEqual("" + Integer.MAX_VALUE, m.getString("int")); + assertEqual(count, m.getInt("messageNumber")); + + //long + assertEqual(Long.MAX_VALUE, m.getLong("long")); + assertEqual("" + Long.MAX_VALUE, m.getString("long")); + + //Short + assertEqual(Short.MAX_VALUE, m.getShort("short")); + assertEqual("" + Short.MAX_VALUE, m.getString("short")); + assertEqual((int) Short.MAX_VALUE, m.getInt("short")); + + //String + assertEqual(MESSAGE + count, m.getString("message")); + + //Test getObjects + assertEqual(true, m.getObject("object-bool")); + assertEqual(Byte.MAX_VALUE, m.getObject("object-byte")); + assertBytesEqual(_bytes, (byte[]) m.getObject("object-bytes")); + assertEqual('c', m.getObject("object-char")); + assertEqual(Double.MAX_VALUE, m.getObject("object-double")); + assertEqual(Float.MAX_VALUE, m.getObject("object-float")); + assertEqual(Integer.MAX_VALUE, m.getObject("object-int")); + assertEqual(Long.MAX_VALUE, m.getObject("object-long")); + assertEqual(Short.MAX_VALUE, m.getObject("object-short")); - assertEqual(messages.iterator(), actual.iterator()); + //Check Special values + assertTrue(m.getString("nullString") == null); + assertEqual("", m.getString("emptyString")); } private void assertBytesEqual(byte[] expected, byte[] actual) @@ -279,6 +1223,7 @@ public class MapMessageTest extends TestCase implements MessageListener { synchronized(received) { + _logger.info("****************** Recevied Messgage:" + (JMSMapMessage) message); received.add((JMSMapMessage) message); received.notify(); } @@ -303,6 +1248,6 @@ public class MapMessageTest extends TestCase implements MessageListener public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(MapMessageTest.class)); + return new junit.framework.TestSuite(MapMessageTest.class); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java index 16ac8596c3..c88024f39f 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java @@ -6,9 +6,9 @@ * 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 @@ -19,18 +19,15 @@ */ package org.apache.qpid.test.unit.basic; +import junit.framework.TestCase; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.test.VMBrokerSetup; import javax.jms.*; -import junit.framework.TestCase; - public class MultipleConnectionTest extends TestCase { public static final String _defaultBroker = "vm://:1"; @@ -138,6 +135,19 @@ public class MultipleConnectionTest extends TestCase } } + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + private static void waitForCompletion(int expected, long wait, Receiver[] receivers) throws InterruptedException { for (int i = 0; i < receivers.length; i++) @@ -209,6 +219,6 @@ public class MultipleConnectionTest extends TestCase public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(MultipleConnectionTest.class)); + return new junit.framework.TestSuite(MultipleConnectionTest.class); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java index e7d7159bd8..3f726ae5ab 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ObjectMessageTest.java @@ -6,9 +6,9 @@ * 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 @@ -19,28 +19,21 @@ */ package org.apache.qpid.test.unit.basic; +import junit.framework.Assert; +import junit.framework.TestCase; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.message.JMSObjectMessage; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.client.transport.TransportConnection; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.MessageNotWriteableException; +import javax.jms.*; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import junit.framework.TestCase; -import junit.framework.Assert; - public class ObjectMessageTest extends TestCase implements MessageListener { private AMQConnection _connection; @@ -54,6 +47,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener protected void setUp() throws Exception { super.setUp(); + TransportConnection.createVMBroker(1); try { init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); @@ -67,6 +61,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener protected void tearDown() throws Exception { super.tearDown(); + TransportConnection.killAllVMBrokers(); } private void init(AMQConnection connection) throws Exception @@ -263,6 +258,6 @@ public class ObjectMessageTest extends TestCase implements MessageListener public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(ObjectMessageTest.class)); + return new junit.framework.TestSuite(ObjectMessageTest.class); } } 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 index 02f371e81b..7f76baa157 100644 --- 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 @@ -27,7 +27,7 @@ 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.qpid.testutil.VMBrokerSetup; import javax.jms.Destination; import javax.jms.JMSException; @@ -119,8 +119,17 @@ public class PropertyValueTest extends TestCase implements MessageListener m.setJMSPriority(100); // Queue - Queue q = //_session.createTemporaryQueue(); - q = new AMQQueue("TestReply"); + Queue q; + + if (i / 2 == 0) + { + q = _session.createTemporaryQueue(); + } + else + { + q = new AMQQueue("TestReply"); + } + m.setJMSReplyTo(q); m.setStringProperty("TempQueue", q.toString()); @@ -173,6 +182,8 @@ public class PropertyValueTest extends TestCase implements MessageListener (int) Integer.MAX_VALUE, m.getIntProperty("Int")); Assert.assertEquals("Check CorrelationID properties are correctly transported", "Correlation", m.getJMSCorrelationID()); + + _logger.warn("getJMSPriority not being verified."); // Assert.assertEquals("Check Priority properties are correctly transported", // 100, m.getJMSPriority()); @@ -180,8 +191,9 @@ public class PropertyValueTest extends TestCase implements MessageListener Assert.assertEquals("Check ReplyTo properties are correctly transported", m.getStringProperty("TempQueue"), m.getJMSReplyTo().toString()); -// Assert.assertEquals("Check Type properties are correctly transported", -// "Test", m.getJMSType()); + 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", diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionTest.java new file mode 100644 index 0000000000..f4814795c4 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionTest.java @@ -0,0 +1,67 @@ +/* + * + * 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 junit.framework.TestCase; +import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQTopic; + +import javax.jms.*; + +/** + * @author Apache Software Foundation + */ +public class PubSubTwoConnectionTest extends TestCase +{ + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + protected void tearDown() throws Exception + { + super.tearDown(); + } + + /** + * This tests that a consumer is set up synchronously + * @throws Exception + */ + public void testTwoConnections() throws Exception + { + Topic topic = new AMQTopic("MyTopic"); + Connection con1 = new AMQConnection("vm://:1", "guest", "guest", "Client1", "/test_path"); + Session session1 = con1.createSession(false, AMQSession.NO_ACKNOWLEDGE); + MessageProducer producer = session1.createProducer(topic); + + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "Client2", "/test_path"); + Session session2 = con2.createSession(false, AMQSession.NO_ACKNOWLEDGE); + MessageConsumer consumer = session2.createConsumer(topic); + con2.start(); + producer.send(session1.createTextMessage("Hello")); + TextMessage tm1 = (TextMessage) consumer.receive(2000); + assertNotNull(tm1); + assertEquals("Hello", tm1.getText()); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java index 28b0a1c2f7..27a2ccb32e 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/SelectorTest.java @@ -26,7 +26,7 @@ import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.BasicMessageProducer; import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.test.VMBrokerSetup; + import org.apache.log4j.Logger; import javax.jms.JMSException; @@ -57,6 +57,7 @@ public class SelectorTest extends TestCase implements MessageListener protected void tearDown() throws Exception { super.tearDown(); + TransportConnection.killAllVMBrokers(); } private void init(AMQConnection connection) throws Exception @@ -71,7 +72,7 @@ public class SelectorTest extends TestCase implements MessageListener connection.start(); - String selector= null; + String selector = null; // selector = "Cost = 2 AND JMSDeliveryMode=" + DeliveryMode.NON_PERSISTENT; // selector = "JMSType = Special AND Cost = 2 AND AMQMessageID > 0 AND JMSDeliveryMode=" + DeliveryMode.NON_PERSISTENT; @@ -135,6 +136,6 @@ public class SelectorTest extends TestCase implements MessageListener public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(SelectorTest.class)); + return new junit.framework.TestSuite(SelectorTest.class); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java index 6fa8ab95bf..9ddb290e73 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/SessionStartTest.java @@ -26,7 +26,7 @@ import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import javax.jms.JMSException; import javax.jms.Message; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java index cd3954fbcb..903f6a9da9 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/TextMessageTest.java @@ -21,13 +21,10 @@ package org.apache.qpid.test.unit.basic; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.message.JMSTextMessage; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import org.apache.log4j.Logger; import java.util.ArrayList; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java index 9b46c5b18a..63b5bf48b7 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java @@ -28,7 +28,7 @@ import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.AMQException; import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import java.lang.reflect.Method; import javax.jms.*; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java index af4673856e..1c8f925d72 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/AMQSessionTest.java @@ -27,7 +27,7 @@ import org.apache.qpid.client.AMQTopic; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import org.apache.qpid.url.URLSyntaxException; import javax.jms.JMSException; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java index d3a05c3d75..d323f042e9 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java @@ -24,7 +24,7 @@ import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import org.apache.log4j.Logger; import javax.jms.*; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java index d7862d047f..0da4147351 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java @@ -22,12 +22,10 @@ package org.apache.qpid.test.unit.client.connection; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQAuthenticationException; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.AMQException; import org.apache.qpid.AMQConnectionException; import org.apache.qpid.AMQUnresolvedAddressException; -import org.apache.qpid.test.VMBrokerSetup; import javax.jms.Connection; @@ -40,6 +38,18 @@ public class ConnectionTest extends TestCase String _broker_NotRunning = "vm://:2"; String _broker_BadDNS = "tcp://hg3sgaaw4lgihjs"; + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + protected void tearDown() throws Exception + { + TransportConnection.killAllVMBrokers(); + } + public void testSimpleConnection() { try @@ -102,8 +112,30 @@ public class ConnectionTest extends TestCase } } + public void testClientIdCannotBeChanged() throws Exception + { + Connection connection = new AMQConnection(_broker, "guest", "guest", + "fred", "/test"); + try + { + connection.setClientID("someClientId"); + fail("No IllegalStateException thrown when resetting clientid"); + } + catch (javax.jms.IllegalStateException e) + { + // PASS + } + } + + public void testClientIdIsPopulatedAutomatically() throws Exception + { + Connection connection = new AMQConnection(_broker, "guest", "guest", + null, "/test"); + assertNotNull(connection.getClientID()); + } + public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(ConnectionTest.class)); + return new junit.framework.TestSuite(ConnectionTest.class); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java index 9218424a5e..dde3d53299 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java @@ -22,7 +22,7 @@ package org.apache.qpid.test.unit.client.forwardall; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import junit.framework.TestCase; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java index 2a76c920b1..a0e4aa9787 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java @@ -7,9 +7,9 @@ * 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 @@ -20,14 +20,15 @@ */ package org.apache.qpid.test.unit.client.message; +import junit.framework.TestCase; import org.apache.qpid.client.message.JMSBytesMessage; import org.apache.qpid.client.message.TestMessageHelper; +import javax.jms.MessageEOFException; import javax.jms.MessageNotReadableException; import javax.jms.MessageNotWriteableException; -import javax.jms.MessageEOFException; - -import junit.framework.TestCase; +import javax.jms.MessageFormatException; +import java.util.HashMap; public class BytesMessageTest extends TestCase { @@ -82,6 +83,18 @@ public class BytesMessageTest extends TestCase bm.writeInt(10); } + public void testWriteBoolean() throws Exception + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.writeBoolean(true); + bm.writeBoolean(false); + bm.reset(); + boolean val = bm.readBoolean(); + assertEquals(true, val); + val = bm.readBoolean(); + assertEquals(false, val); + } + public void testWriteInt() throws Exception { JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); @@ -102,6 +115,61 @@ public class BytesMessageTest extends TestCase assertEquals("Bananas", res); } + public void testWriteBytes() throws Exception + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + byte[] bytes = {1,2,3,4}; + bm.writeBytes(bytes, 1, 2); + bm.reset(); + bytes = new byte[2]; + bm.readBytes(bytes); + assertEquals(2, bytes[0]); + assertEquals(3, bytes[1]); + } + + public void testWriteObject() throws Exception + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.writeObject(new Boolean(true)); + bm.writeObject(new Boolean(false)); + bm.writeObject(new Byte((byte)2)); + bm.writeObject(new byte[]{1,2,3,4}); + bm.writeObject(new Character('g')); + bm.writeObject(new Short((short) 29)); + bm.writeObject(new Integer(101)); + bm.writeObject(new Long(50003222L)); + bm.writeObject("Foobar"); + bm.writeObject(new Float(1.7f)); + bm.writeObject(new Double(8.7d)); + bm.reset(); + assertTrue(bm.readBoolean()); + assertTrue(!bm.readBoolean()); + assertEquals((byte)2, bm.readByte()); + byte[] bytes = new byte[4]; + bm.readBytes(bytes); + assertEquals('g', bm.readChar()); + assertEquals((short) 29, bm.readShort()); + assertEquals(101, bm.readInt()); + assertEquals(50003222L, bm.readLong()); + assertEquals("Foobar", bm.readUTF()); + assertEquals(1.7f, bm.readFloat()); + assertEquals(8.7d, bm.readDouble()); + } + + public void testWriteObjectRejectsNonPrimitives() throws Exception + { + try + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.writeObject(new HashMap()); + fail("expected MessageFormatException was not thrown"); + } + catch (MessageFormatException e) + { + // pass + } + } + public void testWriteObjectThrowsNPE() throws Exception { try @@ -126,7 +194,83 @@ public class BytesMessageTest extends TestCase bm.writeBoolean(true); bm.reset(); boolean result = bm.readBoolean(); - assertTrue(result); + assertTrue(result); + } + + public void testReadUnsignedByte() throws Exception + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.writeByte((byte) 9); + bm.reset(); + int result = bm.readUnsignedByte(); + assertEquals(9, result); + } + + public void testReadUnsignedShort() throws Exception + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.writeShort((byte) 9); + bm.reset(); + int result = bm.readUnsignedShort(); + assertEquals(9, result); + } + + public void testReadBytesChecksNull() throws Exception + { + try + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.readBytes(null); + } + catch (IllegalArgumentException e) + { + // pass + } + + try + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + bm.readBytes(null, 1); + } + catch (IllegalArgumentException e) + { + // pass + } + } + + public void testReadBytesChecksMaxSize() throws Exception + { + try + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + byte[] bytes = new byte[100]; + bm.readBytes(bytes, 120); + } + catch (IllegalArgumentException e) + { + // pass + } + } + + public void testReadBytesReturnsCorrectLengths() throws Exception + { + JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); + byte[] bytes = {2, 3}; + bm.writeBytes(bytes); + bm.reset(); + int len = bm.readBytes(bytes); + assertEquals(2, len); + len = bm.readBytes(bytes); + assertEquals(-1, len); + len = bm.readBytes(bytes, 2); + assertEquals(-1, len); + bm.reset(); + len = bm.readBytes(bytes, 2); + assertEquals(2, len); + bm.reset(); + len = bm.readBytes(bytes, 1); + assertEquals(1, len); + } public void testEOFByte() throws Exception @@ -408,16 +552,6 @@ public class BytesMessageTest extends TestCase assertEquals((byte)0, result[2]); } - public void testToBodyString() throws Exception - { - JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); - final String testText = "This is a test"; - bm.writeUTF(testText); - bm.reset(); - String result = bm.toBodyString(); - assertEquals(testText, result); - } - public void testToBodyStringWithNull() throws Exception { JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/MapMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/MapMessageTest.java index f55f2428ce..bd4b3b3987 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/MapMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/MapMessageTest.java @@ -14,15 +14,14 @@ * "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. + * under the License. + * * - * */ package org.apache.qpid.test.unit.client.message; -import junit.framework.TestCase; import junit.framework.Assert; -import org.apache.qpid.framing.PropertyFieldTable; +import junit.framework.TestCase; import org.apache.qpid.client.message.JMSMapMessage; import org.apache.qpid.client.message.TestMessageHelper; @@ -103,6 +102,27 @@ public class MapMessageTest extends TestCase { Assert.fail("JMSException received." + e); } + + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + + mm.setString("value", null); + char c = mm.getChar("value"); + fail("Expected NullPointerException"); + + } + catch (NullPointerException e) + { + ; // pass + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + + + } public void testDoubleLookup() @@ -203,7 +223,7 @@ public class MapMessageTest extends TestCase { JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); mm.getByte("random"); - Assert.fail("NumberFormatException should be received."); + Assert.fail("NumberFormatException expected"); } catch (NumberFormatException e) { @@ -221,7 +241,12 @@ public class MapMessageTest extends TestCase try { JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); - Assert.assertEquals(null, mm.getBytes("random")); + mm.getBytes("random"); + Assert.fail("MessageFormatException expected"); + } + catch (MessageFormatException mfe) + { + //normal path } catch (JMSException e) { @@ -235,9 +260,9 @@ public class MapMessageTest extends TestCase { JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); mm.getChar("random"); - Assert.fail("NullPointerException should be received."); + Assert.fail("MessageFormatException expected"); } - catch (NullPointerException e) + catch (MessageFormatException e) { //normal execution } @@ -325,7 +350,7 @@ public class MapMessageTest extends TestCase { JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); mm.getShort("random"); - Assert.fail("NumberFormatException should be received."); + Assert.fail("NumberFormatException should be received."); } catch (NumberFormatException e) { diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java index 9425b7c304..bbd1870168 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/ObjectMessageTest.java @@ -24,9 +24,7 @@ import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import javax.jms.MessageListener; import javax.jms.MessageProducer; @@ -36,6 +34,7 @@ import javax.jms.ObjectMessage; import java.io.Serializable; import java.util.HashMap; import java.util.ArrayList; +import java.util.Arrays; import junit.framework.TestCase; @@ -44,6 +43,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener private AMQConnection connection; private AMQDestination destination; private AMQSession session; + private MessageProducer producer; private Serializable[] data; private volatile boolean waiting; private int received; @@ -57,6 +57,13 @@ public class ObjectMessageTest extends TestCase implements MessageListener connection = new AMQConnection(_broker, "guest", "guest", randomize("Client"), "/test_path"); destination = new AMQQueue(randomize("LatencyTest"), true); session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); + + //set up a consumer + session.createConsumer(destination).setMessageListener(this); + connection.start(); + + //create a publisher + producer = session.createProducer(destination, false, false, true); A a1 = new A(1, "A"); A a2 = new A(2, "a"); B b = new B(1, "B"); @@ -83,7 +90,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener _broker = broker; } - public void test() throws Exception + public void testSendAndReceive() throws Exception { try { @@ -102,16 +109,74 @@ public class ObjectMessageTest extends TestCase implements MessageListener } } - private void send() throws Exception + public void testSetObjectPropertyForString() throws Exception { - //set up a consumer - session.createConsumer(destination).setMessageListener(this); - connection.start(); + String testStringProperty = "TestStringProperty"; + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestStringProperty",testStringProperty); + assertEquals(testStringProperty, msg.getObjectProperty("TestStringProperty")); + } - //create a publisher - MessageProducer producer = session.createProducer(destination, false, false, true); + public void testSetObjectPropertyForBoolean() throws Exception + { + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestBooleanProperty",Boolean.TRUE); + assertEquals(Boolean.TRUE, msg.getObjectProperty("TestBooleanProperty")); + } + public void testSetObjectPropertyForByte() throws Exception + { + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestByteProperty",Byte.MAX_VALUE); + assertEquals(Byte.MAX_VALUE, msg.getObjectProperty("TestByteProperty")); + } + public void testSetObjectPropertyForShort() throws Exception + { + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestShortProperty",Short.MAX_VALUE); + assertEquals(Short.MAX_VALUE, msg.getObjectProperty("TestShortProperty")); + } + public void testSetObjectPropertyForInteger() throws Exception + { + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestIntegerProperty",Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, msg.getObjectProperty("TestIntegerProperty")); + } + + public void testSetObjectPropertyForDouble() throws Exception + { + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestDoubleProperty",Double.MAX_VALUE); + assertEquals(Double.MAX_VALUE, msg.getObjectProperty("TestDoubleProperty")); + } + + public void testSetObjectPropertyForFloat() throws Exception + { + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestFloatProperty",Float.MAX_VALUE); + assertEquals(Float.MAX_VALUE, msg.getObjectProperty("TestFloatProperty")); + } + + public void testSetObjectPropertyForByteArray() throws Exception + { + byte[] array = {1,2,3,4,5}; + ObjectMessage msg = session.createObjectMessage(data[0]); + msg.setObjectProperty("TestByteArrayProperty",array); + assertTrue(Arrays.equals(array,(byte[])msg.getObjectProperty("TestByteArrayProperty"))); + } + + + public void testSetObjectForNull() throws Exception + { + ObjectMessage msg = session.createObjectMessage(); + msg.setObject(null); + assertNull(msg.getObject()); + } + + + private void send() throws Exception + { for (int i = 0; i < data.length; i++) { ObjectMessage msg; @@ -207,7 +272,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener { System.out.println("Usage: <broker>"); } - new ObjectMessageTest(broker).test(); + new ObjectMessageTest(broker).testSendAndReceive(); } private static class A implements Serializable diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java new file mode 100644 index 0000000000..727881de96 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java @@ -0,0 +1,616 @@ +/* + * + * 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.client.message; + +import junit.framework.TestCase; +import org.apache.qpid.client.message.JMSStreamMessage; +import org.apache.qpid.client.message.TestMessageHelper; + +import javax.jms.*; +import java.util.HashMap; + +/** + * @author Apache Software Foundation + */ +public class StreamMessageTest extends TestCase +{ + /** + * Tests that on creation a call to getBodyLength() throws an exception + * if null was passed in during creation + */ + public void testNotReadableOnCreationWithNull() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.readByte(); + fail("expected exception did not occur"); + } + catch (MessageNotReadableException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageNotReadableException, got " + e); + } + } + + public void testResetMakesReadble() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeInt(10); + bm.reset(); + bm.writeInt(12); + fail("expected exception did not occur"); + } + catch (MessageNotWriteableException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageNotWriteableException, got " + e); + } + } + + public void testClearBodyMakesWritable() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeInt(10); + bm.reset(); + bm.clearBody(); + bm.writeInt(10); + } + + public void testWriteBoolean() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeBoolean(true); + bm.writeBoolean(false); + bm.reset(); + boolean val = bm.readBoolean(); + assertEquals(true, val); + val = bm.readBoolean(); + assertEquals(false, val); + } + + public void testWriteInt() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeInt(10); + bm.reset(); + int val = bm.readInt(); + assertTrue(val == 10); + } + + public void testWriteString() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeString("Bananas"); + bm.reset(); + String res = bm.readString(); + assertEquals("Bananas", res); + } + + public void testWriteBytes() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + byte[] bytes = {1,2,3,4}; + bm.writeBytes(bytes, 1, 2); + bm.reset(); + bytes = new byte[2]; + bm.readBytes(bytes); + assertEquals(2, bytes[0]); + assertEquals(3, bytes[1]); + } + + public void testWriteObject() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeObject(new Boolean(true)); + bm.writeObject(new Boolean(false)); + bm.writeObject(new Byte((byte)2)); + bm.writeObject(new byte[]{1,2,3,4}); + bm.writeObject(new Character('g')); + bm.writeObject(new Short((short) 29)); + bm.writeObject(new Integer(101)); + bm.writeObject(new Long(50003222L)); + bm.writeObject("Foobar"); + bm.writeObject(new Float(1.7f)); + bm.writeObject(new Double(8.7d)); + bm.reset(); + assertTrue(bm.readBoolean()); + assertTrue(!bm.readBoolean()); + assertEquals((byte)2, bm.readByte()); + byte[] bytes = new byte[4]; + bm.readBytes(bytes); + assertEquals('g', bm.readChar()); + assertEquals((short) 29, bm.readShort()); + assertEquals(101, bm.readInt()); + assertEquals(50003222L, bm.readLong()); + assertEquals("Foobar", bm.readString()); + assertEquals(1.7f, bm.readFloat()); + assertEquals(8.7d, bm.readDouble()); + } + + public void testWriteObjectRejectsNonPrimitives() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeObject(new HashMap()); + fail("expected MessageFormatException was not thrown"); + } + catch (MessageFormatException e) + { + // pass + } + } + + public void testReadBoolean() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeBoolean(true); + bm.reset(); + boolean result = bm.readBoolean(); + assertTrue(result); + } + + public void testReadBytesChecksNull() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.readBytes(null); + } + catch (IllegalArgumentException e) + { + // pass + } + } + + public void testReadBytesReturnsCorrectLengths() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + byte[] bytes = {2, 3}; + bm.writeBytes(bytes); + bm.writeBytes(null); + bm.writeBytes(new byte[]{}); + bm.reset(); + int len = bm.readBytes(bytes); + assertEquals(2, len); + len = bm.readBytes(bytes); + assertEquals(-1, len); + len = bm.readBytes(bytes); + assertEquals(-1, len); + len = bm.readBytes(bytes); + assertEquals(0, len); + } + + public void testReadBytesFollowedByPrimitive() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeBytes(new byte[]{2, 3, 4, 5, 6, 7, 8}); + bm.writeBytes(new byte[]{2, 3, 4, 5, 6, 7}); + bm.writeString("Foo"); + bm.reset(); + int len; + do + { + len = bm.readBytes(new byte[2]); + } + while (len == 2); + + do + { + len = bm.readBytes(new byte[2]); + } + while (len == 2); + + assertEquals("Foo", bm.readString()); + } + + public void testReadMultipleByteArrays() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + byte[] bytes = {2, 3, 4}; + bm.writeBytes(bytes); + bm.writeBytes(bytes); + bm.reset(); + byte[] result = new byte[2]; + int len = bm.readBytes(result); + assertEquals(2, len); + len = bm.readBytes(result); + assertEquals(1, len); + len = bm.readBytes(result); + assertEquals(2, len); + } + + public void testEOFByte() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeByte((byte)1); + bm.reset(); + bm.readByte(); + // should throw + bm.readByte(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFBoolean() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeBoolean(true); + bm.reset(); + bm.readBoolean(); + // should throw + bm.readBoolean(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFChar() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeChar('A'); + bm.reset(); + bm.readChar(); + // should throw + bm.readChar(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFDouble() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeDouble(1.3d); + bm.reset(); + bm.readDouble(); + // should throw + bm.readDouble(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFFloat() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeFloat(1.3f); + bm.reset(); + bm.readFloat(); + // should throw + bm.readFloat(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFInt() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeInt(99); + bm.reset(); + bm.readInt(); + // should throw + bm.readInt(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFLong() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeLong(4L); + bm.reset(); + bm.readLong(); + // should throw + bm.readLong(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testEOFShort() throws Exception + { + try + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeShort((short)4); + bm.reset(); + bm.readShort(); + // should throw + bm.readShort(); + fail("expected exception did not occur"); + } + catch (MessageEOFException m) + { + // ok + } + catch (Exception e) + { + fail("expected MessageEOFException, got " + e); + } + } + + public void testToBodyStringWithNull() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.reset(); + String result = bm.toBodyString(); + assertNull(result); + } + + private void checkConversionsFail(StreamMessage sm, int[] conversions) throws JMSException + { + for (int conversion : conversions) + { + try + { + switch (conversion) + { + case 0: + sm.readBoolean(); + break; + case 1: + sm.readByte(); + break; + case 2: + sm.readShort(); + break; + case 3: + sm.readChar(); + break; + case 4: + sm.readInt(); + break; + case 5: + sm.readLong(); + break; + case 6: + sm.readFloat(); + break; + case 7: + sm.readDouble(); + break; + case 8: + sm.readString(); + break; + case 9: + sm.readBytes(new byte[3]); + break; + } + fail("MessageFormatException was not thrown"); + } + catch (MessageFormatException e) + { + // PASS + } + sm.reset(); + } + } + public void testBooleanConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeBoolean(true); + bm.reset(); + String result = bm.readString(); + assertEquals("true", result); + bm.reset(); + checkConversionsFail(bm, new int[]{1,2,3,4,5,6,7,9}); + } + + public void testByteConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeByte((byte) 43); + bm.reset(); + assertEquals(43, bm.readShort()); + bm.reset(); + assertEquals(43, bm.readInt()); + bm.reset(); + assertEquals(43, bm.readLong()); + bm.reset(); + String result = bm.readString(); + assertEquals("43", result); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 3, 6, 7, 9}); + } + + public void testShortConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeShort((short) 87); + bm.reset(); + assertEquals(87, bm.readInt()); + bm.reset(); + assertEquals(87, bm.readLong()); + bm.reset(); + assertEquals("87", bm.readString()); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 1, 3, 6, 7, }); + } + + public void testCharConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeChar('d'); + bm.reset(); + assertEquals("d", bm.readString()); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 1, 2, 4, 5, 6, 7, 9}); + } + + public void testIntConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeInt(167); + bm.reset(); + assertEquals(167, bm.readLong()); + bm.reset(); + assertEquals("167", bm.readString()); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 1, 2, 3, 6, 7, 9}); + } + + public void testLongConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeLong(1678); + bm.reset(); + assertEquals("1678", bm.readString()); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 1, 2, 3, 4, 6, 7, 9}); + } + + public void testFloatConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeFloat(6.2f); + bm.reset(); + assertEquals(6.2d, bm.readDouble(), 0.01); + bm.reset(); + assertEquals("6.2", bm.readString()); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 1, 2, 3, 4, 5, 9}); + } + + public void testDoubleConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeDouble(88.35d); + bm.reset(); + assertEquals("88.35", bm.readString()); + bm.reset(); + checkConversionsFail(bm, new int[]{0, 1, 2, 3, 4, 5, 6, 9}); + } + + public void testStringConversions() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeString("true"); + bm.reset(); + assertEquals(true, bm.readBoolean()); + bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeString("2"); + bm.reset(); + assertEquals((byte)2, bm.readByte()); + bm.reset(); + assertEquals((short)2, bm.readShort()); + bm.reset(); + assertEquals(2, bm.readInt()); + bm.reset(); + assertEquals((long)2, bm.readLong()); + bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeString("5.7"); + bm.reset(); + assertEquals(5.7f, bm.readFloat()); + bm.reset(); + assertEquals(5.7d, bm.readDouble()); + } + + public void testNulls() throws Exception + { + JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); + bm.writeString(null); + bm.writeObject(null); + bm.reset(); + assertNull(bm.readObject()); + assertNull(bm.readObject()); + } + + public static junit.framework.Test suite() + { + return new junit.framework.TestSuite(StreamMessageTest.class); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/TextMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/TextMessageTest.java index 337b0f3bbc..64d10fb13f 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/message/TextMessageTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/message/TextMessageTest.java @@ -7,9 +7,9 @@ * 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 @@ -22,8 +22,13 @@ package org.apache.qpid.test.unit.client.message; import org.apache.qpid.client.message.TestMessageHelper; import org.apache.qpid.client.message.JMSTextMessage; +import org.apache.qpid.client.message.JMSMapMessage; import junit.framework.TestCase; +import junit.framework.Assert; + +import javax.jms.JMSException; +import javax.jms.MessageFormatException; public class TextMessageTest extends TestCase { @@ -47,6 +52,248 @@ public class TextMessageTest extends TestCase assertEquals(val, "Banana"); } + + public void testBooleanPropertyLookup() + { + try + { + JMSTextMessage tm = TestMessageHelper.newJMSTextMessage(); + + tm.setBooleanProperty("value", true); + Assert.assertEquals(true, tm.getBooleanProperty("value")); + Assert.assertEquals("true", tm.getStringProperty("value")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testBytePropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.setByteProperty("value", Byte.MAX_VALUE); + + Assert.assertEquals(Byte.MAX_VALUE, mm.getByteProperty("value")); + Assert.assertEquals((short) Byte.MAX_VALUE, mm.getShortProperty("value")); + Assert.assertEquals(Byte.MAX_VALUE, mm.getIntProperty("value")); + Assert.assertEquals((long) Byte.MAX_VALUE, mm.getLongProperty("value")); + Assert.assertEquals("" + Byte.MAX_VALUE, mm.getStringProperty("value")); + + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testShortPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.setShortProperty("value", Short.MAX_VALUE); + Assert.assertEquals(Short.MAX_VALUE, mm.getShortProperty("value")); + Assert.assertEquals((int) Short.MAX_VALUE, mm.getIntProperty("value")); + Assert.assertEquals((long) Short.MAX_VALUE, mm.getLongProperty("value")); + Assert.assertEquals("" + Short.MAX_VALUE, mm.getStringProperty("value")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testDoublePropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.setDoubleProperty("value", Double.MAX_VALUE); + Assert.assertEquals(Double.MAX_VALUE, mm.getDoubleProperty("value")); + Assert.assertEquals("" + Double.MAX_VALUE, mm.getStringProperty("value")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testFloatPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.setFloatProperty("value", Float.MAX_VALUE); + Assert.assertEquals(Float.MAX_VALUE, mm.getFloatProperty("value")); + Assert.assertEquals((double) Float.MAX_VALUE, mm.getDoubleProperty("value")); + Assert.assertEquals("" + Float.MAX_VALUE, mm.getStringProperty("value")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testIntPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.setIntProperty("value", Integer.MAX_VALUE); + Assert.assertEquals(Integer.MAX_VALUE, mm.getIntProperty("value")); + Assert.assertEquals((long) Integer.MAX_VALUE, mm.getLongProperty("value")); + Assert.assertEquals("" + Integer.MAX_VALUE, mm.getStringProperty("value")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testLongPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.setLongProperty("value", Long.MAX_VALUE); + Assert.assertEquals(Long.MAX_VALUE, mm.getLongProperty("value")); + Assert.assertEquals("" + Long.MAX_VALUE, mm.getStringProperty("value")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + + // Failed Lookups + + public void testFailedBooleanPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + Assert.assertEquals(false, mm.getBooleanProperty("int")); + } + catch (JMSException e) + { + Assert.fail("JMSException received." + e); + } + } + + public void testFailedBytePropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.getByteProperty("random"); + Assert.fail("NumberFormatException expected"); + } + catch (NumberFormatException e) + { + //normal execution + } + catch (JMSException e) + { + Assert.fail("JMSException received:" + e); + } + + } + + public void testFailedDoublePropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.getDoubleProperty("random"); + Assert.fail("NullPointerException should be received."); + } + catch (NullPointerException e) + { + //normal execution + } + catch (JMSException e) + { + Assert.fail("JMSException received:" + e); + } + } + + public void testFailedFloatPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.getFloatProperty("random"); + Assert.fail("NullPointerException should be received."); + } + catch (NullPointerException e) + { + //normal execution + } + catch (JMSException e) + { + Assert.fail("JMSException received:" + e); + } + } + + public void testFailedIntPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.getIntProperty("random"); + Assert.fail("NumberFormatException should be received."); + } + catch (NumberFormatException e) + { + //normal execution + } + catch (JMSException e) + { + Assert.fail("JMSException received:" + e); + } + } + + public void testFailedLongPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.getLongProperty("random"); + Assert.fail("NumberFormatException should be received."); + } + catch (NumberFormatException e) + { + //normal execution + } + catch (JMSException e) + { + Assert.fail("JMSException received:" + e); + } + } + + public void testFailedShortPropertyLookup() + { + try + { + JMSMapMessage mm = TestMessageHelper.newJMSMapMessage(); + mm.getShortProperty("random"); + Assert.fail("NumberFormatException should be received."); + } + catch (NumberFormatException e) + { + //normal execution + } + catch (JMSException e) + { + Assert.fail("JMSException received:" + e); + } + } + + public static junit.framework.Test suite() { return new junit.framework.TestSuite(TextMessageTest.class); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java index 98e355b0da..eee9b2de9f 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java @@ -7,9 +7,9 @@ * 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 @@ -87,19 +87,19 @@ public class AMQProtocolSessionTest extends TestCase _testSession.getMinaProtocolSession().setLocalPort(_port); testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue name from an address with special chars",_generatedAddress,testAddress); + assertEquals("Failure when generating a queue exchange from an address with special chars",_generatedAddress,testAddress); //test empty address _testSession.getMinaProtocolSession().setStringLocalAddress(_emptyAddress); testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue name from an empty address",_generatedAddress_2,testAddress); + assertEquals("Failure when generating a queue exchange from an empty address",_generatedAddress_2,testAddress); //test address with no special chars _testSession.getMinaProtocolSession().setStringLocalAddress(_validAddress); testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue name from an address with no special chars",_generatedAddress_3,testAddress); + assertEquals("Failure when generating a queue exchange from an address with no special chars",_generatedAddress_3,testAddress); } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/temporaryqueue/TemporaryQueueTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/temporaryqueue/TemporaryQueueTest.java new file mode 100644 index 0000000000..d0ebdcc668 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/temporaryqueue/TemporaryQueueTest.java @@ -0,0 +1,81 @@ +package org.apache.qpid.test.unit.client.temporaryqueue;
+
+import junit.framework.TestCase;
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQAuthenticationException;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQConnectionException;
+import org.apache.qpid.AMQUnresolvedAddressException;
+import org.apache.qpid.url.URLSyntaxException;
+import org.apache.qpid.test.unit.client.connection.ConnectionTest;
+
+import javax.jms.*;
+
+public class TemporaryQueueTest extends TestCase
+{
+
+ String _broker = "vm://:1";
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ TransportConnection.createVMBroker(1);
+ }
+
+ protected void tearDown() throws Exception
+ {
+ TransportConnection.killAllVMBrokers();
+ }
+
+ protected Connection createConnection() throws AMQException, URLSyntaxException
+ {
+ return new AMQConnection(_broker, "guest", "guest",
+ "fred", "/test");
+ }
+
+ public void testTempoaryQueue() throws Exception
+ {
+ Connection conn = createConnection();
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TemporaryQueue queue = session.createTemporaryQueue();
+ assertNotNull(queue);
+ MessageProducer producer = session.createProducer(queue);
+ MessageConsumer consumer = session.createConsumer(queue);
+ conn.start();
+ producer.send(session.createTextMessage("hello"));
+ TextMessage tm = (TextMessage) consumer.receive(2000);
+ assertNotNull(tm);
+ assertEquals("hello",tm.getText());
+
+ try
+ {
+ queue.delete();
+ fail("Expected JMSException : should not be able to delete while there are active consumers");
+ }
+ catch(JMSException je)
+ {
+ ; //pass
+ }
+
+ consumer.close();
+
+ try
+ {
+ queue.delete();
+ }
+ catch(JMSException je)
+ {
+ fail("Unexpected Exception: " + je.getMessage());
+ }
+
+ conn.close();
+ }
+
+
+ public static junit.framework.Test suite()
+ {
+ return new junit.framework.TestSuite(TemporaryQueueTest.class);
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/close/TopicPublisherCloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/close/TopicPublisherCloseTest.java new file mode 100644 index 0000000000..c9240e9be7 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/close/TopicPublisherCloseTest.java @@ -0,0 +1,70 @@ +/* + * + * 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.close; + +import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.client.*; +import junit.framework.TestCase; + +import javax.jms.Session; +import javax.jms.TopicPublisher; +import javax.jms.TopicSession; +import javax.jms.Topic; + +/** + * @author Apache Software Foundation + */ +public class TopicPublisherCloseTest extends TestCase +{ + + public String _connectionString = "vm://:1"; + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + + public void testAllMethodsThrowAfterConnectionClose() throws Exception + { + AMQConnection connection = new AMQConnection(_connectionString, "guest", "guest", "Client", "/test_path"); + + Topic destination1 = new AMQTopic("t1"); + TopicSession session1 = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + TopicPublisher pub = session1.createPublisher(destination1); + connection.close(); + try + { + pub.getDeliveryMode(); + fail("Expected exception not thrown"); + } + catch (javax.jms.IllegalStateException e) + { + // PASS + } + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java new file mode 100644 index 0000000000..315ba6ae4c --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/StreamMessageTest.java @@ -0,0 +1,136 @@ +/** + * User: Robert Greig + * Date: 12-Dec-2006 + ****************************************************************************** + * (c) Copyright JP Morgan Chase Ltd 2006. All rights reserved. No part of + * this program may be photocopied reproduced or translated to another + * program language without prior written consent of JP Morgan Chase Ltd + ******************************************************************************/ +package org.apache.qpid.test.unit.message; + +import junit.framework.TestCase; +import org.apache.log4j.Logger; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQHeadersExchange; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.PropertyFieldTable; +import org.apache.qpid.url.AMQBindingURL; +import org.apache.qpid.url.BindingURL; + +import javax.jms.*; + +/** + * @author Apache Software Foundation + */ +public class StreamMessageTest extends TestCase +{ + + private static final Logger _logger = Logger.getLogger(StreamMessageTest.class); + + public String _connectionString = "vm://:1"; + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + + public void testStreamMessageEOF() throws Exception + { + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); + + + AMQHeadersExchange queue = new AMQHeadersExchange(new AMQBindingURL(ExchangeDefaults.HEADERS_EXCHANGE_CLASS+"://"+ExchangeDefaults.HEADERS_EXCHANGE_NAME+"/test/queue1?"+ BindingURL.OPTION_ROUTING_KEY+"='F0000=1'")); + FieldTable ft = new PropertyFieldTable(); + ft.setString("F1000","1"); + MessageConsumer consumer = consumerSession.createConsumer(queue, AMQSession.DEFAULT_PREFETCH_LOW_MARK, AMQSession.DEFAULT_PREFETCH_HIGH_MARK, false, false, (String)null, ft); + + + //force synch to ensure the consumer has resulted in a bound queue + ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.HEADERS_EXCHANGE_NAME, ExchangeDefaults.HEADERS_EXCHANGE_CLASS); + + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + + AMQSession producerSession = (AMQSession) con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); + + // Need to start the "producer" connection in order to receive bounced messages + _logger.info("Starting producer connection"); + con2.start(); + + + MessageProducer mandatoryProducer = producerSession.createProducer(queue); + + // Third test - should be routed + _logger.info("Sending isBound message"); + StreamMessage msg = producerSession.createStreamMessage(); + + msg.setStringProperty("F1000","1"); + + msg.writeByte((byte)42); + + mandatoryProducer.send(msg); + + + + _logger.info("Starting consumer connection"); + con.start(); + + StreamMessage msg2 = (StreamMessage) consumer.receive(); + + byte b1 = msg2.readByte(); + try + { + byte b2 = msg2.readByte(); + } + catch (Exception e) + { + assertTrue("Expected MessageEOFException: " + e, e instanceof MessageEOFException); + } + } + + public void testModifyReceivedMessageExpandsBuffer() throws Exception + { + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); + AMQQueue queue = new AMQQueue("testQ"); + MessageConsumer consumer = consumerSession.createConsumer(queue); + consumer.setMessageListener(new MessageListener() + { + + public void onMessage(Message message) + { + StreamMessage sm = (StreamMessage) message; + try + { + sm.clearBody(); + sm.writeString("dfgjshfslfjshflsjfdlsjfhdsljkfhdsljkfhsd"); + } + catch (JMSException e) + { + _logger.error("Error when writing large string to received msg: " + e, e); + fail("Error when writing large string to received msg" + e); + } + } + }); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + AMQSession producerSession = (AMQSession) con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); + MessageProducer mandatoryProducer = producerSession.createProducer(queue); + con.start(); + StreamMessage sm = producerSession.createStreamMessage(); + sm.writeInt(42); + mandatoryProducer.send(sm); + Thread.sleep(2000); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java index b20cfa046a..f00d7185af 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java @@ -27,7 +27,7 @@ import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.AMQTopic; import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import javax.jms.JMSException; import javax.jms.Message; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicPublisherTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicPublisherTest.java new file mode 100644 index 0000000000..4ffb3e8459 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicPublisherTest.java @@ -0,0 +1,75 @@ +/* + * + * 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.topic; + +import junit.framework.TestCase; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQTopic; +import org.apache.qpid.client.transport.TransportConnection; + +import javax.jms.*; + +/** + * @author Apache Software Foundation + */ +public class TopicPublisherTest extends TestCase +{ + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + + public void testUnidentifiedProducer() throws Exception + { + AMQTopic topic = new AMQTopic("MyTopic"); + AMQConnection con = new AMQConnection("vm://:1", "guest", "guest", "test", "/test"); + TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + TopicPublisher publisher = session1.createPublisher(null); + MessageConsumer consumer1 = session1.createConsumer(topic); + con.start(); + publisher.publish(topic, session1.createTextMessage("Hello")); + TextMessage m = (TextMessage) consumer1.receive(2000); + assertNotNull(m); + try + { + publisher.publish(session1.createTextMessage("Goodbye")); + fail("Did not throw UnsupportedOperationException"); + } + catch (UnsupportedOperationException e) + { + // PASS + } + + } + + public static junit.framework.Test suite() + { + return new junit.framework.TestSuite(TopicPublisherTest.class); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicSessionTest.java new file mode 100644 index 0000000000..14ceaa75f1 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/topic/TopicSessionTest.java @@ -0,0 +1,281 @@ +/* + * + * 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.topic; + +import junit.framework.TestCase; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQTopic; +import org.apache.qpid.client.transport.TransportConnection; + +import javax.jms.*; + + +/** + * @author Apache Software Foundation + */ +public class TopicSessionTest extends TestCase +{ + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + //Thread.sleep(2000); + } + + + public void testTopicSubscriptionUnsubscription() throws Exception + { + AMQTopic topic = new AMQTopic("MyTopic"); + AMQConnection con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + TopicSubscriber sub = session1.createDurableSubscriber(topic,"subscription0"); + TopicPublisher publisher = session1.createPublisher(topic); + + con.start(); + + TextMessage tm = session1.createTextMessage("Hello"); + publisher.publish(tm); + + tm = (TextMessage) sub.receive(2000); + assertNotNull(tm); + + session1.unsubscribe("subscription0"); + + try + { + session1.unsubscribe("not a subscription"); + fail("expected InvalidDestinationException when unsubscribing from unknown subscription"); + } + catch(InvalidDestinationException e) + { + ; // PASS + } + catch(Exception e) + { + fail("expected InvalidDestinationException when unsubscribing from unknown subscription, got: " + e); + } + + con.close(); + } + + public void testSubscriptionNameReuseForDifferentTopicSingleConnection() throws Exception + { + subscriptionNameReuseForDifferentTopic(false); + } + + public void testSubscriptionNameReuseForDifferentTopicTwoConnections() throws Exception + { + subscriptionNameReuseForDifferentTopic(true); + } + + private void subscriptionNameReuseForDifferentTopic(boolean shutdown) throws Exception + { + AMQTopic topic = new AMQTopic("MyTopic1" + String.valueOf(shutdown)); + AMQTopic topic2 = new AMQTopic("MyOtherTopic1" + String.valueOf(shutdown)); + AMQConnection con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + TopicSubscriber sub = session1.createDurableSubscriber(topic, "subscription0"); + TopicPublisher publisher = session1.createPublisher(null); + + con.start(); + + publisher.publish(topic, session1.createTextMessage("hello")); + TextMessage m = (TextMessage) sub.receive(2000); + assertNotNull(m); + + if (shutdown) + { + session1.close(); + con.close(); + con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + con.start(); + session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + publisher = session1.createPublisher(null); + } + TopicSubscriber sub2 = session1.createDurableSubscriber(topic2, "subscription0"); + publisher.publish(topic, session1.createTextMessage("hello")); + if (!shutdown) + { + m = (TextMessage) sub.receive(2000); + assertNull(m); + } + publisher.publish(topic2, session1.createTextMessage("goodbye")); + m = (TextMessage) sub2.receive(2000); + assertNotNull(m); + assertEquals("goodbye", m.getText()); + con.close(); + } + + public void testUnsubscriptionAfterConnectionClose() throws Exception + { + AMQTopic topic = new AMQTopic("MyTopic3"); + AMQConnection con1 = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + TopicSession session1 = con1.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + TopicPublisher publisher = session1.createPublisher(topic); + + AMQConnection con2 = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test2", "/test"); + TopicSession session2 = con2.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + TopicSubscriber sub = session2.createDurableSubscriber(topic, "subscription0"); + + con2.start(); + + publisher.publish(session1.createTextMessage("Hello")); + TextMessage tm = (TextMessage) sub.receive(2000); + assertNotNull(tm); + con2.close(); + publisher.publish(session1.createTextMessage("Hello2")); + con2 = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test2", "/test"); + session2 = con2.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + sub = session2.createDurableSubscriber(topic, "subscription0"); + con2.start(); + tm = (TextMessage) sub.receive(2000); + assertNotNull(tm); + assertEquals("Hello2", tm.getText()); + con1.close(); + con2.close(); + } + + public void testTextMessageCreation() throws Exception + { + AMQTopic topic = new AMQTopic("MyTopic4"); + AMQConnection con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + TopicSession session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); + TopicPublisher publisher = session1.createPublisher(topic); + MessageConsumer consumer1 = session1.createConsumer(topic); + con.start(); + TextMessage tm = session1.createTextMessage("Hello"); + publisher.publish(tm); + tm = (TextMessage) consumer1.receive(2000); + assertNotNull(tm); + String msgText = tm.getText(); + assertEquals("Hello", msgText); + tm = session1.createTextMessage(); + msgText = tm.getText(); + assertNull(msgText); + publisher.publish(tm); + tm = (TextMessage) consumer1.receive(2000); + assertNotNull(tm); + msgText = tm.getText(); + assertNull(msgText); + tm.clearBody(); + tm.setText("Now we are not null"); + publisher.publish(tm); + tm = (TextMessage) consumer1.receive(2000); + assertNotNull(tm); + msgText = tm.getText(); + assertEquals("Now we are not null", msgText); + + tm = session1.createTextMessage(""); + msgText = tm.getText(); + assertEquals("Empty string not returned", "", msgText); + publisher.publish(tm); + tm = (TextMessage) consumer1.receive(2000); + assertNotNull(tm); + assertEquals("Empty string not returned", "", msgText); + con.close(); + } + + public void testSendingSameMessage() throws Exception + { + AMQConnection conn = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + TopicSession session = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + TemporaryTopic topic = session.createTemporaryTopic(); + assertNotNull(topic); + TopicPublisher producer = session.createPublisher(topic); + MessageConsumer consumer = session.createConsumer(topic); + conn.start(); + TextMessage sentMessage = session.createTextMessage("Test Message"); + producer.send(sentMessage); + TextMessage receivedMessage = (TextMessage) consumer.receive(2000); + assertNotNull(receivedMessage); + assertEquals(sentMessage.getText(),receivedMessage.getText()); + producer.send(sentMessage); + receivedMessage = (TextMessage) consumer.receive(2000); + assertNotNull(receivedMessage); + assertEquals(sentMessage.getText(),receivedMessage.getText()); + + + } + + public void testTemporaryTopic() throws Exception + { + AMQConnection conn = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + TopicSession session = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + TemporaryTopic topic = session.createTemporaryTopic(); + assertNotNull(topic); + TopicPublisher producer = session.createPublisher(topic); + MessageConsumer consumer = session.createConsumer(topic); + conn.start(); + producer.send(session.createTextMessage("hello")); + TextMessage tm = (TextMessage) consumer.receive(2000); + assertNotNull(tm); + assertEquals("hello",tm.getText()); + + try + { + topic.delete(); + fail("Expected JMSException : should not be able to delete while there are active consumers"); + } + catch(JMSException je) + { + ; //pass + } + + consumer.close(); + + try + { + topic.delete(); + } + catch(JMSException je) + { + fail("Unexpected Exception: " + je.getMessage()); + } + + TopicSession session2 = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + try + { + MessageConsumer consumer2 = session2.createConsumer(topic); + fail("Expected a JMSException when subscribing to a temporary topic created on adifferent session"); + } + catch (JMSException je) + { + ; // pass + } + + + + conn.close(); + } + + + public static junit.framework.Test suite() + { + return new junit.framework.TestSuite(TopicSessionTest.class); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java index 92f3234bba..e858e1ad36 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/TransactedTest.java @@ -25,7 +25,7 @@ import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.test.VMBrokerSetup; +import org.apache.qpid.testutil.VMBrokerSetup; import javax.jms.*; diff --git a/java/client/src/test/java/org/apache/qpid/test/VMBrokerSetup.java b/java/client/src/test/java/org/apache/qpid/testutil/VMBrokerSetup.java index e859fac4af..cedf1ac824 100644 --- a/java/client/src/test/java/org/apache/qpid/test/VMBrokerSetup.java +++ b/java/client/src/test/java/org/apache/qpid/testutil/VMBrokerSetup.java @@ -17,7 +17,7 @@ * under the License. * */ -package org.apache.qpid.test; +package org.apache.qpid.testutil; import junit.extensions.TestSetup; import junit.framework.Test; |