diff options
| author | Kim van der Riet <kpvdr@apache.org> | 2007-02-14 20:02:03 +0000 |
|---|---|---|
| committer | Kim van der Riet <kpvdr@apache.org> | 2007-02-14 20:02:03 +0000 |
| commit | a22f3f594d6eee7d610fb4f140e18cddd7c880f6 (patch) | |
| tree | 5adb376ed217d2debaff1c0bdd59af1a1c93e829 /java/client | |
| parent | 9cb1922884c5b258c961046e6fd48e5152aa79d5 (diff) | |
| download | qpid-python-a22f3f594d6eee7d610fb4f140e18cddd7c880f6.tar.gz | |
First backmerge from trunk to 0-9 branch for Java. Not all java tests passing yet
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/qpid.0-9@507672 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/client')
133 files changed, 4588 insertions, 2729 deletions
diff --git a/java/client/dist/readme.txt b/java/client/dist/readme.txt deleted file mode 100644 index b5f7b107b6..0000000000 --- a/java/client/dist/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -This directory is deliberately empty. -AMQP JAR files will be built here during the build process. diff --git a/java/client/distribution/pom.xml b/java/client/distribution/pom.xml new file mode 100644 index 0000000000..dfbe8b83c2 --- /dev/null +++ b/java/client/distribution/pom.xml @@ -0,0 +1,155 @@ +<!-- + 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-client-distribution</artifactId> + <packaging>jar</packaging> + <version>1.0-incubating-M2-SNAPSHOT</version> + <name>Qpid Client Distributions</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> + <java.source.version>1.5</java.source.version> + <qpid.version>${pom.version}</qpid.version> + <qpid.targetDir>${project.build.directory}</qpid.targetDir> + <qpid.root>${basedir}/..</qpid.root> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-client</artifactId> + <type>jar</type> + </dependency> + </dependencies> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>${java.source.version}</source> + <target>${java.source.version}</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>${assembly.version}</version> + <configuration> + <descriptors> + <descriptor>src/main/assembly/client-bin.xml</descriptor> + </descriptors> + <finalName>qpid-${pom.version}</finalName> + <outputDirectory>${qpid.targetDir}</outputDirectory> + <tarLongFileMode>gnu</tarLongFileMode> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <finalName>qpid-incubating</finalName> + <archive> + <manifest> + <addClasspath>true</addClasspath> + </manifest> + </archive> + </configuration> + </plugin> + + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>distribution-package</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <descriptors> + <descriptor>src/main/assembly/client-bin.xml</descriptor> + <descriptor>src/main/assembly/client-src.xml</descriptor> + </descriptors> + <finalName>qpid-${pom.version}</finalName> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + + </build> + +<profiles> + <profile> + <id>tests</id> + + <dependencies> + <dependency> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-client</artifactId> + <type>test-jar</type> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>distribution-package</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <descriptors> + <descriptor>src/main/assembly/client-bin-tests.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> +</profiles> + +</project> diff --git a/java/client/distribution/src/main/assembly/client-bin-tests.xml b/java/client/distribution/src/main/assembly/client-bin-tests.xml new file mode 100644 index 0000000000..ec4df1c9a7 --- /dev/null +++ b/java/client/distribution/src/main/assembly/client-bin-tests.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<assembly> + <id>java-client-bin-with-tests</id> + <includeBaseDirectory>false</includeBaseDirectory> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + + <fileSets> + <fileSet> + <!-- Apache license files --> + <directory>../../resources</directory> + <outputDirectory>qpid-${qpid.version}</outputDirectory> + <includes> + <include>DISCLAIMER</include> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + <include>README.txt</include> + </includes> + </fileSet> + + <fileSet> + <directory>../../release-docs</directory> + <outputDirectory>qpid-${qpid.version}/docs</outputDirectory> + <includes> + <include>RELEASE_NOTES.txt</include> + </includes> + </fileSet> + + <!-- Include easy access to test source--> + <fileSet> + <directory>../src/test</directory> + <outputDirectory>qpid-${qpid.version}/src</outputDirectory> + <includes> + <include>**/*.java</include> + </includes> + </fileSet> + + <!-- fileSet> Client contains a readme.txt as does qpid root. + Which will cause problems on windows as the zip will + contain: readme.txt and README.txt + < Client local documentation> + <directory>..</directory> + <outputDirectory>qpid-${qpid.version}</outputDirectory> + <includes> + <include>*.txt</include> + </includes> + </fileSet--> + + <!-- Configuration --> + <fileSet> + <directory>../test/etc</directory> + <outputDirectory>qpid-${qpid.version}/etc</outputDirectory> + <includes> + <include>**/*</include> + </includes> + </fileSet> + + <!-- Execution Scripts --> + <fileSet> + <directory>../test/bin</directory> + <outputDirectory>qpid-${qpid.version}/bin</outputDirectory> + <includes> + <include>**/*</include> + </includes> + <fileMode>777</fileMode> <!-- RWX --> + </fileSet> + + <!-- Metadata Jar --> + <fileSet> + <directory>target</directory> + <outputDirectory>qpid-${qpid.version}/lib</outputDirectory> + <includes> + <include>qpid-incubating.jar</include> + </includes> + </fileSet> + </fileSets> + + <dependencySets> + <dependencySet> + <outputDirectory>qpid-${qpid.version}/lib</outputDirectory> + <unpack>false</unpack> + <excludes> + <exclude>org.apache.qpid:qpid-client-distribution</exclude> + </excludes> + </dependencySet> + </dependencySets> +</assembly> diff --git a/java/client/distribution/src/main/assembly/client-bin.xml b/java/client/distribution/src/main/assembly/client-bin.xml new file mode 100644 index 0000000000..962f084995 --- /dev/null +++ b/java/client/distribution/src/main/assembly/client-bin.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<assembly> + <id>java-client-bin</id> + <includeBaseDirectory>false</includeBaseDirectory> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + + <fileSets> + <fileSet> + <!-- Apache license files --> + <directory>../../resources</directory> + <outputDirectory>qpid-${qpid.version}</outputDirectory> + <includes> + <include>DISCLAIMER</include> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + <include>README.txt</include> + </includes> + </fileSet> + + <!--fileSet> + < Client local documentation> + <directory>..</directory> + <outputDirectory>qpid-${qpid.version}</outputDirectory> + <includes> + <include>*.txt</include> + </includes> + </fileSet--> + + <fileSet> + <directory>../../release-docs</directory> + <outputDirectory>qpid-${qpid.version}/docs</outputDirectory> + <includes> + <include>RELEASE_NOTES.txt</include> + </includes> + </fileSet> + + <fileSet> + <directory>target</directory> + <outputDirectory>qpid-${qpid.version}/lib</outputDirectory> + <includes> + <include>qpid-incubating.jar</include> + </includes> + </fileSet> + </fileSets> + + <dependencySets> + <dependencySet> + <outputDirectory>qpid-${qpid.version}/lib</outputDirectory> + <unpack>false</unpack> + <excludes> + <exclude>org.apache.qpid:qpid-client-distribution</exclude> + </excludes> + </dependencySet> + </dependencySets> +</assembly> diff --git a/java/client/distribution/src/main/assembly/client-src.xml b/java/client/distribution/src/main/assembly/client-src.xml new file mode 100644 index 0000000000..b5055f05d7 --- /dev/null +++ b/java/client/distribution/src/main/assembly/client-src.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<assembly> + <!-- id typically identifies the "type" (src vs bin etc) of the assembly --> + <id>java-client-src</id> + <includeBaseDirectory>false</includeBaseDirectory> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + + <fileSets> + + <fileSet> + <!-- Apache license files --> + <directory>../../resources</directory> + <outputDirectory>qpid-${qpid.version}-src</outputDirectory> + <includes> + <include>DISCLAIMER</include> + <include>LICENSE.txt</include> + <include>NOTICE.txt</include> + <include>README.txt</include> + </includes> + </fileSet> + + <fileSet> + <directory>..</directory> + <outputDirectory>qpid-${qpid.version}-src</outputDirectory> + <includes> + <include>src/main/**</include> + <include>src/test/**</include> + <include>test/main/**</include> + <include>test/test/**</include> + <include>pom.xml</include> + <include>distribution/**</include> + </includes> + <excludes> + <exclude>**/target</exclude> + <exclude>**/target/**/*</exclude> + <exclude>**/build</exclude> + <exclude>**/build/**/*</exclude> + </excludes> + </fileSet> + </fileSets> +</assembly> diff --git a/java/client/example/bin/set_classpath.bat b/java/client/example/bin/set_classpath.bat new file mode 100644 index 0000000000..d528967024 --- /dev/null +++ b/java/client/example/bin/set_classpath.bat @@ -0,0 +1,50 @@ +@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+
+@REM Helper script to set classpath for running Qpid example classes
+@REM NB: You must add the Qpid client and common jars to your CLASSPATH
+@REM before running this script
+
+@echo off
+
+if "%QPID_HOME%" == "" GOTO ERROR_QPID_HOME
+
+set QPIDLIB=%QPID_HOME%\lib
+
+if "%CLASSPATH%" == "" GOTO ERROR_CLASSPATH
+
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\backport-util-concurrent-2.2.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\geronimo-jms_1.1_spec-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-collections-3.1.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-configuration-1.2.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-cli-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-lang-2.1.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-logging-api-1.0.4.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\commons-logging-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\log4j-1.2.12.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\mina-core-1.0.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\mina-filter-ssl-1.0.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\mina-java5-1.0.0.jar
+set CLASSPATH=%CLASSPATH%;%QPIDLIB%\slf4j-simple-1.0.jar
+
+GOTO END
+
+:ERROR_CLASSPATH
+Echo Please set set your CLASSPATH variable to include the Qpid client and common jars. Exiting ....
+:ERROR_QPID_HOME
+Echo Please set QPID_HOME variable. Exiting ....
+:END
diff --git a/java/client/example/bin/set_classpath.sh b/java/client/example/bin/set_classpath.sh new file mode 100755 index 0000000000..89e9bc8242 --- /dev/null +++ b/java/client/example/bin/set_classpath.sh @@ -0,0 +1,83 @@ +#!/bin/sh -xv +# +# 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. +# + +# Helper script to set classpath for running Qpid example classes +# NB: You must add the Qpid client and common jars to your CLASSPATH +# before running this script + + +cygwin=false +if [[ "$(uname -a | fgrep Cygwin)" != "" ]]; then + cygwin=true +fi + +#Should have set the QPID_HOME var after install to the working dir e.g. home/qpid/qpid-1.0-incubating-M2-SNAPSHOT +if [ "$QPID_HOME" = "" ] ; then + echo "ERROR: Please set QPID_HOME variable. Exiting ...." + exit 1 +else + QPIDLIB=$QPID_HOME/lib +fi + +if $cygwin; then + QPIDLIB=$(cygpath -w $QPIDLIB) +fi + +if [ "$CLASSPATH" = "" ] ; then + echo "ERROR: Please set set your CLASSPATH variable to include the Qpid client and common jars. Exiting ...." + exit 2 +fi + +#Converts paths for cygwin if req +#Some nasty concatenation to get round cygpath line limits +if $cygwin; then + SEP=";" + CLASSPATH=`cygpath -w $CLASSPATH` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/backport-util-concurrent-2.2.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/geronimo-jms_1.1_spec-1.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-collections-3.1.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-configuration-1.2.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-cli-1.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-lang-2.1.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-logging-api-1.0.4.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/commons-logging-1.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/log4j-1.2.12.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/mina-core-1.0.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/mina-filter-ssl-1.0.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/mina-java5-1.0.0.jar` + CLASSPATH=$CLASSPATH$SEP`cygpath -w $QPIDLIB/slf4j-simple-1.0.jar` + export CLASSPATH +else + CLASSPATH=$CLASSPATH:$QPIDLIB/backport-util-concurrent-2.2.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/geronimo-jms_1.1_spec-1.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-collections-3.1.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-configuration-1.2.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-cli-1.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-lang-2.1.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-logging-api-1.0.4.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/commons-logging-1.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/log4j-1.2.12.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/mina-core-1.0.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/mina-filter-ssl-1.0.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/mina-java5-1.0.0.jar + CLASSPATH=$CLASSPATH:$QPIDLIB/slf4j-simple-1.0.jar + export CLASSPATH +fi + diff --git a/java/client/pom.xml b/java/client/pom.xml index e45aad733d..854428fb39 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -35,40 +35,45 @@ <properties> <topDirectoryLocation>..</topDirectoryLocation> + <java.source.version>1.5</java.source.version> + <qpid.version>${pom.version}</qpid.version> + <qpid.targetDir>${project.build.directory}</qpid.targetDir> </properties> <dependencies> + <dependency> <groupId>org.apache.qpid</groupId> <artifactId>qpid-common</artifactId> </dependency> - <dependency> - <groupId>org.apache.qpid</groupId> - <artifactId>qpid-broker</artifactId> - </dependency> - - <dependency> - <groupId>commons-codec</groupId> - <artifactId>commons-codec</artifactId> - </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jms_1.1_spec</artifactId> </dependency> + <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </dependency> + <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </dependency> + <dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-filter-ssl</artifactId> </dependency> + <!-- Test Dependencies --> + <dependency> <!-- for inVm Broker --> + <groupId>org.apache.qpid</groupId> + <artifactId>qpid-broker</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>jmscts</groupId> <artifactId>jmscts</artifactId> @@ -85,12 +90,14 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> + <scope>test</scope> </dependency> + <dependency> <groupId>org.easymock</groupId> <artifactId>easymockclassextension</artifactId> + <scope>test</scope> </dependency> - </dependencies> <build> @@ -115,11 +122,67 @@ </property> <property> <name>log4j.configuration</name> - <value>file:///${basedir}/src/main/java/log4j.properties</value> + <value>file:///${basedir}/src/main/java/client.log4j</value> </property> </systemProperties> </configuration> </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + +<!-- The inclusion of this resource causes the build to hang. --> + <!--resources> + <resource> + <targetPath>META-INF/</targetPath> + <filtering>false</filtering> + <directory>../resources/META-INF</directory> + <includes> + <include>**</include> + </includes> + </resource> + </resources--> + + <testResources> + <testResource> + <targetPath>META-INF/</targetPath> + <filtering>false</filtering> + <directory>../resources/META-INF</directory> + <includes> + <include>**</include> + </includes> + </testResource> + <testResource> + <targetPath>src/</targetPath> + <filtering>false</filtering> + <directory>src/test/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </testResource> + + <testResource> + <targetPath></targetPath> + <filtering>false</filtering> + <directory>src/main/java</directory> + <includes> + <include>client.log4j</include> + </includes> + </testResource> + </testResources> + </build> + </project> diff --git a/java/client/readme.txt b/java/client/readme.txt deleted file mode 100644 index ef8fa01717..0000000000 --- a/java/client/readme.txt +++ /dev/null @@ -1,31 +0,0 @@ -AMQP JMS API - -To build this you will need ant. The build.xml file requires that the amq.home -property be set to point to the location of the root directory under which the -base2 and amqp moduels reside (these contain protocol definitions used in -the code generation). - -You can avoid setting it if you have the following structure: - - root/ - base/ - base2/ - foreign/ - gsl/ - amqp/ - blaze/ - java/ - client - build.xml - Readme.txt [this file] - common - - -Otherwise you can either pass it in on the command line or add it to a file -named build.properties in the same directory as this Readme.txt file. - -E.g.: - -ant -Damq.home=c:\AMQP\ - - diff --git a/java/client/src/main/java/log4j.properties b/java/client/src/main/java/client.log4j index 6d596d1d19..525433e9a9 100644 --- a/java/client/src/main/java/log4j.properties +++ b/java/client/src/main/java/client.log4j @@ -1,28 +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. -# -log4j.rootLogger=${root.logging.level} - - -log4j.logger.org.apache.qpid=${amqj.logging.level}, console -log4j.additivity.org.apache.qpid=false - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.Threshold=all -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n +#
+# 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.
+#
+log4j.rootLogger=${root.logging.level}
+
+
+log4j.logger.org.apache.qpid=${amqj.logging.level}, console
+log4j.additivity.org.apache.qpid=false
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=all
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java index 6da0da9f6f..8fb87f9e64 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java @@ -308,7 +308,7 @@ public class AMQBrokerDetails implements BrokerDetails } } - //remove the extra DEFAULT_OPTION_SEPERATOR or the '?' if there are no options + //removeKey the extra DEFAULT_OPTION_SEPERATOR or the '?' if there are no options optionsURL.deleteCharAt(optionsURL.length() - 1); return optionsURL.toString(); @@ -334,4 +334,15 @@ public class AMQBrokerDetails implements BrokerDetails } + public static String checkTransport(String broker) + { + if ((!broker.contains("://"))) + { + return "tcp://" + broker; + } + else + { + return broker; + } + } } 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 bb3c33f2fe..f20a3f7d1f 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 @@ -30,6 +30,7 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import javax.jms.ConnectionConsumer; import javax.jms.ConnectionMetaData; @@ -156,21 +157,30 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect // Keeps a tally of connections for logging and debugging - private static AtomicInteger _ConnectionId; - static { _ConnectionId = new AtomicInteger(0); } + private static AtomicLong _ConnectionId; + static { _ConnectionId = new AtomicLong(0); } /* * The connection meta data */ private QpidConnectionMetaData _connectionMetaData; + /** + * @param broker brokerdetails + * @param username username + * @param password password + * @param clientName clientid + * @param virtualHost virtualhost + * @throws AMQException + * @throws URLSyntaxException + */ public AMQConnection(String broker, String username, String password, String clientName, String virtualHost) throws AMQException, URLSyntaxException { this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@" + - (clientName==null?"":clientName) + - virtualHost + "?brokerlist='" + broker + "'")); + (clientName == null ? "" : clientName) + "/" + + virtualHost + "?brokerlist='" + AMQBrokerDetails.checkTransport(broker) + "'")); } public AMQConnection(String host, int port, String username, String password, @@ -185,12 +195,12 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect this(new AMQConnectionURL(useSSL ? ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@" + - (clientName==null?"":clientName) + + (clientName == null ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'" + "," + ConnectionURL.OPTIONS_SSL + "='true'" : ConnectionURL.AMQ_PROTOCOL + "://" + username + ":" + password + "@" + - (clientName==null?"":clientName) + + (clientName == null ? "" : clientName) + virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'" + "," + ConnectionURL.OPTIONS_SSL + "='false'" )); @@ -215,7 +225,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _clientName = connectionURL.getClientName(); _username = connectionURL.getUsername(); _password = connectionURL.getPassword(); - _virtualHost = connectionURL.getVirtualHost(); + setVirtualHost(connectionURL.getVirtualHost()); _failoverPolicy = new FailoverPolicy(connectionURL); @@ -326,6 +336,15 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _clientName = clientName; _username = username; _password = password; + setVirtualHost(virtualHost); + } + + private void setVirtualHost(String virtualHost) + { + if(virtualHost.startsWith("/")) + { + virtualHost = virtualHost.substring(1); + } _virtualHost = virtualHost; } @@ -410,6 +429,12 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect return _failoverPolicy.failoverAllowed(); } + // Test purposes only - used for testing refs, which cannot be done using JMS interfaces + public AMQSession createAMQSession(final boolean transacted, final int acknowledgeMode) throws JMSException + { + return (AMQSession)createSession(transacted, acknowledgeMode, AMQSession.DEFAULT_PREFETCH_HIGH_MARK); + } + public Session createSession(final boolean transacted, final int acknowledgeMode) throws JMSException { return createSession(transacted, acknowledgeMode, AMQSession.DEFAULT_PREFETCH_HIGH_MARK); @@ -484,20 +509,21 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private void createChannelOverWire(int channelId, int prefetchHigh, int prefetchLow, boolean transacted) throws AMQException { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. _protocolHandler.syncWrite(channelId, - ChannelOpenBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) + ChannelOpenBody.createMethodBody( + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version null), // outOfBand ChannelOpenOkBody.class); //todo send low water mark when protocol allows. - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. + // Be aware of possible changes to parameter order as versions change. _protocolHandler.syncWrite(channelId, - MessageQosBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) + MessageQosBody.createMethodBody( + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version false, // global prefetchHigh, // prefetchCount 0), // prefetchSize @@ -509,10 +535,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { _logger.debug("Issuing TxSelect for " + channelId); } - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - _protocolHandler.syncWrite(channelId, TxSelectBody.createMethodBody((byte)0, (byte)9), TxSelectOkBody.class); + _protocolHandler.syncWrite(channelId, TxSelectBody.createMethodBody( + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion()), // AMQP minor version + TxSelectOkBody.class); } } @@ -544,6 +571,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect /** * Returns an AMQQueueSessionAdaptor which wraps an AMQSession and throws IllegalStateExceptions * where specified in the JMS spec + * * @param transacted * @param acknowledgeMode * @return QueueSession @@ -557,6 +585,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect /** * Returns an AMQTopicSessionAdapter which wraps an AMQSession and throws IllegalStateExceptions * where specified in the JMS spec + * * @param transacted * @param acknowledgeMode * @return TopicSession @@ -591,7 +620,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { checkNotClosed(); return _connectionMetaData; - + } public ExceptionListener getExceptionListener() throws JMSException @@ -642,13 +671,18 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public void close() throws JMSException { - synchronized(getFailoverMutex()) + close(-1); + } + + public void close(long timeout) throws JMSException + { + synchronized (getFailoverMutex()) { if (!_closed.getAndSet(true)) { try { - closeAllSessions(null); + closeAllSessions(null, timeout); _protocolHandler.closeConnection(); } catch (AMQException e) @@ -686,7 +720,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect * <p/> * The caller must hold the failover mutex before calling this method. */ - private void closeAllSessions(Throwable cause) throws JMSException + private void closeAllSessions(Throwable cause, long timeout) throws JMSException { final LinkedList sessionCopy = new LinkedList(_sessions.values()); final Iterator it = sessionCopy.iterator(); @@ -702,7 +736,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { try { - session.close(); + session.close(timeout); } catch (JMSException e) { @@ -920,7 +954,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { if (cause instanceof AMQException) { - je = new JMSException(Integer.toString(((AMQException)cause).getErrorCode()) ,"Exception thrown against " + toString() + ": " + cause); + je = new JMSException(Integer.toString(((AMQException) cause).getErrorCode()), "Exception thrown against " + toString() + ": " + cause); } else { @@ -951,7 +985,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { _logger.info("Closing AMQConnection due to :" + cause.getMessage()); _closed.set(true); - closeAllSessions(cause); // FIXME: when doing this end up with RejectedExecutionException from executor. + closeAllSessions(cause, -1); // FIXME: when doing this end up with RejectedExecutionException from executor. } catch (JMSException e) { @@ -973,8 +1007,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. @@ -982,7 +1016,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public void resubscribeSessions() throws JMSException, AMQException { ArrayList sessions = new ArrayList(_sessions.values()); - _logger.info(MessageFormat.format("Resubscribing sessions = {0} sessions.size={1}", sessions, sessions.size())); // FIXME: remove? + _logger.info(MessageFormat.format("Resubscribing sessions = {0} sessions.size={1}", sessions, sessions.size())); // FIXME: removeKey? for (Iterator it = sessions.iterator(); it.hasNext();) { AMQSession s = (AMQSession) it.next(); @@ -1025,7 +1059,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect null); // factory location } - public int getConnectionId() + public long getConnectionId() { return _ConnectionId.get(); } 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 c6f3f9c492..bc9e7137dc 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 @@ -25,6 +25,7 @@ import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.URLSyntaxException; import org.apache.qpid.url.URLHelper; import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; import javax.naming.Reference; import javax.naming.NamingException; @@ -35,19 +36,31 @@ import javax.jms.Destination; public abstract class AMQDestination implements Destination, Referenceable { - protected final String _exchangeName; + protected final AMQShortString _exchangeName; - protected final String _exchangeClass; + protected final AMQShortString _exchangeClass; - protected final String _destinationName; + protected final AMQShortString _destinationName; - protected boolean _isDurable; + protected final boolean _isDurable; protected final boolean _isExclusive; protected final boolean _isAutoDelete; - protected String _queueName; + private AMQShortString _queueName; + + private String _url; + private AMQShortString _urlAsShortString; + + private byte[] _byteEncoding; + private static final int IS_DURABLE_MASK = 0x1; + private static final int IS_EXCLUSIVE_MASK = 0x2; + private static final int IS_AUTODELETE_MASK = 0x4; + + public static final byte QUEUE_TYPE = 1; + public static final byte TOPIC_TYPE = 2; + public static final byte UNKNOWN_TYPE = 3; protected AMQDestination(String url) throws URLSyntaxException { @@ -63,27 +76,27 @@ public abstract class AMQDestination implements Destination, Referenceable _isExclusive = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_EXCLUSIVE)); _isAutoDelete = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_AUTODELETE)); _isDurable = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_DURABLE)); - _queueName = binding.getQueueName(); + _queueName = new AMQShortString(binding.getQueueName()); } - protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, String queueName) + protected AMQDestination(AMQShortString exchangeName, AMQShortString exchangeClass, AMQShortString destinationName, AMQShortString queueName) { this(exchangeName, exchangeClass, destinationName, false, false, queueName); } - protected AMQDestination(String exchangeName, String exchangeClass, String destinationName) + protected AMQDestination(AMQShortString exchangeName, AMQShortString exchangeClass, AMQShortString destinationName) { this(exchangeName, exchangeClass, destinationName, false, false, null); } - protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, boolean isExclusive, - boolean isAutoDelete, String queueName) + protected AMQDestination(AMQShortString exchangeName, AMQShortString exchangeClass, AMQShortString destinationName, boolean isExclusive, + boolean isAutoDelete, AMQShortString 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) + protected AMQDestination(AMQShortString exchangeName, AMQShortString exchangeClass, AMQShortString destinationName, boolean isExclusive, + boolean isAutoDelete, AMQShortString queueName, boolean isDurable) { if (destinationName == null) { @@ -106,9 +119,13 @@ public abstract class AMQDestination implements Destination, Referenceable _isDurable = isDurable; } - public String getEncodedName() + public AMQShortString getEncodedName() { - return toURL(); + if(_urlAsShortString == null) + { + toURL(); + } + return _urlAsShortString; } public boolean isDurable() @@ -116,12 +133,12 @@ public abstract class AMQDestination implements Destination, Referenceable return _isDurable; } - public String getExchangeName() + public AMQShortString getExchangeName() { return _exchangeName; } - public String getExchangeClass() + public AMQShortString getExchangeClass() { return _exchangeClass; } @@ -136,22 +153,34 @@ public abstract class AMQDestination implements Destination, Referenceable return ExchangeDefaults.DIRECT_EXCHANGE_NAME.equals(_exchangeName); } - public String getDestinationName() + public AMQShortString getDestinationName() { return _destinationName; } public String getQueueName() { + return _queueName == null ? null : _queueName.toString(); + } + + public AMQShortString getAMQQueueName() + { return _queueName; } - public void setQueueName(String queueName) + + + public void setQueueName(AMQShortString queueName) { + _queueName = queueName; + // calculated URL now out of date + _url = null; + _urlAsShortString = null; + _byteEncoding = null; } - public abstract String getRoutingKey(); + public abstract AMQShortString getRoutingKey(); public boolean isExclusive() { @@ -179,53 +208,114 @@ public abstract class AMQDestination implements Destination, Referenceable public String toURL() { - StringBuffer sb = new StringBuffer(); + String url = _url; + if(url == null) + { - sb.append(_exchangeClass); - sb.append("://"); - sb.append(_exchangeName); - sb.append("/"); + StringBuffer sb = new StringBuffer(); - if (_destinationName != null) - { - sb.append(_destinationName); - } + sb.append(_exchangeClass); + sb.append("://"); + sb.append(_exchangeName); - sb.append("/"); + sb.append('/'); - if (_queueName != null) - { - sb.append(_queueName); - } + if (_destinationName != null) + { + sb.append(_destinationName); + } - sb.append("?"); + sb.append('/'); - if (_isDurable) - { - sb.append(BindingURL.OPTION_DURABLE); - sb.append("='true'"); - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - } + if (_queueName != null) + { + sb.append(_queueName); + } - if (_isExclusive) - { - sb.append(BindingURL.OPTION_EXCLUSIVE); - sb.append("='true'"); - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - } + sb.append('?'); - if (_isAutoDelete) - { - sb.append(BindingURL.OPTION_AUTODELETE); - sb.append("='true'"); - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); + if (_isDurable) + { + sb.append(BindingURL.OPTION_DURABLE); + sb.append("='true'"); + sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); + } + + if (_isExclusive) + { + sb.append(BindingURL.OPTION_EXCLUSIVE); + sb.append("='true'"); + sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); + } + + if (_isAutoDelete) + { + sb.append(BindingURL.OPTION_AUTODELETE); + sb.append("='true'"); + sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); + } + + //removeKey the last char '?' if there is no options , ',' if there are. + sb.deleteCharAt(sb.length() - 1); + url = sb.toString(); + _url = url; + _urlAsShortString = new AMQShortString(url); } + return url; + } - //remove the last char '?' if there is no options , ',' if there are. - sb.deleteCharAt(sb.length() - 1); + public byte[] toByteEncoding() + { + byte[] encoding = _byteEncoding; + if(encoding == null) + { + int size = _exchangeClass.length() + 1 + + _exchangeName.length() + 1 + + (_destinationName == null ? 0 : _destinationName.length()) + 1 + + (_queueName == null ? 0 : _queueName.length()) + 1 + + 1; + encoding = new byte[size]; + int pos = 0; + + pos = _exchangeClass.writeToByteArray(encoding, pos); + pos = _exchangeName.writeToByteArray(encoding, pos); + if(_destinationName == null) + { + encoding[pos++] = (byte)0; + } + else + { + pos = _destinationName.writeToByteArray(encoding,pos); + } + if(_queueName == null) + { + encoding[pos++] = (byte)0; + } + else + { + pos = _queueName.writeToByteArray(encoding,pos); + } + byte options = 0; + if(_isDurable) + { + options |= IS_DURABLE_MASK; + } + if(_isExclusive) + { + options |= IS_EXCLUSIVE_MASK; + } + if(_isAutoDelete) + { + options |= IS_AUTODELETE_MASK; + } + encoding[pos] = options; + + + _byteEncoding = encoding; - return sb.toString(); + } + return encoding; } public boolean equals(Object o) @@ -258,7 +348,7 @@ public abstract class AMQDestination implements Destination, Referenceable { return false; } - if (_isExclusive != that._isExclusive) + /* if (_isExclusive != that._isExclusive) { return false; } @@ -266,6 +356,7 @@ public abstract class AMQDestination implements Destination, Referenceable { return false; } + */ return true; } @@ -279,8 +370,8 @@ public abstract class AMQDestination implements Destination, Referenceable { result = 29 * result + _queueName.hashCode(); } - result = result * (_isExclusive ? 13 : 7); - result = result * (_isAutoDelete ? 13 : 7); +// result = result * (_isExclusive ? 13 : 7); +// result = result * (_isAutoDelete ? 13 : 7); return result; } @@ -293,9 +384,55 @@ public abstract class AMQDestination implements Destination, Referenceable null); // factory location } + + public static Destination createDestination(byte[] byteEncodedDestination) + { + AMQShortString exchangeClass; + AMQShortString exchangeName; + AMQShortString destinationName; + AMQShortString queueName; + boolean isDurable; + boolean isExclusive; + boolean isAutoDelete; + + int pos = 0; + exchangeClass = AMQShortString.readFromByteArray(byteEncodedDestination, pos); + pos+= exchangeClass.length() + 1; + exchangeName = AMQShortString.readFromByteArray(byteEncodedDestination, pos); + pos+= exchangeName.length() + 1; + destinationName = AMQShortString.readFromByteArray(byteEncodedDestination, pos); + pos+= (destinationName == null ? 0 : destinationName.length()) + 1; + queueName = AMQShortString.readFromByteArray(byteEncodedDestination, pos); + pos+= (queueName == null ? 0 : queueName.length()) + 1; + int options = byteEncodedDestination[pos]; + isDurable = (options & IS_DURABLE_MASK) != 0; + isExclusive = (options & IS_EXCLUSIVE_MASK) != 0; + isAutoDelete = (options & IS_AUTODELETE_MASK) != 0; + + if (exchangeClass.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS)) + { + return new AMQQueue(destinationName,queueName,isExclusive,isAutoDelete,isDurable); + } + else if (exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS)) + { + return new AMQTopic(destinationName,isAutoDelete,queueName,isDurable); + } + else if (exchangeClass.equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS)) + { + return new AMQHeadersExchange(destinationName); + } + else + { + throw new IllegalArgumentException("Unknown Exchange Class:" + exchangeClass); + } + + + + } + public static Destination createDestination(BindingURL binding) { - String type = binding.getExchangeClass(); + AMQShortString type = binding.getExchangeClass(); if (type.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS)) { 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 c6d21c0ea7..b3dea770fa 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 @@ -22,6 +22,7 @@ package org.apache.qpid.client; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.url.BindingURL; +import org.apache.qpid.framing.AMQShortString; /** * A destination backed by a headers exchange @@ -33,12 +34,17 @@ public class AMQHeadersExchange extends AMQDestination this(binding.getExchangeName()); } - public AMQHeadersExchange(String queueName) + public AMQHeadersExchange(String name) + { + this(new AMQShortString(name)); + } + + public AMQHeadersExchange(AMQShortString queueName) { super(queueName, ExchangeDefaults.HEADERS_EXCHANGE_CLASS, queueName, true, true, null); } - public String getRoutingKey() + public AMQShortString 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 6c0da6112a..5b4f4e015c 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 @@ -22,6 +22,7 @@ package org.apache.qpid.client; import org.apache.qpid.url.BindingURL; import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; import javax.jms.Queue; @@ -42,11 +43,27 @@ public class AMQQueue extends AMQDestination implements Queue * Create a reference to a non temporary queue. Note this does not actually imply the queue exists. * @param name the name of the queue */ - public AMQQueue(String name) + public AMQQueue(AMQShortString name) { this(name, false); } + public AMQQueue(AMQShortString exchangeName, AMQShortString routingKey, AMQShortString queueName) + { + super(exchangeName, ExchangeDefaults.DIRECT_EXCHANGE_CLASS, routingKey, false, + false, queueName, false); } + + + /** + * Create a reference to a non temporary queue. Note this does not actually imply the queue exists. + * @param name the name of the queue + */ + public AMQQueue(String name) + { + this(new AMQShortString(name), false); + } + + /** * Create a queue with a specified name. * @@ -56,10 +73,23 @@ public class AMQQueue extends AMQDestination implements Queue */ public AMQQueue(String name, boolean temporary) { + this(new AMQShortString(name),temporary); + } + + + /** + * Create a queue with a specified name. + * + * @param name the destination name (used in the routing key) + * @param temporary if true the broker will generate a queue name, also if true then the queue is autodeleted + * and exclusive + */ + public AMQQueue(AMQShortString name, boolean temporary) + { // queue name is set to null indicating that the broker assigns a name in the case of temporary queues // temporary queues are typically used as response queues - this(name, temporary?null:name, temporary, temporary); - _isDurable = !temporary; + this(name, temporary?null:name, temporary, temporary, !temporary); + } /** @@ -69,16 +99,22 @@ public class AMQQueue extends AMQDestination implements Queue * @param exclusive true if the queue should only permit a single consumer * @param autoDelete true if the queue should be deleted automatically when the last consumers detaches */ - public AMQQueue(String destinationName, String queueName, boolean exclusive, boolean autoDelete) + public AMQQueue(AMQShortString destinationName, AMQShortString queueName, boolean exclusive, boolean autoDelete) + { + this(destinationName, queueName, exclusive, autoDelete, false); + } + + + public AMQQueue(AMQShortString destinationName, AMQShortString queueName, boolean exclusive, boolean autoDelete, boolean durable) { super(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS, destinationName, exclusive, - autoDelete, queueName); + autoDelete, queueName, durable); } - public String getRoutingKey() + public AMQShortString getRoutingKey() { - return getQueueName(); + return getAMQQueueName(); } public boolean isNameRequired() 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 8862c466cb..9027c1b29c 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 @@ -20,16 +20,6 @@ */ package org.apache.qpid.client; -import java.io.Serializable; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - import javax.jms.BytesMessage; import javax.jms.Destination; import javax.jms.IllegalStateException; @@ -60,16 +50,15 @@ import org.apache.qpid.AMQException; import org.apache.qpid.AMQInvalidSelectorException; import org.apache.qpid.AMQUndeliveredException; 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.message.*; import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.util.FlowControllingBlockingQueue; import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ChannelCloseBody; import org.apache.qpid.framing.ChannelCloseOkBody; import org.apache.qpid.framing.ChannelFlowBody; @@ -93,10 +82,19 @@ import org.apache.qpid.framing.TxRollbackOkBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.jms.Session; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.handler.ExchangeBoundHandler; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.URLSyntaxException; +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + public class AMQSession extends Closeable implements Session, QueueSession, TopicSession { private static final Logger _logger = Logger.getLogger(AMQSession.class); @@ -115,6 +113,10 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private int _defaultPrefetchHighMark = DEFAULT_PREFETCH_HIGH_MARK; private int _defaultPrefetchLowMark = DEFAULT_PREFETCH_LOW_MARK; + private MessageListener _messageListener = null; + + private AtomicBoolean _startedAtLeastOnce = new AtomicBoolean(false); + /** * 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 @@ -137,8 +139,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ private final FlowControllingBlockingQueue _queue; + // working private ConcurrentLinkedQueue<Long> _unacknowledged = new ConcurrentLinkedQueue(); - + // merge-right.r501854 + private final java.util.Queue<MessageConsumerPair> _reprocessQueue; + private Dispatcher _dispatcher; private MessageFactoryRegistry _messageFactoryRegistry; @@ -151,7 +156,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi /** * Maps from consumer tag (String) to JMSMessageConsumer instance */ - private Map<String, BasicMessageConsumer> _consumers = new ConcurrentHashMap<String, BasicMessageConsumer>(); + private Map<AMQShortString, BasicMessageConsumer> _consumers = new ConcurrentHashMap<AMQShortString, BasicMessageConsumer>(); /** * Maps from destination to count of JMSMessageConsumers @@ -186,16 +191,27 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private volatile AtomicBoolean _stopped = new AtomicBoolean(true); /** + * Used to signal 'pausing' the dispatcher when setting a message listener on a consumer + */ + private final AtomicBoolean _pausingDispatcher = new AtomicBoolean(false); + + /** + * Used to signal 'pausing' the dispatcher when setting a message listener on a consumer + */ + private final AtomicBoolean _pausedDispatcher = new AtomicBoolean(false); + + /** * Set when recover is called. This is to handle the case where recover() is called by application code * during onMessage() processing. We need to make sure we do not send an auto ack if recover was called. */ private boolean _inRecovery; - + private boolean _hasMessageListeners; /** * Responsible for decoding a message fragment and passing it to the appropriate message consumer. */ + private class Dispatcher extends Thread { public Dispatcher() @@ -224,57 +240,18 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private void dispatchMessage(UnprocessedMessage message) { - if (message.contents != null) - { - final BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(message.contentHeader.getDestination()); + final BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(message.getMessageHeaders().getDestination()); - if (consumer == null) - { - _logger.warn("Received a message from queue " + message.contentHeader.getDestination() + " without a handler - ignoring..."); - _logger.warn("Consumers that exist: " + _consumers); - _logger.warn("Session hashcode: " + System.identityHashCode(this)); - } - else - { - - consumer.notifyMessage(message, _channelId); - - } + if (consumer == null) + { + _logger.warn("Received a message from queue " + message.getMessageHeaders().getDestination() + " without a handler - ignoring..."); + _logger.warn("Consumers that exist: " + _consumers); + _logger.warn("Session hashcode: " + System.identityHashCode(this)); } - /*else + else { - try - { - // Bounced message is processed here, away from the mina thread - AbstractJMSMessage bouncedMessage = _messageFactoryRegistry.createMessage(0, - false, - message.contentHeader, - message.content); - - int errorCode = message.bounceBody.replyCode; - String reason = message.bounceBody.replyText; - _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); - - //@TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. - if (errorCode == AMQConstant.NO_CONSUMERS.getCode()) - { - _connection.exceptionReceived(new AMQNoConsumersException("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)); - } - - } - catch (Exception e) - { - _logger.error("Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", e); - } - }*/ + consumer.notifyMessage(message, _channelId); + } } public void stopDispatcher() @@ -284,6 +261,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } + + AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry) { @@ -314,6 +293,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _defaultPrefetchHighMark = defaultPrefetchHighMark; _defaultPrefetchLowMark = defaultPrefetchLowMark; + _reprocessQueue = new ConcurrentLinkedQueue<MessageConsumerPair>(); + if (_acknowledgeMode == NO_ACKNOWLEDGE) { _queue = new FlowControllingBlockingQueue(_defaultPrefetchHighMark, _defaultPrefetchLowMark, @@ -374,136 +355,69 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public BytesMessage createBytesMessage() throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { checkNotClosed(); - try - { - return (BytesMessage) _messageFactoryRegistry.createMessage("application/octet-stream"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } + return new JMSBytesMessage(); } } public MapMessage createMapMessage() throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { checkNotClosed(); - try - { - return (MapMessage) _messageFactoryRegistry.createMessage("jms/map-message"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } + return new JMSMapMessage(); } } public javax.jms.Message createMessage() throws JMSException { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - return (BytesMessage) _messageFactoryRegistry.createMessage("application/octet-stream"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } + return createBytesMessage(); } public ObjectMessage createObjectMessage() throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { checkNotClosed(); - try - { - return (ObjectMessage) _messageFactoryRegistry.createMessage("application/java-object-stream"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } + return (ObjectMessage) new JMSObjectMessage(); } } public ObjectMessage createObjectMessage(Serializable object) throws JMSException { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - ObjectMessage msg = (ObjectMessage) _messageFactoryRegistry.createMessage("application/java-object-stream"); - msg.setObject(object); - return msg; - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } + ObjectMessage msg = createObjectMessage(); + msg.setObject(object); + return msg; } public StreamMessage createStreamMessage() throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { checkNotClosed(); - try - { - return (StreamMessage) _messageFactoryRegistry.createMessage(JMSStreamMessage.MIME_TYPE); - } - catch (AMQException e) - { - throw new JMSException("Unable to create text message: " + e); - } + return new JMSStreamMessage(); } } public TextMessage createTextMessage() throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { checkNotClosed(); - try - { - return (TextMessage) _messageFactoryRegistry.createMessage("text/plain"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create text message: " + e); - } + return new JMSTextMessage(); } } public TextMessage createTextMessage(String text) throws JMSException { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - TextMessage msg = (TextMessage) _messageFactoryRegistry.createMessage("text/plain"); - msg.setText(text); - return msg; - } - catch (AMQException e) - { - throw new JMSException("Unable to create text message: " + e); - } - } + + TextMessage msg = createTextMessage(); + msg.setText(text); + return msg; } public boolean getTransacted() throws JMSException @@ -532,10 +446,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } // Commits outstanding messages sent and outstanding acknowledgements. - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - _connection.getProtocolHandler().syncWrite(_channelId, TxCommitBody.createMethodBody((byte)0, (byte)9), TxCommitOkBody.class); + _connection.getProtocolHandler().syncWrite(_channelId, TxCommitBody.createMethodBody( + getProtocolMajorVersion(), + getProtocolMinorVersion()), + TxCommitOkBody.class); } catch (AMQException e) { @@ -545,17 +460,18 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } + public void rollback() throws JMSException { checkTransacted(); try { _unacknowledged.clear(); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - _connection.getProtocolHandler().syncWrite(_channelId, - TxRollbackBody.createMethodBody((byte)0, (byte)9), TxRollbackOkBody.class); + _connection.getProtocolHandler().syncWrite(_channelId, TxRollbackBody.createMethodBody( + getProtocolMajorVersion(), + getProtocolMinorVersion()), + TxRollbackOkBody.class); } catch (AMQException e) { @@ -565,9 +481,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public void close() throws JMSException { + close(-1); + } + + public void close(long timeout) throws JMSException + { // We must close down all producers and consumers in an orderly fashion. This is the only method // that can be called from a different thread of control from the one controlling the session - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { //Ensure we only try and close an open session. if (!_closed.getAndSet(true)) @@ -578,15 +499,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { _connection.getProtocolHandler().closeSession(this); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. final AMQMethodBody methodBody = ChannelCloseBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), + getProtocolMinorVersion(), 0, // classId 0, // methodId AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - "JMS client closing channel"); // replyText + new AMQShortString("JMS client closing channel")); // replyText _connection.getProtocolHandler().syncWrite(getChannelId(), methodBody, ChannelCloseOkBody.class); // When control resumes at this point, a reply will have been received that // indicates the broker has closed the channel successfully @@ -606,13 +526,31 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } + private AMQProtocolHandler getProtocolHandler() + { + return _connection.getProtocolHandler(); + } + + + private byte getProtocolMinorVersion() + { + return getProtocolHandler().getProtocolMinorVersion(); + } + + private byte getProtocolMajorVersion() + { + return getProtocolHandler().getProtocolMajorVersion(); + } + + /** * Close all producers or consumers. This is called either in the error case or when closing the session normally. * * @param amqe the exception, may be null to indicate no error has occurred */ - private void closeProducersAndConsumers(AMQException amqe) + private void closeProducersAndConsumers(AMQException amqe) throws JMSException { + JMSException jmse = null; try { closeProducers(); @@ -620,6 +558,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi catch (JMSException e) { _logger.error("Error closing session: " + e, e); + jmse = e; } try { @@ -628,7 +567,19 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi catch (JMSException e) { _logger.error("Error closing session: " + e, e); + if (jmse == null) + { + jmse = e; + } + } + finally + { + if (jmse != null) + { + throw jmse; + } } + } /** @@ -637,9 +588,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi * * @param e the exception that caused this session to be closed. Null causes the */ - public void closed(Throwable e) + public void closed(Throwable e) throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { // An AMQException has an error code and message already and will be passed in when closure occurs as a // result of a channel close request @@ -777,14 +728,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi consumer.clearUnackedMessages(); } _unacknowledged.clear(); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - try { + try + { _connection.getProtocolHandler().writeRequest(_channelId, - MessageRecoverBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) + MessageRecoverBody.createMethodBody( + getProtocolMajorVersion(), + getProtocolMinorVersion(), false)); // requeue - } catch (AMQException e) { + } + catch (AMQException e) + { _logger.error("Error recovering",e); JMSException ex = new JMSException("Error Recovering"); ex.initCause(e); @@ -820,13 +774,37 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public MessageListener getMessageListener() throws JMSException { checkNotClosed(); - throw new java.lang.UnsupportedOperationException("MessageListener interface not supported"); + return _messageListener; } public void setMessageListener(MessageListener listener) throws JMSException { checkNotClosed(); - throw new java.lang.UnsupportedOperationException("MessageListener interface not supported"); + + if (!isStopped()) + { + throw new javax.jms.IllegalStateException("Attempt to set listener while session is started."); + } + + // We are stopped + for (Iterator<BasicMessageConsumer> i = _consumers.values().iterator(); i.hasNext();) + { + BasicMessageConsumer consumer = i.next(); + + if (consumer.isReceiving()) + { + throw new javax.jms.IllegalStateException("Another thread is already receiving synchronously."); + } + } + + _messageListener = listener; + + for (Iterator<BasicMessageConsumer> i = _consumers.values().iterator(); i.hasNext();) + { + i.next().setMessageListener(_messageListener); + } + + } public void run() @@ -858,6 +836,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi return createProducerImpl(destination, DEFAULT_MANDATORY, DEFAULT_IMMEDIATE); } + // Test purposes only - used for testing refs, which cannot be done using JMS interfaces + public BasicMessageProducer createBasicProducer(Topic destination) throws JMSException + { + return (BasicMessageProducer)createProducerImpl(destination, DEFAULT_MANDATORY, DEFAULT_IMMEDIATE); + } + private org.apache.qpid.jms.MessageProducer createProducerImpl(Destination destination, boolean mandatory, boolean immediate) throws JMSException @@ -883,7 +867,10 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi registerProducer(producerId, producer); return producer; } - catch (AMQException e) { throw new JMSException(e.toString()); } + catch (AMQException e) + { + throw new JMSException(e.toString()); + } } }.execute(_connection); } @@ -964,8 +951,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } public MessageConsumer createBrowserConsumer(Destination destination, - String messageSelector, - boolean noLocal) + String messageSelector, + boolean noLocal) throws JMSException { checkValidDestination(destination); @@ -1039,6 +1026,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { checkTemporaryDestination(destination); + return (org.apache.qpid.jms.MessageConsumer) new FailoverSupport() { public Object operation() throws JMSException @@ -1047,7 +1035,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi AMQDestination amqd = (AMQDestination) destination; - final AMQProtocolHandler protocolHandler = _connection.getProtocolHandler(); + final AMQProtocolHandler protocolHandler = getProtocolHandler(); // TODO: construct the rawSelector from the selector string if rawSelector == null final FieldTable ft = FieldTableFactory.newFieldTable(); //if (rawSelector != null) @@ -1061,6 +1049,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi protocolHandler, ft, prefetchHigh, prefetchLow, exclusive, _acknowledgeMode, noConsume, autoClose); + if (_messageListener != null) + { + consumer.setMessageListener(_messageListener); + } + try { registerConsumer(consumer, false); @@ -1074,11 +1067,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi catch (AMQException e) { JMSException ex = new JMSException("Error registering consumer: " + e); + + //todo remove + e.printStackTrace(); ex.setLinkedException(e); throw ex; } - synchronized(destination) + synchronized (destination) { _destinationConsumerCount.putIfAbsent(destination, new AtomicInteger()); _destinationConsumerCount.get(destination).incrementAndGet(); @@ -1118,18 +1114,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } - public void declareExchange(String name, String type) throws AMQException + public void declareExchange(AMQShortString name, AMQShortString type) throws AMQException { - declareExchange(name, type, _connection.getProtocolHandler()); + declareExchange(name, type, getProtocolHandler()); } - public void declareExchangeSynch(String name, String type) throws AMQException + public void declareExchangeSynch(AMQShortString name, AMQShortString type) throws AMQException { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ExchangeDeclareBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version null, // arguments false, // autoDelete false, // durable @@ -1142,18 +1137,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _connection.getProtocolHandler().syncWrite(_channelId, methodBody, ExchangeDeclareOkBody.class); } - private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler)throws AMQException + private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException { declareExchange(amqd.getExchangeName(), amqd.getExchangeClass(), protocolHandler); } - private void declareExchange(String name, String type, AMQProtocolHandler protocolHandler) throws AMQException + private void declareExchange(AMQShortString name, AMQShortString type, AMQProtocolHandler protocolHandler) throws AMQException { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ExchangeDeclareBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version null, // arguments false, // autoDelete false, // durable @@ -1175,7 +1169,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi * @return the queue name. This is useful where the broker is generating a queue name on behalf of the client. * @throws AMQException */ - private String declareQueue(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException + private AMQShortString declareQueue(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException { // For queues (but not topics) we generate the name in the client rather than the // server. This allows the name to be reused on failover if required. In general, @@ -1185,38 +1179,35 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi amqd.setQueueName(protocolHandler.generateQueueName()); } - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = QueueDeclareBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version null, // arguments amqd.isAutoDelete(), // autoDelete amqd.isDurable(), // durable amqd.isExclusive(), // exclusive true, // nowait false, // passive - amqd.getQueueName(), // queue + amqd.getAMQQueueName(), // queue 0); // ticket protocolHandler.writeRequest(_channelId, methodBody); - return amqd.getQueueName(); + return amqd.getAMQQueueName(); } - private void bindQueue(AMQDestination amqd, String queueName, AMQProtocolHandler protocolHandler, FieldTable ft) throws AMQException + private void bindQueue(AMQDestination amqd, AMQShortString queueName, AMQProtocolHandler protocolHandler, FieldTable ft) throws AMQException { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = QueueBindBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version ft, // arguments amqd.getExchangeName(), // exchange true, // nowait queueName, // queue amqd.getRoutingKey(), // routingKey 0); // ticket - protocolHandler.writeRequest(_channelId, methodBody); } @@ -1226,23 +1217,23 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi * @param queueName * @return the consumer tag generated by the broker */ - private void consumeFromQueue(BasicMessageConsumer consumer, String queueName, AMQProtocolHandler protocolHandler, + private void consumeFromQueue(BasicMessageConsumer consumer, AMQShortString 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++); + AMQShortString tag = new AMQShortString(Integer.toString(_nextTag++)); FieldTable arguments = FieldTableFactory.newFieldTable(); if (messageSelector != null && !messageSelector.equals("")) { arguments.put(AMQPFilterTypes.JMS_SELECTOR.getValue(), messageSelector); } - if(consumer.isAutoClose()) + if (consumer.isAutoClose()) { arguments.put(AMQPFilterTypes.AUTO_CLOSE.getValue(), Boolean.TRUE); } - if(consumer.isNoConsume()) + if (consumer.isNoConsume()) { arguments.put(AMQPFilterTypes.NO_CONSUME.getValue(), Boolean.TRUE); } @@ -1253,29 +1244,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - /*AMQFrame jmsConsume = BasicConsumeBody.createAMQFrame(_channelId, - (byte)0, (byte)9, // AMQP version (major, minor) - arguments, // arguments - tag, // consumerTag - consumer.isExclusive(), // exclusive - consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, // noAck - consumer.isNoLocal(), // noLocal - nowait, // nowait - queueName, // queue - 0); // ticket */ - AMQMethodBody methodBody = MessageConsumeBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) - tag, // consumerTag - consumer.isExclusive(), // exclusive - arguments, // arguments in the form of a field table - consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, // noAck - consumer.isNoLocal(), // noLocal - queueName, // queue - 0); // ticket */ + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version + tag, // consumerTag + consumer.isExclusive(), // exclusive + arguments, // arguments in the form of a field table + consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, // noAck + consumer.isNoLocal(), // noLocal + queueName, // queue + 0); // ticket */ /* if (nowait) { @@ -1364,7 +1343,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi if (topicName.indexOf('/') == -1) { - return new AMQTopic(topicName); + return new AMQTopic(new AMQShortString(topicName)); } else { @@ -1434,12 +1413,21 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } else { + AMQShortString topicName; + if (topic instanceof AMQTopic) + { + topicName = ((AMQTopic) topic).getDestinationName(); + } + else + { + topicName = new AMQShortString(topic.getTopicName()); + } // 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())) + if (isQueueBound(dest.getAMQQueueName()) && + !isQueueBound(dest.getAMQQueueName(), topicName)) { - deleteQueue(dest.getQueueName()); + deleteQueue(dest.getAMQQueueName()); } } @@ -1451,15 +1439,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi return subscriber; } - void deleteQueue(String queueName) throws JMSException + void deleteQueue(AMQShortString queueName) throws JMSException { try { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = QueueDeleteBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version false, // ifEmpty false, // ifUnused true, // nowait @@ -1504,7 +1491,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { checkNotClosed(); checkValidQueue(queue); - return new AMQQueueBrowser(this, (AMQQueue) queue,messageSelector); + return new AMQQueueBrowser(this, (AMQQueue) queue, messageSelector); } public TemporaryQueue createTemporaryQueue() throws JMSException @@ -1543,18 +1530,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } - boolean isQueueBound(String queueName) throws JMSException + boolean isQueueBound(AMQShortString queueName) throws JMSException { return isQueueBound(queueName, null); } - boolean isQueueBound(String queueName, String routingKey) throws JMSException + boolean isQueueBound(AMQShortString queueName, AMQShortString routingKey) throws JMSException { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ExchangeBoundBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version ExchangeDefaults.TOPIC_EXCHANGE_NAME, // exchange queueName, // queue routingKey); // routingKey @@ -1568,7 +1554,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi throw new JMSAMQException(e); } ExchangeBoundOkBody responseBody = (ExchangeBoundOkBody) response.getMethod(); - return (responseBody.replyCode == ExchangeBoundHandler.OK); + return (responseBody.replyCode == 0); //ExchangeBoundHandler.OK); Remove Broker compile dependency } private void checkTransacted() throws JMSException @@ -1600,7 +1586,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _logger.debug("Message received in session with channel id " + _channelId); } - _unacknowledged.offer(message.deliveryTag); + _unacknowledged.offer(message.getDeliveryTag()); _queue.add(message); } @@ -1616,10 +1602,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public synchronized void acknowledgeMessage(long requestId, boolean multiple) throws AMQException { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - final AMQMethodBody methodBody = MessageOkBody.createMethodBody((byte)0, (byte)9); // AMQP version (major, minor) + final AMQMethodBody methodBody = MessageOkBody.createMethodBody(getProtocolMajorVersion(), getProtocolMinorVersion()); // AMQP version (major, minor) if (_logger.isDebugEnabled()) { _logger.debug("Sending ack for request ID " + requestId + " on channel " + _channelId); @@ -1659,7 +1643,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi void start() { - if (_dispatcher != null) + if (_startedAtLeastOnce.getAndSet(true)) { try{ //then we stopped this and are restarting, so signal server to resume delivery @@ -1668,9 +1652,31 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _logger.error("Error Un Suspending Channel", e); } } - _dispatcher = new Dispatcher(); - _dispatcher.setDaemon(true); - _dispatcher.start(); + + if(hasMessageListeners() && _dispatcher == null) + { + startDistpatcherIfNecessary(); + } + } + + private boolean hasMessageListeners() + { + return _hasMessageListeners; + } + + void setHasMessageListeners() + { + _hasMessageListeners = true; + } + + synchronized void startDistpatcherIfNecessary() + { + if(_dispatcher == null) + { + _dispatcher = new Dispatcher(); + _dispatcher.setDaemon(true); + _dispatcher.start(); + } } void stop() @@ -1682,7 +1688,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _logger.error("Error Suspending Channel", e); } -//stop the dispatcher thread + //stop the dispatcher thread _stopped.set(true); } @@ -1701,11 +1707,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { AMQDestination amqd = consumer.getDestination(); - AMQProtocolHandler protocolHandler = _connection.getProtocolHandler(); + AMQProtocolHandler protocolHandler = getProtocolHandler(); declareExchange(amqd, protocolHandler); - String queueName = declareQueue(amqd, protocolHandler); + AMQShortString queueName = declareQueue(amqd, protocolHandler); bindQueue(amqd, queueName, protocolHandler, consumer.getRawSelectorFieldTable()); @@ -1727,19 +1733,21 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ void deregisterConsumer(BasicMessageConsumer consumer) { - _consumers.remove(consumer.getConsumerTag()); - String subscriptionName = _reverseSubscriptionMap.remove(consumer); - if (subscriptionName != null) + if (_consumers.remove(consumer.getConsumerTag()) != null) { - _subscriptions.remove(subscriptionName); - } + String subscriptionName = _reverseSubscriptionMap.remove(consumer); + if (subscriptionName != null) + { + _subscriptions.remove(subscriptionName); + } - Destination dest = consumer.getDestination(); - synchronized(dest) - { - if (_destinationConsumerCount.get(dest).decrementAndGet() == 0) + Destination dest = consumer.getDestination(); + synchronized (dest) { - _destinationConsumerCount.remove(dest); + if (_destinationConsumerCount.get(dest).decrementAndGet() == 0) + { + _destinationConsumerCount.remove(dest); + } } } } @@ -1773,7 +1781,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private void resubscribeProducers() throws AMQException { ArrayList producers = new ArrayList(_producers.values()); - _logger.info(MessageFormat.format("Resubscribing producers = {0} producers.size={1}", producers, producers.size())); // FIXME: remove + _logger.info(MessageFormat.format("Resubscribing producers = {0} producers.size={1}", producers, producers.size())); // FIXME: removeKey for (Iterator it = producers.iterator(); it.hasNext();) { BasicMessageProducer producer = (BasicMessageProducer) it.next(); @@ -1796,11 +1804,10 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private void suspendChannel() throws AMQException { _logger.warn("Suspending channel"); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ChannelFlowBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version false); // active _connection.getProtocolHandler().writeRequest(_channelId, methodBody); } @@ -1808,19 +1815,18 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private void unsuspendChannel() throws AMQException { _logger.warn("Unsuspending channel"); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ChannelFlowBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + getProtocolMajorVersion(), // AMQP major version + getProtocolMinorVersion(), // AMQP minor version true); // active _connection.getProtocolHandler().writeRequest(_channelId, methodBody); } - public void confirmConsumerCancelled(String consumerTag) + public void confirmConsumerCancelled(AMQShortString consumerTag) { BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(consumerTag); - if((consumer != null) && (consumer.isAutoClose())) + if ((consumer != null) && (consumer.isAutoClose())) { consumer.closeWhenNoMessages(true); } 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 81fee69f90..18c655a829 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 @@ -20,6 +20,8 @@ */ package org.apache.qpid.client; +import org.apache.qpid.framing.AMQShortString; + import javax.jms.JMSException; import javax.jms.TemporaryQueue; @@ -38,7 +40,7 @@ final class AMQTemporaryQueue extends AMQQueue implements TemporaryQueue, Tempor */ public AMQTemporaryQueue(AMQSession session) { - super("TempQueue" + Long.toString(System.currentTimeMillis()), true); + super(new AMQShortString("TempQueue" + Long.toString(System.currentTimeMillis())), true); _session = session; } 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 39304f3f4c..f50b0390c5 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 @@ -22,6 +22,7 @@ package org.apache.qpid.client; import org.apache.qpid.url.BindingURL; import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; import javax.jms.JMSException; import javax.jms.Topic; @@ -40,10 +41,21 @@ public class AMQTopic extends AMQDestination implements Topic public AMQTopic(String name) { + this(new AMQShortString(name)); + } + + public AMQTopic(AMQShortString exchange, AMQShortString routingKey, AMQShortString queueName) + { + super(exchange, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, routingKey, true, true, queueName, false); + } + + + public AMQTopic(AMQShortString name) + { this(name, true, null, false); } - public AMQTopic(String name, boolean isAutoDelete, String queueName, boolean isDurable) + public AMQTopic(AMQShortString name, boolean isAutoDelete, AMQShortString queueName, boolean isDurable) { super(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, name, true, isAutoDelete, queueName, isDurable); @@ -56,17 +68,17 @@ public class AMQTopic extends AMQDestination implements Topic true); } - public static String getDurableTopicQueueName(String subscriptionName, AMQConnection connection) throws JMSException + public static AMQShortString getDurableTopicQueueName(String subscriptionName, AMQConnection connection) throws JMSException { - return connection.getClientID() + ":" + subscriptionName; + return new AMQShortString(connection.getClientID() + ":" + subscriptionName); } public String getTopicName() throws JMSException { - return super.getDestinationName(); + return super.getDestinationName().toString(); } - public String getRoutingKey() + public AMQShortString getRoutingKey() { return getDestinationName(); } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQUndefinedDestination.java b/java/client/src/main/java/org/apache/qpid/client/AMQUndefinedDestination.java new file mode 100644 index 0000000000..0f3723c58b --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/AMQUndefinedDestination.java @@ -0,0 +1,45 @@ +/*
+ *
+ * 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;
+
+import org.apache.qpid.framing.AMQShortString;
+
+public class AMQUndefinedDestination extends AMQDestination
+{
+
+ private static final AMQShortString UNKNOWN_EXCHANGE_CLASS = new AMQShortString("unknown");
+
+
+ public AMQUndefinedDestination(AMQShortString exchange, AMQShortString routingKey, AMQShortString queueName)
+ {
+ super(exchange, UNKNOWN_EXCHANGE_CLASS, routingKey, queueName);
+ }
+
+ public AMQShortString getRoutingKey()
+ {
+ return getDestinationName();
+ }
+
+ public boolean isNameRequired()
+ {
+ return getAMQQueueName() == null;
+ }
+}
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 47213af55c..e9c755d09c 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 @@ -27,11 +27,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.client.message.AbstractJMSMessage; @@ -40,6 +35,7 @@ import org.apache.qpid.client.message.UnprocessedMessage; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.MessageCancelBody; import org.apache.qpid.framing.MessageOkBody; @@ -48,6 +44,18 @@ import org.apache.qpid.jms.Session; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.URLSyntaxException; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import java.util.Iterator; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + public class BasicMessageConsumer extends Closeable implements MessageConsumer { private static final Logger _logger = Logger.getLogger(BasicMessageConsumer.class); @@ -70,13 +78,13 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer /** * Holds an atomic reference to the listener installed. */ - private final AtomicReference _messageListener = new AtomicReference(); + private final AtomicReference<MessageListener> _messageListener = new AtomicReference<MessageListener>(); /** * The consumer tag allows us to close the consumer by sending a jmsCancel method to the * broker */ - private String _consumerTag; + private AMQShortString _consumerTag; /** * We need to know the channel id when constructing frames @@ -85,13 +93,17 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer /** * Used in the blocking receive methods to receive a message from - * the Session thread. Argument true indicates we want strict FIFO semantics + * the Session thread. + * <p/> + * Or to notify of errors + * <p/> + * Argument true indicates we want strict FIFO semantics */ private final ArrayBlockingQueue _synchronousQueue; private MessageFactoryRegistry _messageFactory; - private AMQSession _session; + private final AMQSession _session; private AMQProtocolHandler _protocolHandler; @@ -148,8 +160,8 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer private Thread _receivingThread; /** - * autoClose denotes that the consumer will automatically cancel itself when there are no more messages to receive - * on the queue. This is used for queue browsing. + * autoClose denotes that the consumer will automatically cancel itself when there are no more messages to receive + * on the queue. This is used for queue browsing. */ private boolean _autoClose; private boolean _closeWhenNoMessages; @@ -186,14 +198,14 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public String getMessageSelector() throws JMSException { - checkPreConditions(); + checkPreConditions(); return _messageSelector; } public MessageListener getMessageListener() throws JMSException { - checkPreConditions(); - return (MessageListener) _messageListener.get(); + checkPreConditions(); + return _messageListener.get(); } public int getAcknowledgeMode() @@ -206,9 +218,9 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer return _messageListener.get() != null; } - public void setMessageListener(MessageListener messageListener) throws JMSException + public void setMessageListener(final MessageListener messageListener) throws JMSException { - checkPreConditions(); + checkPreConditions(); //if the current listener is non-null and the session is not stopped, then //it is an error to call this method. @@ -223,7 +235,13 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer if (_session.isStopped()) { _messageListener.set(messageListener); - _logger.debug("Message listener set for destination " + _destination); + _session.setHasMessageListeners(); + _session.startDistpatcherIfNecessary(); + + if (_logger.isDebugEnabled()) + { + _logger.debug("Session stopped : Message listener(" + messageListener + ") set for destination " + _destination); + } } else { @@ -235,25 +253,35 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { throw new javax.jms.IllegalStateException("Attempt to alter listener while session is started."); } + _logger.debug("Message listener set for destination " + _destination); if (messageListener != null) { - try +// working +// try +// { +// //handle case where connection has already been started, and the dispatcher is blocked +// //doing a put on the _synchronousQueue +// AbstractJMSMessage jmsMsg = (AbstractJMSMessage)_synchronousQueue.poll(); +// if (jmsMsg != null) +// { +// preApplicationProcessing(jmsMsg); +// messageListener.onMessage(jmsMsg); +// postDeliver(jmsMsg); +// } +// } +// catch (AMQException e) +// { +// throw new JMSException(e.toString()); +// } + +// r501854 + synchronized (_session) { - //handle case where connection has already been started, and the dispatcher is blocked - //doing a put on the _synchronousQueue - AbstractJMSMessage jmsMsg = (AbstractJMSMessage)_synchronousQueue.poll(); - if (jmsMsg != null) - { - preApplicationProcessing(jmsMsg); - messageListener.onMessage(jmsMsg); - postDeliver(jmsMsg); - } - } - catch (AMQException e) - { - throw new JMSException(e.toString()); + _messageListener.set(messageListener); + _session.setHasMessageListeners(); + _session.startDistpatcherIfNecessary(); } } } @@ -261,21 +289,12 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer private void preApplicationProcessing(AbstractJMSMessage jmsMsg) throws JMSException { - if(_session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE) + + if (_session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE) { _unacknowledgedDeliveryTags.add(jmsMsg.getDeliveryTag()); - String url = jmsMsg.getStringProperty(CustomJMXProperty.JMSX_QPID_JMSDESTINATIONURL.toString()); - try - { - Destination dest = AMQDestination.createDestination(new AMQBindingURL(url)); - jmsMsg.setJMSDestination(dest); - } - catch (URLSyntaxException e) - { - _logger.warn("Unable to parse the supplied destination header: " + url); - } - } + _session.setInRecovery(false); } @@ -328,6 +347,11 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer return _exclusive; } + public boolean isReceiving() + { + return _receiving.get(); + } + public Message receive() throws JMSException { return receive(0); @@ -335,13 +359,15 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public Message receive(long l) throws JMSException { - checkPreConditions(); + _session.startDistpatcherIfNecessary(); + + checkPreConditions(); acquireReceiving(); try { - if(closeOnAutoClose()) + if (closeOnAutoClose()) { return null; } @@ -380,7 +406,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer private boolean closeOnAutoClose() throws JMSException { - if(isAutoClose() && _closeWhenNoMessages && _synchronousQueue.isEmpty()) + if (isAutoClose() && _closeWhenNoMessages && _synchronousQueue.isEmpty()) { close(false); return true; @@ -393,13 +419,15 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public Message receiveNoWait() throws JMSException { - checkPreConditions(); + _session.startDistpatcherIfNecessary(); + + checkPreConditions(); acquireReceiving(); try { - if(closeOnAutoClose()) + if (closeOnAutoClose()) { return null; } @@ -459,17 +487,16 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer public void close(boolean sendClose) throws JMSException { - synchronized(_connection.getFailoverMutex()) + synchronized (_connection.getFailoverMutex()) { if (!_closed.getAndSet(true)) { - if(sendClose) + if (sendClose) { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. final AMQMethodBody cancelBody = MessageCancelBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version _consumerTag); // consumerTag try @@ -514,22 +541,50 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer */ void notifyMessage(UnprocessedMessage messageFrame, int channelId) { - if (_logger.isDebugEnabled()) + final boolean debug = _logger.isDebugEnabled(); + + if (debug) { - _logger.debug("notifyMessage called with message number " + messageFrame.deliveryTag); + _logger.debug("notifyMessage called with message number " + messageFrame.getDeliveryTag()); } try { - AbstractJMSMessage jmsMessage = _messageFactory.createMessage(messageFrame.deliveryTag, + AbstractJMSMessage jmsMessage = _messageFactory.createMessage(messageFrame.getDeliveryTag(), false, - messageFrame.contentHeader, - messageFrame.contents); + messageFrame.getMessageHeaders(), + messageFrame.getContents()); - _logger.debug("Message is of type: " + jmsMessage.getClass().getName()); + if (debug) + { + _logger.debug("Message is of type: " + jmsMessage.getClass().getName()); + } jmsMessage.setConsumer(this); preDeliver(jmsMessage); + notifyMessage(jmsMessage, channelId); + } + catch (Exception e) + { + if (e instanceof InterruptedException) + { + _logger.info("SynchronousQueue.put interupted. Usually result of connection closing"); + } + else + { + _logger.error("Caught exception (dump follows) - ignoring...", e); + } + } + } + + /** + * @param jmsMessage this message has already been processed so can't redo preDeliver + * @param channelId + */ + public void notifyMessage(AbstractJMSMessage jmsMessage, int channelId) + { + try + { if (isMessageListenerSet()) { //we do not need a lock around the test above, and the dispatch below as it is invalid @@ -540,6 +595,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer } else { + //This shouldn't be possible. _synchronousQueue.put(jmsMessage); } } @@ -547,11 +603,11 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { if (e instanceof InterruptedException) { - _logger.info("SynchronousQueue.put interupted. Usually result of connection closing"); + _logger.info("reNotification : SynchronousQueue.put interupted. Usually result of connection closing"); } else { - _logger.error("Caught exception (dump follows) - ignoring...", e); + _logger.error("reNotification : Caught exception (dump follows) - ignoring...", e); } } } @@ -573,7 +629,7 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer private void postDeliver(AbstractJMSMessage msg) throws JMSException, AMQException { - msg.setJMSDestination(_destination); + msg.setJMSDestination(_destination); switch (_acknowledgeMode) { case Session.CLIENT_ACKNOWLEDGE: @@ -636,6 +692,8 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { _closed.set(true); + //QPID-293 can "request redelivery of this error through dispatcher" + // we have no way of propagating the exception to a message listener - a JMS limitation - so we // deal with the case where we have a synchronous receive() waiting for a message to arrive if (!isMessageListenerSet()) @@ -649,41 +707,45 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer deregisterConsumer(); } + /** * Perform cleanup to deregister this consumer. This occurs when closing the consumer in both the clean * case and in the case of an error occurring. */ private void deregisterConsumer() { - _session.deregisterConsumer(this); + _session.deregisterConsumer(this); } - public String getConsumerTag() + public AMQShortString getConsumerTag() { return _consumerTag; } - public void setConsumerTag(String consumerTag) + public void setConsumerTag(AMQShortString consumerTag) { _consumerTag = consumerTag; } - public AMQSession getSession() { - return _session; - } + public AMQSession getSession() + { + return _session; + } - private void checkPreConditions() throws JMSException{ + private void checkPreConditions() throws JMSException + { - this.checkNotClosed(); + this.checkNotClosed(); - if(_session == null || _session.isClosed()){ - throw new javax.jms.IllegalStateException("Invalid Session"); - } - } + if (_session == null || _session.isClosed()) + { + throw new javax.jms.IllegalStateException("Invalid Session"); + } + } public void acknowledge() throws JMSException { - if(!isClosed()) + if (!isClosed()) { try { @@ -728,10 +790,10 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { _closeWhenNoMessages = b; - if(_closeWhenNoMessages - && _synchronousQueue.isEmpty() - && _receiving.get() - && _messageListener != null) + if (_closeWhenNoMessages + && _synchronousQueue.isEmpty() + && _receiving.get() + && _messageListener != null) { _receivingThread.interrupt(); } 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 39c4c28baf..7063ad62d1 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 @@ -26,6 +26,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.client.message.AbstractJMSMessage; import org.apache.qpid.client.message.JMSBytesMessage; import org.apache.qpid.client.message.MessageHeaders; +import org.apache.qpid.client.message.MessageConverter; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.framing.*; @@ -139,11 +140,10 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j { // Declare the exchange // Note that the durable and internal arguments are ignored since passive is set to false - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ExchangeDeclareBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version null, // arguments false, // autoDelete false, // durable @@ -256,6 +256,19 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j } } + public void sendRef(Message message) throws JMSException + { + checkPreConditions(); + checkInitialDestination(); + + + synchronized (_connection.getFailoverMutex()) + { + sendImpl(_destination, message, true, _deliveryMode, _messagePriority, _timeToLive, + _mandatory, _immediate); + } + } + public void send(Message message, int deliveryMode) throws JMSException { checkPreConditions(); @@ -373,112 +386,31 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j 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; + newMessage = new MessageConverter((BytesMessage)message).getConvertedMessage(); } 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; + newMessage = new MessageConverter((MapMessage)message).getConvertedMessage(); } else if (message instanceof ObjectMessage) { - ObjectMessage origMessage = (ObjectMessage) message; - ObjectMessage nativeMessage = _session.createObjectMessage(); - - nativeMessage.setObject(origMessage.getObject()); - - newMessage = (AbstractJMSMessage) nativeMessage; + newMessage = new MessageConverter((ObjectMessage)message).getConvertedMessage(); } else if (message instanceof TextMessage) { - TextMessage origMessage = (TextMessage) message; - TextMessage nativeMessage = _session.createTextMessage(); - - nativeMessage.setText(origMessage.getText()); - - newMessage = (AbstractJMSMessage) nativeMessage; + newMessage = new MessageConverter((TextMessage)message).getConvertedMessage(); } 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; + newMessage = new MessageConverter((StreamMessage)message).getConvertedMessage(); } else { + //TODO; Do we really want to create an empty message here ? 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; + return new MessageConverter(newMessage).getConvertedMessage(); } - newMessage.setJMSPriority(priority); - if (message.getJMSReplyTo() != null) - { - newMessage.setJMSReplyTo(message.getJMSReplyTo()); - } - newMessage.setJMSType(message.getJMSType()); - - if (newMessage != null) { return newMessage; @@ -511,7 +443,13 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j 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); + sendImpl(destination, message, false, deliveryMode, priority, timeToLive, mandatory, immediate, _waitUntilSent); + } + + protected void sendImpl(AMQDestination destination, Message message, boolean forceRef, int deliveryMode, int priority, + long timeToLive, boolean mandatory, boolean immediate) throws JMSException + { + sendImpl(destination, message, forceRef, deliveryMode, priority, timeToLive, mandatory, immediate, _waitUntilSent); } /** @@ -530,11 +468,18 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j long timeToLive, boolean mandatory, boolean immediate, boolean wait) throws JMSException { + sendImpl(destination, origMessage, false, deliveryMode, priority, timeToLive, mandatory, immediate, wait); + } + + protected void sendImpl(AMQDestination destination, Message origMessage, boolean forceRef, int deliveryMode, int priority, + long timeToLive, boolean mandatory, boolean immediate, boolean wait) + throws JMSException + { checkTemporaryDestination(destination); origMessage.setJMSDestination(destination); AbstractJMSMessage message = convertToNativeMessage(origMessage); - message.getMessageHeaders().getJMSHeaders().setString(CustomJMXProperty.JMSX_QPID_JMSDESTINATIONURL.toString(), destination.toURL()); + message.getMessageHeaders().getJMSHeaders().setString(CustomJMSXProperty.JMSZ_QPID_DESTTYPE.toString(), destination.toURL()); long currentTime = 0; if (!_disableTimestamps) @@ -564,7 +509,8 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j int size = (payload != null) ? payload.limit() : 0; final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize(); - if(_logger.isDebugEnabled()){ + if(_logger.isDebugEnabled()) + { _logger.debug("framePayloadMax " + framePayloadMax); _logger.debug("size " + size); _logger.debug("payload capacity" + payload.capacity()); @@ -573,14 +519,17 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j _logger.debug("payload position" + payload.position()); } - if (size < framePayloadMax){ + if (size < framePayloadMax && !forceRef) + { // Inline message case _logger.debug("Inline case, sending data inline with the transfer method"); Content data = new Content(Content.TypeEnum.INLINE_T, payload); doMessageTransfer(messageHeaders,destination,data,message,deliveryMode,priority,timeToLive,mandatory,immediate); - } else { + } + else + { // Reference message case // Sequence is as follows // 1. Message.open @@ -602,7 +551,8 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j doMessageTransfer(messageHeaders,destination,data,message,deliveryMode,priority,timeToLive,mandatory,immediate); //Message.Append - for(Iterator it = content.iterator(); it.hasNext();){ + for(Iterator it = content.iterator(); it.hasNext();) + { doMessageAppend(referenceId,(byte[])it.next()); } @@ -621,12 +571,16 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j } } - private void doMessageTransfer(MessageHeaders messageHeaders,AMQDestination destination, Content content, AbstractJMSMessage message, int deliveryMode, int priority, - long timeToLive, boolean mandatory, boolean immediate)throws JMSException{ + private void doMessageTransfer(MessageHeaders messageHeaders, AMQDestination destination, Content content, + AbstractJMSMessage message, int deliveryMode, int priority, + long timeToLive, boolean mandatory, boolean immediate) throws JMSException + { try { + // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = MessageTransferBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version messageHeaders.getAppId(), // String appId messageHeaders.getJMSHeaders(), // FieldTable applicationHeaders content, // Content body @@ -659,16 +613,56 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j } } - private void doMessageOpen(String referenceId){ - AMQMethodBody methodBody = MessageOpenBody.createMethodBody((byte)0, (byte)9, referenceId.getBytes()); + private void doMessageOpen(String referenceId) throws JMSException + { + try + { + // Be aware of possible changes to parameter order as versions change. + AMQMethodBody methodBody = MessageOpenBody.createMethodBody( + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version + referenceId.getBytes()); + _protocolHandler.writeRequest(_channelId, methodBody); + } + catch (AMQException e) + { + throw new JMSException(e.toString()); + } } - private void doMessageAppend(String referenceId,byte[] data){ - AMQMethodBody methodBody = MessageAppendBody.createMethodBody((byte)0, (byte)9, data, referenceId.getBytes()); + private void doMessageAppend(String referenceId, byte[] data) throws JMSException + { + try + { + // Be aware of possible changes to parameter order as versions change. + AMQMethodBody methodBody = MessageAppendBody.createMethodBody( + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version + data, + referenceId.getBytes()); + _protocolHandler.writeRequest(_channelId, methodBody); + } + catch (AMQException e) + { + throw new JMSException(e.toString()); + } } - private void doMessageClose(String referenceId){ - AMQMethodBody methodBody = MessageCloseBody.createMethodBody((byte)0, (byte)9, referenceId.getBytes()); + private void doMessageClose(String referenceId) throws JMSException + { + try + { + // Be aware of possible changes to parameter order as versions change. + AMQMethodBody methodBody = MessageCloseBody.createMethodBody( + _protocolHandler.getProtocolMajorVersion(), // AMQP major version + _protocolHandler.getProtocolMinorVersion(), // AMQP minor version + referenceId.getBytes()); + _protocolHandler.writeRequest(_channelId, methodBody); + } + catch (AMQException e) + { + throw new JMSException(e.toString()); + } } private String generateReferenceId(){ @@ -699,23 +693,28 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j * maximum frame size. * * @param payload + * @param frames + * @param offset + * @param channelId * @return the array of content bodies */ - private List createContent(ByteBuffer payload) + private List<byte[]> createContent(ByteBuffer payload) { int dataLength = payload.remaining(); final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize(); int lastFrame = (dataLength % framePayloadMax) > 0 ? 1 : 0; int frameCount = (int) (dataLength / framePayloadMax) + lastFrame; - List bodies = new LinkedList(); + List<byte[]> bodies = new LinkedList<byte[]>(); long remaining = dataLength; - for (int i = 0; i < frameCount + lastFrame; i++) + for (int i = 0; i < frameCount; i++) { payload.position((int) framePayloadMax * i); int length = (remaining >= framePayloadMax) ? (int) framePayloadMax : (int) remaining; payload.limit(payload.position() + length); - bodies.add(payload.slice().array()); + byte[] ba = new byte[length]; + payload.slice().get(ba); + bodies.add(ba); remaining -= length; } return bodies; @@ -762,11 +761,8 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j { throw new InvalidDestinationException("Supplied Destination was invalid"); } - - } - public AMQSession getSession() { return _session; diff --git a/java/client/src/main/java/org/apache/qpid/client/CustomJMXProperty.java b/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java index 56cd4f3aa3..dc354a4b0d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/CustomJMXProperty.java +++ b/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java @@ -20,24 +20,39 @@ */
package org.apache.qpid.client;
+import org.apache.qpid.framing.AMQShortString;
+
import java.util.*;
-public enum CustomJMXProperty
+public enum CustomJMSXProperty
{
- JMSX_QPID_JMSDESTINATIONURL,
+ JMSZ_QPID_DESTTYPE,
JMSXGroupID,
JMSXGroupSeq,
JMSXType;
+
+ private final AMQShortString _nameAsShortString;
+
+ CustomJMSXProperty()
+ {
+ _nameAsShortString = new AMQShortString(toString());
+ }
+
+ public AMQShortString getShortStringName()
+ {
+ return _nameAsShortString;
+ }
+
private static Enumeration _names;
public static synchronized Enumeration asEnumeration()
{
if(_names == null)
{
- CustomJMXProperty[] properties = values();
+ CustomJMSXProperty[] properties = values();
ArrayList<String> nameList = new ArrayList<String>(properties.length);
- for(CustomJMXProperty property : properties)
+ for(CustomJMSXProperty property : properties)
{
nameList.add(property.toString());
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/DispatcherCallback.java b/java/client/src/main/java/org/apache/qpid/client/DispatcherCallback.java new file mode 100644 index 0000000000..81a55006ed --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/DispatcherCallback.java @@ -0,0 +1,36 @@ +/* + * 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; + +import java.util.Queue; + +public abstract class DispatcherCallback +{ + BasicMessageConsumer _consumer; + + public DispatcherCallback(BasicMessageConsumer mc) + { + _consumer = mc; + } + + abstract public void whilePaused(Queue<MessageConsumerPair> reprocessQueue); + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/MessageConsumerPair.java b/java/client/src/main/java/org/apache/qpid/client/MessageConsumerPair.java new file mode 100644 index 0000000000..585d6db3fd --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/MessageConsumerPair.java @@ -0,0 +1,43 @@ +/* + * 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; + +public class MessageConsumerPair +{ + BasicMessageConsumer _consumer; + Object _item; + + public MessageConsumerPair(BasicMessageConsumer consumer, Object item) + { + _consumer = consumer; + _item = item; + } + + public BasicMessageConsumer getConsumer() + { + return _consumer; + } + + public Object getItem() + { + return _item; + } +} 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 index 9ee802ff10..7749bded2c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java +++ b/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java @@ -56,7 +56,7 @@ public class QpidConnectionMetaData implements ConnectionMetaData public Enumeration getJMSXPropertyNames() throws JMSException { - return CustomJMXProperty.asEnumeration(); + return CustomJMSXProperty.asEnumeration(); } public int getProviderMajorVersion() throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java index 50596d4bfc..7b789aa09d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java @@ -82,8 +82,6 @@ public class FailoverHandler implements Runnable // client code which runs in a separate thread. synchronized (_amqProtocolHandler.getConnection().getFailoverMutex()) { - _logger.info("Starting failover process"); - // We switch in a new state manager temporarily so that the interaction to get to the "connection open" // state works, without us having to terminate any existing "state waiters". We could theoretically // have a state waiter waiting until the connection is closed for some reason. Or in future we may have @@ -92,6 +90,8 @@ public class FailoverHandler implements Runnable _amqProtocolHandler.setStateManager(new AMQStateManager(_amqProtocolHandler.getProtocolSession())); if (!_amqProtocolHandler.getConnection().firePreFailover(_host != null)) { + _logger.info("Failover process veto-ed by client"); + _amqProtocolHandler.setStateManager(existingStateManager); if (_host != null) { @@ -105,6 +105,9 @@ public class FailoverHandler implements Runnable _amqProtocolHandler.setFailoverLatch(null); return; } + + _logger.info("Starting failover process"); + boolean failoverSucceeded; // when host is non null we have a specified failover host otherwise we all the client to cycle through // all specified hosts diff --git a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverSupport.java b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverSupport.java index bb7397f194..2e08d303c8 100644 --- a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverSupport.java +++ b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverSupport.java @@ -56,7 +56,7 @@ public abstract class FailoverSupport } catch (FailoverException e) { - _log.info("Failover exception caught during operation"); + _log.info("Failover exception caught during operation: " + e, e); } } } 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 0007ee8b5f..3ae13f949c 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 @@ -20,7 +20,6 @@ */ 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; @@ -29,13 +28,15 @@ import org.apache.qpid.client.AMQNoRouteException; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ChannelCloseBody; import org.apache.qpid.framing.ChannelCloseOkBody; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.log4j.Logger; + public class ChannelCloseMethodHandler implements StateAwareMethodListener { private static final Logger _logger = Logger.getLogger(ChannelCloseMethodHandler.class); @@ -46,24 +47,27 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener { return _handler; } + + private ChannelCloseMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { _logger.debug("ChannelClose method received"); - ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); + final ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); int errorCode = method.replyCode; - String reason = method.replyText; + String reason = method.replyText.asString(); if (_logger.isDebugEnabled()) { _logger.debug("Channel close reply code: " + errorCode + ", reason: " + reason); } - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - AMQMethodBody methodBody = ChannelCloseOkBody.createMethodBody((byte)0, (byte)9); + AMQMethodBody methodBody = ChannelCloseOkBody.createMethodBody( + protocolSession.getProtocolMajorVersion(), // AMQP major version + protocolSession.getProtocolMinorVersion()); // AMQP minor version protocolSession.writeResponse(evt.getChannelId(), evt.getRequestId(), methodBody); + if (errorCode != AMQConstant.REPLY_SUCCESS.getCode()) { _logger.error("Channel close received with errorCode " + errorCode + ", and reason " + reason); @@ -79,13 +83,12 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener { _logger.info("Broker responded with Invalid Selector."); - throw new AMQInvalidSelectorException(reason); + throw new AMQInvalidSelectorException(String.valueOf(reason)); } else { throw new AMQChannelClosedException(errorCode, "Error: " + reason); } - } protocolSession.channelClosed(evt.getChannelId(), errorCode, reason); } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java index a99c963eb4..4aef4bc1b6 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java @@ -21,10 +21,11 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.protocol.AMQMethodEvent; + import org.apache.log4j.Logger; public class ChannelCloseOkMethodHandler implements StateAwareMethodListener @@ -37,6 +38,8 @@ public class ChannelCloseOkMethodHandler implements StateAwareMethodListener { return _instance; } + + private ChannelCloseOkMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java index 7a13972d8f..e21ab5cba1 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java @@ -20,31 +20,31 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ChannelFlowOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +import org.apache.log4j.Logger; public class ChannelFlowOkMethodHandler implements StateAwareMethodListener { - private static final Logger _logger = Logger.getLogger(ChannelFlowOkMethodHandler.class); - private static final ChannelFlowOkMethodHandler _instance = new ChannelFlowOkMethodHandler(); + private static final Logger _logger = Logger.getLogger(ChannelFlowOkMethodHandler.class); + + private static final ChannelFlowOkMethodHandler _instance = new ChannelFlowOkMethodHandler(); - public static ChannelFlowOkMethodHandler getInstance() - { - return _instance; - } + public static ChannelFlowOkMethodHandler getInstance() + { + return _instance; + } - private ChannelFlowOkMethodHandler() - { - } + private ChannelFlowOkMethodHandler() {} - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - ChannelFlowOkBody method = (ChannelFlowOkBody) evt.getMethod(); - _logger.debug("Received Channel.Flow-Ok message, active = " + method.active); - } + public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException + { + ChannelFlowOkBody method = (ChannelFlowOkBody) evt.getMethod(); + _logger.debug("Received Channel.Flow-Ok message, active = " + method.active); + } } 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 25acd2cb6b..a5fdd4779a 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 @@ -20,18 +20,20 @@ */ 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.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.client.AMQAuthenticationException; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionCloseOkBody; +import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.protocol.AMQMethodEvent; + +import org.apache.log4j.Logger; public class ConnectionCloseMethodHandler implements StateAwareMethodListener { @@ -44,9 +46,7 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener return _handler; } - private ConnectionCloseMethodHandler() - { - } + private ConnectionCloseMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { @@ -57,13 +57,13 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener //stateManager.changeState(AMQState.CONNECTION_CLOSING); int errorCode = method.replyCode; - String reason = method.replyText; + AMQShortString reason = method.replyText; // TODO: check whether channel id of zero is appropriate - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - protocolSession.writeResponse(0, evt.getRequestId(), ConnectionCloseOkBody.createMethodBody((byte)0, (byte)9)); + protocolSession.writeResponse(0, evt.getRequestId(), ConnectionCloseOkBody.createMethodBody( + protocolSession.getProtocolMajorVersion(), // AMQP major version + protocolSession.getProtocolMinorVersion())); // AMQP minor version if (errorCode != 200) { @@ -76,7 +76,7 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener //todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state. stateManager.changeState(AMQState.CONNECTION_NOT_STARTED); - throw new AMQAuthenticationException(errorCode, reason); + throw new AMQAuthenticationException(errorCode, reason == null ? null : reason.toString()); } else { diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java index da903e7c1d..877d91e676 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java @@ -21,14 +21,19 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.ConnectionOpenOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(ConnectionOpenOkMethodHandler.class); + private static final ConnectionOpenOkMethodHandler _instance = new ConnectionOpenOkMethodHandler(); public static ConnectionOpenOkMethodHandler getInstance() @@ -36,13 +41,10 @@ public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener return _instance; } - private ConnectionOpenOkMethodHandler() - { - } + private ConnectionOpenOkMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { stateManager.changeState(AMQState.CONNECTION_OPEN); } - } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java index 699c8955bc..641a58f69b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java @@ -20,13 +20,14 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ConnectionRedirectBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +import org.apache.log4j.Logger; public class ConnectionRedirectMethodHandler implements StateAwareMethodListener { @@ -41,28 +42,27 @@ public class ConnectionRedirectMethodHandler implements StateAwareMethodListener return _handler; } - private ConnectionRedirectMethodHandler() - { - } + private ConnectionRedirectMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { _logger.info("ConnectionRedirect frame received"); ConnectionRedirectBody method = (ConnectionRedirectBody) evt.getMethod(); + String host = method.host.toString(); // the host is in the form hostname:port with the port being optional - int portIndex = method.host.indexOf(':'); - String host; + int portIndex = host.indexOf(':'); + int port; if (portIndex == -1) { - host = method.host; port = DEFAULT_REDIRECT_PORT; } else { - host = method.host.substring(0, portIndex); - port = Integer.parseInt(method.host.substring(portIndex + 1)); + port = Integer.parseInt(host.substring(portIndex + 1)); + host = host.substring(0, portIndex); + } protocolSession.failover(host, port); } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java index 94cf8b16c6..4b6963d2cf 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java @@ -21,26 +21,32 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.ConnectionSecureOkBody; import org.apache.qpid.framing.ConnectionSecureBody; +import org.apache.qpid.framing.ConnectionSecureOkBody; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; + +//import org.apache.log4j.Logger; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; public class ConnectionSecureMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(ConnectionSecureMethodHandler.class); + private static final ConnectionSecureMethodHandler _instance = new ConnectionSecureMethodHandler(); public static ConnectionSecureMethodHandler getInstance() { return _instance; } + + private ConnectionSecureMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { @@ -56,10 +62,11 @@ public class ConnectionSecureMethodHandler implements StateAwareMethodListener { // Evaluate server challenge byte[] response = client.evaluateChallenge(body.challenge); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. + // Be aware of possible changes to parameter order as versions change. - AMQMethodBody methodBody = ConnectionSecureOkBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) + AMQMethodBody methodBody = ConnectionSecureOkBody.createMethodBody( + protocolSession.getProtocolMajorVersion(), // AMQP major version + protocolSession.getProtocolMinorVersion(), // AMQP minor version response); // response protocolSession.writeResponse(evt.getChannelId(), evt.getRequestId(), methodBody); } @@ -67,7 +74,5 @@ public class ConnectionSecureMethodHandler implements StateAwareMethodListener { throw new AMQException("Error processing SASL challenge: " + e, e); } - - } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java index e58499f116..3e6bbcc3a5 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java @@ -20,22 +20,26 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.common.ClientProperties; import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.security.AMQCallbackHandler; import org.apache.qpid.client.security.CallbackHandlerRegistry; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionStartBody; import org.apache.qpid.framing.ConnectionStartOkBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.FieldTableFactory; +import org.apache.qpid.framing.ProtocolVersionList; import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.log4j.Logger; + import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; @@ -45,7 +49,6 @@ import java.util.StringTokenizer; public class ConnectionStartMethodHandler implements StateAwareMethodListener { - private static final Logger _log = Logger.getLogger(ConnectionStartMethodHandler.class); private static final ConnectionStartMethodHandler _instance = new ConnectionStartMethodHandler(); @@ -55,90 +58,110 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener return _instance; } - private ConnectionStartMethodHandler() - { - } + private ConnectionStartMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { ConnectionStartBody body = (ConnectionStartBody) evt.getMethod(); - try - { - // the mechanism we are going to use - String mechanism; - if (body.mechanisms == null) - { - throw new AMQException("mechanism not specified in ConnectionStart method frame"); - } - else - { - mechanism = chooseMechanism(body.mechanisms); - } + byte major = (byte) body.versionMajor; + byte minor = (byte) body.versionMinor; - if (mechanism == null) - { - throw new AMQException("No supported security mechanism found, passed: " + new String(body.mechanisms)); - } + if(checkVersionOK(major, minor)) + { + protocolSession.setProtocolVersion(major, minor); - byte[] saslResponse; try { - SaslClient sc = Sasl.createSaslClient(new String[]{mechanism}, + // the mechanism we are going to use + String mechanism; + if (body.mechanisms == null) + { + throw new AMQException("mechanism not specified in ConnectionStart method frame"); + } + else + { + mechanism = chooseMechanism(body.mechanisms); + } + + if (mechanism == null) + { + throw new AMQException("No supported security mechanism found, passed: " + new String(body.mechanisms)); + } + + byte[] saslResponse; + try + { + SaslClient sc = Sasl.createSaslClient(new String[]{mechanism}, null, "AMQP", "localhost", null, createCallbackHandler(mechanism, protocolSession)); - if (sc == null) + if (sc == null) + protocolSession.setSaslClient(sc); + saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); + } + catch (SaslException e) { - throw new AMQException("Client SASL configuration error: no SaslClient could be created for mechanism " + - mechanism + ". Please ensure all factories are registered. See DynamicSaslRegistrar for " + - " details of how to register non-standard SASL client providers."); + protocolSession.setSaslClient(null); + throw new AMQException("Unable to create SASL client: " + e, e); } - protocolSession.setSaslClient(sc); - saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); - } - catch (SaslException e) - { - protocolSession.setSaslClient(null); - throw new AMQException("Unable to create SASL client: " + e, e); - } - if (body.locales == null) - { - throw new AMQException("Locales is not defined in Connection Start method"); - } - final String locales = new String(body.locales, "utf8"); - final StringTokenizer tokenizer = new StringTokenizer(locales, " "); - String selectedLocale = null; - if (tokenizer.hasMoreTokens()) - { - selectedLocale = tokenizer.nextToken(); + final String locales = new String(body.locales, "utf8"); + final StringTokenizer tokenizer = new StringTokenizer(locales, " "); + String selectedLocale = null; + if (tokenizer.hasMoreTokens()) + { + selectedLocale = tokenizer.nextToken(); + } + else + { + throw new AMQException("No locales sent from server, passed: " + locales); + } + + stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); + FieldTable clientProperties = FieldTableFactory.newFieldTable(); + + clientProperties.put(new AMQShortString(ClientProperties.instance.toString()), protocolSession.getClientID()); + clientProperties.put(new AMQShortString(ClientProperties.product.toString()), QpidProperties.getProductName()); + clientProperties.put(new AMQShortString(ClientProperties.version.toString()), QpidProperties.getReleaseVersion()); + clientProperties.put(new AMQShortString(ClientProperties.platform.toString()), getFullSystemInfo()); + + // Be aware of possible changes to parameter order as versions change. + protocolSession.writeResponse(evt.getChannelId(), evt.getRequestId(), + ConnectionStartOkBody.createMethodBody(major, minor, // AMQP version (major, minor) + clientProperties, // clientProperties + new AMQShortString(selectedLocale), // locale + new AMQShortString(mechanism), // mechanism + saslResponse)); // response } - else + catch (UnsupportedEncodingException e) { - throw new AMQException("No locales sent from server, passed: " + locales); + throw new AMQException(_log, "Unable to decode data: " + e, e); } + } + else + { + _log.error("Broker requested Protocol [" + + body.versionMajor + + "-" + + body.versionMinor + + "] which is not supported by this version of the client library"); - stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - FieldTable clientProperties = FieldTableFactory.newFieldTable(); - - clientProperties.put(ClientProperties.instance.toString(), protocolSession.getClientID()); - clientProperties.put(ClientProperties.product.toString(), QpidProperties.getProductName()); - clientProperties.put(ClientProperties.version.toString(), QpidProperties.getReleaseVersion()); - clientProperties.put(ClientProperties.platform.toString(), getFullSystemInfo()); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - protocolSession.writeResponse(evt.getChannelId(), evt.getRequestId(), - ConnectionStartOkBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) - clientProperties, // clientProperties - selectedLocale, // locale - mechanism, // mechanism - saslResponse)); // response + protocolSession.closeProtocolSession(); } - catch (UnsupportedEncodingException e) + } + + private boolean checkVersionOK(byte versionMajor, byte versionMinor) + { + byte[][] supportedVersions = ProtocolVersionList.pv; + boolean supported = false; + int i = supportedVersions.length; + while(i-- != 0 && !supported) { - throw new AMQException(_log, "Unable to decode data: " + e, e); + supported = (supportedVersions[i][ProtocolVersionList.PROTOCOL_MAJOR] == versionMajor) + && (supportedVersions[i][ProtocolVersionList.PROTOCOL_MINOR] == versionMinor); } + + return supported; } private String getFullSystemInfo() diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java index f2524cfbc9..fd7c48b89f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java @@ -20,20 +20,21 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.client.ConnectionTuneParameters; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionOpenBody; import org.apache.qpid.framing.ConnectionTuneBody; import org.apache.qpid.framing.ConnectionTuneOkBody; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.log4j.Logger; + public class ConnectionTuneMethodHandler implements StateAwareMethodListener { private static final Logger _logger = Logger.getLogger(ConnectionTuneMethodHandler.class); @@ -45,9 +46,7 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener return _instance; } - protected ConnectionTuneMethodHandler() - { - } + protected ConnectionTuneMethodHandler() {} public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { @@ -66,29 +65,31 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener protocolSession.setConnectionTuneParameters(params); stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); - protocolSession.writeResponse(evt.getChannelId(), evt.getRequestId(), createTuneOkMethodBody(params)); + protocolSession.writeResponse(evt.getChannelId(), evt.getRequestId(), createTuneOkMethodBody(protocolSession, params)); + String host = protocolSession.getAMQConnection().getVirtualHost(); + AMQShortString virtualHost = new AMQShortString("/" + host); protocolSession.writeRequest(evt.getChannelId(), - createConnectionOpenMethodBody(protocolSession.getAMQConnection().getVirtualHost(), null, true), + createConnectionOpenMethodBody(protocolSession, virtualHost, null, true), protocolSession.getStateManager()); } - protected AMQMethodBody createConnectionOpenMethodBody(String path, String capabilities, boolean insist) + protected AMQMethodBody createConnectionOpenMethodBody(AMQProtocolSession protocolSession, AMQShortString path, AMQShortString capabilities, boolean insist) { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - return ConnectionOpenBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) + return ConnectionOpenBody.createMethodBody( + protocolSession.getProtocolMajorVersion(), // AMQP major version + protocolSession.getProtocolMinorVersion(), // AMQP minor version capabilities, // capabilities insist, // insist path); // virtualHost } - protected AMQMethodBody createTuneOkMethodBody(ConnectionTuneParameters params) + protected AMQMethodBody createTuneOkMethodBody(AMQProtocolSession protocolSession, ConnectionTuneParameters params) { - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - return ConnectionTuneOkBody.createMethodBody((byte)0, (byte)9, // AMQP version (major, minor) + return ConnectionTuneOkBody.createMethodBody( + protocolSession.getProtocolMajorVersion(), // AMQP major version + protocolSession.getProtocolMinorVersion(), // AMQP minor version params.getChannelMax(), // channelMax params.getFrameMax(), // frameMax params.getHeartbeat()); // heartbeat 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 index 41e57113b0..8a35a3d77a 100644 --- 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 @@ -17,7 +17,6 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; @@ -25,31 +24,29 @@ import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.ExchangeBoundOkBody; import org.apache.qpid.protocol.AMQMethodEvent; -/** - * @author Apache Software Foundation - */ +import org.apache.log4j.Logger; + 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, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - if (_logger.isDebugEnabled()) - { + 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, AMQProtocolSession protocolSession, 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/MessageAppendMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageAppendMethodHandler.java index 152a86ed63..361b63230f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageAppendMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageAppendMethodHandler.java @@ -20,35 +20,36 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageAppendBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageAppendBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +import org.apache.log4j.Logger; public class MessageAppendMethodHandler implements StateAwareMethodListener { - private static MessageAppendMethodHandler _instance = new MessageAppendMethodHandler(); private static final Logger _logger = Logger.getLogger(AMQProtocolSession.class); + private static MessageAppendMethodHandler _instance = new MessageAppendMethodHandler(); + public static MessageAppendMethodHandler getInstance() { return _instance; } private MessageAppendMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { - try { + try + { protocolSession.messageAppendBodyReceived((MessageAppendBody)evt.getMethod()); - } catch (Exception e) { + } + catch (Exception e) + { _logger.error("Unable to add data from MessageAppendBody",e); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageCheckpointMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageCheckpointMethodHandler.java index 4c897e33e5..af2844b686 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageCheckpointMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageCheckpointMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageCheckpointBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageCheckpointBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageCheckpointMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageCheckpointMethodHandler.class); + private static MessageCheckpointMethodHandler _instance = new MessageCheckpointMethodHandler(); public static MessageCheckpointMethodHandler getInstance() @@ -37,12 +41,8 @@ public class MessageCheckpointMethodHandler implements StateAwareMethodListener } private MessageCheckpointMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { // TODO } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageCloseMethodHandler.java index c7d1c60585..dfe15d3360 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageCloseMethodHandler.java @@ -20,18 +20,20 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageCloseBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageCloseBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +import org.apache.log4j.Logger; public class MessageCloseMethodHandler implements StateAwareMethodListener { - private static MessageCloseMethodHandler _instance = new MessageCloseMethodHandler(); private static final Logger _logger = Logger.getLogger(AMQProtocolSession.class); + + private static MessageCloseMethodHandler _instance = new MessageCloseMethodHandler(); public static MessageCloseMethodHandler getInstance() { @@ -39,12 +41,8 @@ public class MessageCloseMethodHandler implements StateAwareMethodListener } private MessageCloseMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { MessageCloseBody body = (MessageCloseBody)evt.getMethod(); String referenceId = new String(body.getReference()); diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageEmptyMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageEmptyMethodHandler.java index 93177cd8ec..1c866d8b44 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageEmptyMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageEmptyMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageEmptyBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageEmptyBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageEmptyMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageEmptyMethodHandler.class); + private static MessageEmptyMethodHandler _instance = new MessageEmptyMethodHandler(); public static MessageEmptyMethodHandler getInstance() @@ -37,12 +41,8 @@ public class MessageEmptyMethodHandler implements StateAwareMethodListener } private MessageEmptyMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { // TODO } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageOffsetMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageOffsetMethodHandler.java index 155a6157fa..7371816fb7 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageOffsetMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageOffsetMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageOffsetBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageOffsetBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageOffsetMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageOffsetMethodHandler.class); + private static MessageOffsetMethodHandler _instance = new MessageOffsetMethodHandler(); public static MessageOffsetMethodHandler getInstance() @@ -36,13 +40,9 @@ public class MessageOffsetMethodHandler implements StateAwareMethodListener return _instance; } - private MessageOffsetMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + private MessageOffsetMethodHandler() {} + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { // TODO } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageOkMethodHandler.java index 5b392eb599..34214a9178 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageOkMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageOkMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageOkMethodHandler.class); + private static MessageOkMethodHandler _instance = new MessageOkMethodHandler(); public static MessageOkMethodHandler getInstance() @@ -37,12 +41,8 @@ public class MessageOkMethodHandler implements StateAwareMethodListener } private MessageOkMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { // TODO } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageOpenMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageOpenMethodHandler.java index 13e05da85a..21bcee9066 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageOpenMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageOpenMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageOpenBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageOpenBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageOpenMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageOpenMethodHandler.class); + private static MessageOpenMethodHandler _instance = new MessageOpenMethodHandler(); public static MessageOpenMethodHandler getInstance() @@ -37,12 +41,8 @@ public class MessageOpenMethodHandler implements StateAwareMethodListener } private MessageOpenMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { // TODO } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageRejectMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageRejectMethodHandler.java index 92ad14594c..576e769531 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageRejectMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageRejectMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageRejectBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageRejectBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageRejectMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageRejectMethodHandler.class); + private static MessageRejectMethodHandler _instance = new MessageRejectMethodHandler(); public static MessageRejectMethodHandler getInstance() @@ -37,12 +41,8 @@ public class MessageRejectMethodHandler implements StateAwareMethodListener } private MessageRejectMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { // TODO } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageResumeMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageResumeMethodHandler.java index 691dd488ff..f670ca5b5a 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageResumeMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageResumeMethodHandler.java @@ -21,14 +21,18 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.MessageResumeBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.MessageResumeBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +//import org.apache.log4j.Logger; public class MessageResumeMethodHandler implements StateAwareMethodListener { + //private static final Logger _logger = Logger.getLogger(MessageResumeMethodHandler.class); + private static MessageResumeMethodHandler _instance = new MessageResumeMethodHandler(); public static MessageResumeMethodHandler getInstance() @@ -37,14 +41,10 @@ public class MessageResumeMethodHandler implements StateAwareMethodListener } private MessageResumeMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { - System.out.println(""); + // TODO } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/MessageTransferMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/MessageTransferMethodHandler.java index f278fb5116..d16f0c1fc4 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/MessageTransferMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/MessageTransferMethodHandler.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.client.handler; -import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.client.message.MessageHeaders; import org.apache.qpid.client.message.UnprocessedMessage; @@ -31,10 +30,13 @@ import org.apache.qpid.framing.Content; import org.apache.qpid.framing.MessageTransferBody; import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.log4j.Logger; + public class MessageTransferMethodHandler implements StateAwareMethodListener { - private static MessageTransferMethodHandler _instance = new MessageTransferMethodHandler(); private static final Logger _logger = Logger.getLogger(MessageTransferMethodHandler.class); + + private static MessageTransferMethodHandler _instance = new MessageTransferMethodHandler(); public static MessageTransferMethodHandler getInstance() { @@ -42,18 +44,11 @@ public class MessageTransferMethodHandler implements StateAwareMethodListener } private MessageTransferMethodHandler() {} - - - public void methodReceived (AMQStateManager stateManager, - AMQProtocolSession protocolSession, - AMQMethodEvent evt) - throws AMQException + + public void methodReceived (AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException { - final UnprocessedMessage msg = new UnprocessedMessage(); MessageTransferBody transferBody = (MessageTransferBody) evt.getMethod(); - msg.channelId = evt.getChannelId(); - msg.deliveryTag = evt.getRequestId(); _logger.debug("New JmsDeliver method received"); MessageHeaders messageHeaders = new MessageHeaders(); @@ -73,7 +68,7 @@ public class MessageTransferMethodHandler implements StateAwareMethodListener messageHeaders.setDeliveryMode(transferBody.getDeliveryMode()); messageHeaders.setJMSHeaders(transferBody.getApplicationHeaders()); - msg.contentHeader = messageHeaders; + final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(), evt.getRequestId(), messageHeaders); if(transferBody.getBody().getContentType() == Content.TypeEnum.INLINE_T) { 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 index b8b75accb4..d2618960dd 100644 --- 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 @@ -17,38 +17,35 @@ */ package org.apache.qpid.client.handler; +import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.AMQException; +import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.QueueDeleteOkBody; import org.apache.qpid.protocol.AMQMethodEvent; + 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, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - if (_logger.isDebugEnabled()) - { + 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, AMQProtocolSession protocolSession, 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/AbstractBytesMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java index f27436393b..1afd3fdd40 100644 --- 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 @@ -22,6 +22,7 @@ package org.apache.qpid.client.message; import java.io.IOException; import java.nio.charset.Charset; +import org.apache.qpid.framing.AMQShortString; import javax.jms.JMSException; import javax.jms.MessageEOFException; @@ -54,7 +55,7 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage AbstractBytesMessage(ByteBuffer data) { super(data); // this instanties a content header - getMessageHeaders().setContentType(getMimeType()); + getMessageHeaders().setContentType(getMimeTypeAsShortString()); if (_data == null) { @@ -68,13 +69,12 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage _data.setAutoExpand(true); } - AbstractBytesMessage(long messageNbr, MessageHeaders contentHeader, ByteBuffer data) throws AMQException { // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea super(messageNbr, contentHeader, data); - getMessageHeaders().setContentType(getMimeType()); + getMessageHeaders().setContentType(getMimeTypeAsShortString()); } public void clearBodyImpl() throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java index 7b97a8b065..c806a93015 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesTypedMessage.java @@ -10,6 +10,7 @@ import javax.jms.MessageNotReadableException; import javax.jms.MessageNotWriteableException;
import org.apache.mina.common.ByteBuffer;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.AMQException;
/**
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 2de86b2cb3..6b55e5237b 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 @@ -34,15 +34,22 @@ import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.BasicMessageConsumer; -import org.apache.qpid.client.CustomJMXProperty; +import org.apache.qpid.client.CustomJMSXProperty; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.BindingURL; import org.apache.qpid.url.URLSyntaxException; +import javax.jms.*; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; + public abstract class AbstractJMSMessage extends AMQMessage implements org.apache.qpid.jms.Message { private static final Map _destinationCache = Collections.synchronizedMap(new ReferenceMap()); + protected boolean _redelivered; @@ -51,6 +58,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach protected boolean _readableMessage = false; protected boolean _changedData; private Destination _destination; + private JMSHeaderAdapter _headerAdapter; private BasicMessageConsumer _consumer; protected AbstractJMSMessage(ByteBuffer data) @@ -84,17 +92,29 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach _readableProperties = (_messageHeaders != null); } - public String getJMSMessageID() throws JMSException + public AMQShortString getJMSMessageIDAsShortString() throws JMSException { if (getMessageHeaders().getMessageId() == null) { - getMessageHeaders().setMessageId("ID:" + _deliveryTag); + getMessageHeaders().setMessageId(new AMQShortString("ID:" + _deliveryTag)); } return getMessageHeaders().getMessageId(); } + + // The String version is required for javax.jms.Message + public String getJMSMessageID() throws JMSException + { + return getJMSMessageIDAsShortString().asString(); + } + // The String version is required for javax.jms.Message public void setJMSMessageID(String messageId) throws JMSException { + setJMSMessageID(new AMQShortString(messageId)); + } + + public void setJMSMessageID(AMQShortString messageId) throws JMSException + { getMessageHeaders().setMessageId(messageId); } @@ -115,22 +135,35 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException { - getMessageHeaders().setCorrelationId(new String(bytes)); + getMessageHeaders().setCorrelationId(new AMQShortString(bytes)); } + // The String version is required for javax.jms.Message public void setJMSCorrelationID(String correlationId) throws JMSException { + setJMSCorrelationID(new AMQShortString(correlationId)); + } + + public void setJMSCorrelationID(AMQShortString correlationId) throws JMSException + { getMessageHeaders().setCorrelationId(correlationId); } - public String getJMSCorrelationID() throws JMSException + public AMQShortString getJMSCorrelationIDAsShortString() throws JMSException { return getMessageHeaders().getCorrelationId(); } + // The String version is required for javax.jms.Message + public String getJMSCorrelationID() throws JMSException + { + AMQShortString ss = getMessageHeaders().getCorrelationId(); + return ss == null ? null : ss.asString(); + } + public Destination getJMSReplyTo() throws JMSException { - String replyToEncoding = getMessageHeaders().getReplyTo(); + AMQShortString replyToEncoding = getMessageHeaders().getReplyTo(); if (replyToEncoding == null) { return null; @@ -142,7 +175,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach { try { - BindingURL binding = new AMQBindingURL(replyToEncoding); + BindingURL binding = new AMQBindingURL(replyToEncoding.asString()); dest = AMQDestination.createDestination(binding); } catch (URLSyntaxException e) @@ -165,11 +198,11 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach if (!(destination instanceof AMQDestination)) { throw new IllegalArgumentException("ReplyTo destination may only be an AMQDestination - passed argument was type " + - destination.getClass()); + destination.getClass()); } final AMQDestination amqd = (AMQDestination) destination; - final String encodedDestination = amqd.getEncodedName(); + final AMQShortString encodedDestination = amqd.getEncodedName(); _destinationCache.put(encodedDestination, destination); getMessageHeaders().setReplyTo(encodedDestination); } @@ -179,7 +212,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach return _destination; } - public void setJMSDestination(Destination destination) throws JMSException + public void setJMSDestination(Destination destination) { _destination = destination; } @@ -209,7 +242,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach // Since the type field is not a part of message.transport and is used only for // JMS messages, this change to JMS Headers solves the problem. // return getMessageHeaders().getType(); - return getStringProperty(CustomJMXProperty.JMSXType.toString()); + return getStringProperty(CustomJMSXProperty.JMSXType.toString()); } public void setJMSType(String string) throws JMSException @@ -217,7 +250,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach // Since the type field is not a part of message.transport and is used only for // JMS messages, this change to JMS Headers solves the problem. // getMessageHeaders().setType(string); - setStringProperty(CustomJMXProperty.JMSXType.toString(), string); + setStringProperty(CustomJMSXProperty.JMSXType.toString(), string); } public long getJMSExpiration() throws JMSException @@ -243,7 +276,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public void clearProperties() throws JMSException { getMessageHeaders().getJMSHeaders().clear(); - _readableProperties = false; } @@ -253,11 +285,24 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach _readableMessage = false; } + public boolean propertyExists(AMQShortString propertyName) throws JMSException + { + checkPropertyName(propertyName); + return getMessageHeaders().getJMSHeaders().propertyExists(propertyName); + } public boolean propertyExists(String propertyName) throws JMSException { + return propertyExists(new AMQShortString(propertyName)); + } + + public boolean getBooleanProperty(AMQShortString propertyName) throws JMSException + { checkPropertyName(propertyName); - return getMessageHeaders().getJMSHeaders().propertyExists(propertyName); + Boolean b = getMessageHeaders().getJMSHeaders().getBoolean(propertyName); + if (b != null) + return b; + return false; } public boolean getBooleanProperty(String propertyName) throws JMSException @@ -267,7 +312,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach if (b != null) return b; return false; -// return getMessageHeaders().getJMSHeaders().getBoolean(propertyName); } public byte getByteProperty(String propertyName) throws JMSException @@ -277,7 +321,13 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach if (b == null) throw new NumberFormatException("Byte value null"); return b; -// return getMessageHeaders().getJMSHeaders().getByte(propertyName); + } + + public byte[] getBytesProperty(AMQShortString propertyName) throws JMSException + { + checkPropertyName(propertyName); + return getMessageHeaders().getJMSHeaders().getBytes(propertyName); + } public short getShortProperty(String propertyName) throws JMSException @@ -291,7 +341,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach if (b == null) throw new NumberFormatException("Short value null"); return (short)b; -// return getMessageHeaders().getJMSHeaders().getShort(propertyName); } public int getIntProperty(String propertyName) throws JMSException @@ -309,7 +358,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach if (b == null) throw new NumberFormatException("Int value null"); return (short)b; -// return getMessageHeaders().getJMSHeaders().getInteger(propertyName); } public long getLongProperty(String propertyName) throws JMSException @@ -318,6 +366,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach Long l = getMessageHeaders().getJMSHeaders().getLong(propertyName); if (l != null) return l; + // try Integer Integer i = getMessageHeaders().getJMSHeaders().getInteger(propertyName); if (i != null) return i; @@ -330,7 +379,6 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach if (b == null) throw new NumberFormatException("Long value null"); return (short)b; -// return getMessageHeaders().getJMSHeaders().getLong(propertyName); } public float getFloatProperty(String propertyName) throws JMSException @@ -374,13 +422,18 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach return getMessageHeaders().getJMSHeaders().getPropertyNames(); } - public void setBooleanProperty(String propertyName, boolean b) throws JMSException + public void setBooleanProperty(AMQShortString propertyName, boolean b) throws JMSException { checkWritableProperties(); checkPropertyName(propertyName); getMessageHeaders().getJMSHeaders().setBoolean(propertyName, b); } + public void setBooleanProperty(String propertyName, boolean b) throws JMSException + { + setBooleanProperty(new AMQShortString(propertyName), b); + } + public void setByteProperty(String propertyName, byte b) throws JMSException { checkWritableProperties(); @@ -437,7 +490,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach getMessageHeaders().getJMSHeaders().setObject(propertyName, object); } - protected void removeProperty(String propertyName) throws JMSException + protected void removeProperty(AMQShortString propertyName) throws JMSException { checkPropertyName(propertyName); getMessageHeaders().getJMSHeaders().remove(propertyName); @@ -468,7 +521,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public void acknowledge() throws JMSException { - if(_session != null) + if (_session != null) { _session.acknowledge(); } @@ -488,7 +541,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach */ public abstract String toBodyString() throws JMSException; - public abstract String getMimeType(); + public String getMimeType() + { + return getMimeTypeAsShortString().toString(); + } + + public abstract AMQShortString getMimeTypeAsShortString(); public String toString() { @@ -496,6 +554,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach { StringBuffer buf = new StringBuffer("Body:\n"); buf.append(toBodyString()); + buf.append("\nJMS Correlation ID: ").append(getJMSCorrelationID()); buf.append("\nJMS timestamp: ").append(getJMSTimestamp()); buf.append("\nJMS expiration: ").append(getJMSExpiration()); buf.append("\nJMS priority: ").append(getJMSPriority()); @@ -525,13 +584,13 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach getMessageHeaders().setJMSHeaders(messageProperties); } - private void checkPropertyName(String propertyName) + private void checkPropertyName(CharSequence propertyName) { if (propertyName == null) { throw new IllegalArgumentException("Property name must not be null"); } - else if ("".equals(propertyName)) + else if (propertyName.length() == 0) { throw new IllegalArgumentException("Property name must not be the empty string"); } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java index 73901c5cf2..b0b45478a3 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java @@ -20,6 +20,9 @@ */ package org.apache.qpid.client.message; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; + import java.util.Iterator; import java.util.List; @@ -27,7 +30,6 @@ import javax.jms.JMSException; import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; public abstract class AbstractJMSMessageFactory implements MessageFactory { @@ -61,5 +63,4 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory msg.setJMSRedelivered(redelivered); return msg; } - } 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 6943f277ca..9f0d51e9e4 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 @@ -25,6 +25,7 @@ import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; +import org.apache.qpid.framing.AMQShortString; import javax.jms.BytesMessage; import javax.jms.JMSException; @@ -35,9 +36,11 @@ import org.apache.qpid.AMQException; public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessage { - private static final String MIME_TYPE = "application/octet-stream"; + public static final String MIME_TYPE = "application/octet-stream"; + private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); - JMSBytesMessage() + + public JMSBytesMessage() { this(null); } @@ -65,9 +68,9 @@ public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessag _readableMessage = true; } - public String getMimeType() + public AMQShortString getMimeTypeAsShortString() { - return MIME_TYPE; + return MIME_TYPE_SHORT_STRING; } public long getBodyLength() throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java index ed8586a06b..2045d571b7 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessageFactory.java @@ -24,6 +24,7 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; public class JMSBytesMessageFactory extends AbstractJMSMessageFactory { diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java new file mode 100644 index 0000000000..3086e5b90a --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSHeaderAdapter.java @@ -0,0 +1,527 @@ +/*
+ *
+ * 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.qpid.framing.FieldTable;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.AMQPInvalidClassException;
+import org.apache.mina.common.ByteBuffer;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import java.util.Enumeration;
+
+
+public final class JMSHeaderAdapter
+{
+ private final FieldTable _headers;
+
+ public JMSHeaderAdapter(FieldTable headers)
+ {
+ _headers = headers;
+ }
+
+
+ public FieldTable getHeaders()
+ {
+ return _headers;
+ }
+
+ public boolean getBoolean(String string) throws JMSException
+ {
+ Boolean b = getHeaders().getBoolean(string);
+
+ if (b == null)
+ {
+ if (getHeaders().containsKey(string))
+ {
+ Object str = getHeaders().getObject(string);
+
+ if (str == null || !(str instanceof String))
+ {
+ throw new MessageFormatException("getBoolean can't use " + string + " item.");
+ }
+ else
+ {
+ return Boolean.valueOf((String) str);
+ }
+ }
+ else
+ {
+ b = Boolean.valueOf(null);
+ }
+ }
+
+ return b;
+ }
+
+ public boolean getBoolean(AMQShortString string) throws JMSException
+ {
+ Boolean b = getHeaders().getBoolean(string);
+
+ if (b == null)
+ {
+ if (getHeaders().containsKey(string))
+ {
+ Object str = getHeaders().getObject(string);
+
+ if (str == null || !(str instanceof String))
+ {
+ throw new MessageFormatException("getBoolean can't use " + string + " item.");
+ }
+ else
+ {
+ return Boolean.valueOf((String) str);
+ }
+ }
+ else
+ {
+ b = Boolean.valueOf(null);
+ }
+ }
+
+ return b;
+ }
+
+ public char getCharacter(String string) throws JMSException
+ {
+ Character c = getHeaders().getCharacter(string);
+
+ if (c == null)
+ {
+ if (getHeaders().isNullStringValue(string))
+ {
+ throw new NullPointerException("Cannot convert null char");
+ }
+ else
+ {
+ throw new MessageFormatException("getChar can't use " + string + " item.");
+ }
+ }
+ else
+ {
+ return (char) c;
+ }
+ }
+
+ public byte[] getBytes(String string) throws JMSException
+ {
+ return getBytes(new AMQShortString(string));
+ }
+
+ public byte[] getBytes(AMQShortString string) throws JMSException
+ {
+ byte[] bs = getHeaders().getBytes(string);
+
+ if (bs == null)
+ {
+ throw new MessageFormatException("getBytes can't use " + string + " item.");
+ }
+ else
+ {
+ return bs;
+ }
+ }
+
+ public byte getByte(String string) throws JMSException
+ {
+ Byte b = getHeaders().getByte(string);
+ if (b == null)
+ {
+ if (getHeaders().containsKey(string))
+ {
+ Object str = getHeaders().getObject(string);
+
+ if (str == null || !(str instanceof String))
+ {
+ throw new MessageFormatException("getByte can't use " + string + " item.");
+ }
+ else
+ {
+ return Byte.valueOf((String) str);
+ }
+ }
+ else
+ {
+ b = Byte.valueOf(null);
+ }
+ }
+
+ return b;
+ }
+
+ public short getShort(String string) throws JMSException
+ {
+ Short s = getHeaders().getShort(string);
+
+ if (s == null)
+ {
+ s = Short.valueOf(getByte(string));
+ }
+
+ return s;
+ }
+
+ public int getInteger(String string) throws JMSException
+ {
+ Integer i = getHeaders().getInteger(string);
+
+ if (i == null)
+ {
+ i = Integer.valueOf(getShort(string));
+ }
+
+ return i;
+ }
+
+ public long getLong(String string) throws JMSException
+ {
+ Long l = getHeaders().getLong(string);
+
+ if (l == null)
+ {
+ l = Long.valueOf(getInteger(string));
+ }
+
+ return l;
+ }
+
+ public float getFloat(String string) throws JMSException
+ {
+ Float f = getHeaders().getFloat(string);
+
+ if (f == null)
+ {
+ if (getHeaders().containsKey(string))
+ {
+ Object str = getHeaders().getObject(string);
+
+ if (str == null || !(str instanceof String))
+ {
+ throw new MessageFormatException("getFloat can't use " + string + " item.");
+ }
+ else
+ {
+ return Float.valueOf((String) str);
+ }
+ }
+ else
+ {
+ f = Float.valueOf(null);
+ }
+
+ }
+
+ return f;
+ }
+
+ public double getDouble(String string) throws JMSException
+ {
+ Double d = getHeaders().getDouble(string);
+
+ if (d == null)
+ {
+ d = Double.valueOf(getFloat(string));
+ }
+
+ return d;
+ }
+
+ public String getString(String string) throws JMSException
+ {
+ String s = getHeaders().getString(string);
+
+ if (s == null)
+ {
+ if (getHeaders().containsKey(string))
+ {
+ Object o = getHeaders().getObject(string);
+ if (o instanceof byte[])
+ {
+ throw new MessageFormatException("getObject couldn't find " + string + " item.");
+ }
+ else
+ {
+ if (o == null)
+ {
+ return null;
+ }
+ else
+ {
+ s = String.valueOf(o);
+ }
+ }
+ }
+ }
+
+ return s;
+ }
+
+ public Object getObject(String string) throws JMSException
+ {
+ return getHeaders().getObject(string);
+ }
+
+ public void setBoolean(AMQShortString string, boolean b) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setBoolean(string, b);
+ }
+
+ public void setBoolean(String string, boolean b) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setBoolean(string, b);
+ }
+
+ public void setChar(String string, char c) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setChar(string, c);
+ }
+
+ public Object setBytes(AMQShortString string, byte[] bytes)
+ {
+ return getHeaders().setBytes(string, bytes);
+ }
+
+ public Object setBytes(String string, byte[] bytes)
+ {
+ return getHeaders().setBytes(string, bytes);
+ }
+
+ public Object setBytes(String string, byte[] bytes, int start, int length)
+ {
+ return getHeaders().setBytes(string, bytes, start, length);
+ }
+
+ public void setByte(String string, byte b) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setByte(string, b);
+ }
+
+ public void setByte(AMQShortString string, byte b) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setByte(string, b);
+ }
+
+
+ public void setShort(String string, short i) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setShort(string, i);
+ }
+
+ public void setInteger(String string, int i) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setInteger(string, i);
+ }
+
+ public void setInteger(AMQShortString string, int i) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setInteger(string, i);
+ }
+
+ public void setLong(String string, long l) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setLong(string, l);
+ }
+
+ public void setFloat(String string, float v) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setFloat(string, v);
+ }
+
+ public void setDouble(String string, double v) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setDouble(string, v);
+ }
+
+ public void setString(String string, String string1) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setString(string, string1);
+ }
+
+ public void setString(AMQShortString string, String string1) throws JMSException
+ {
+ checkPropertyName(string);
+ getHeaders().setString(string, string1);
+ }
+
+ public void setObject(String string, Object object) throws JMSException
+ {
+ checkPropertyName(string);
+ try
+ {
+ getHeaders().setObject(string, object);
+ }
+ catch (AMQPInvalidClassException aice)
+ {
+ throw new MessageFormatException("Only primatives are allowed object is:" + object.getClass());
+ }
+ }
+
+ public boolean itemExists(String string) throws JMSException
+ {
+ return getHeaders().containsKey(string);
+ }
+
+ public Enumeration getPropertyNames()
+ {
+ return getHeaders().getPropertyNames();
+ }
+
+ public void clear()
+ {
+ getHeaders().clear();
+ }
+
+ public boolean propertyExists(AMQShortString propertyName)
+ {
+ return getHeaders().propertyExists(propertyName);
+ }
+
+ public boolean propertyExists(String propertyName)
+ {
+ return getHeaders().propertyExists(propertyName);
+ }
+
+ public Object put(Object key, Object value)
+ {
+ return getHeaders().setObject(key.toString(), value);
+ }
+
+ public Object remove(AMQShortString propertyName)
+ {
+ return getHeaders().remove(propertyName);
+ }
+
+ public Object remove(String propertyName)
+ {
+ return getHeaders().remove(propertyName);
+ }
+
+ public boolean isEmpty()
+ {
+ return getHeaders().isEmpty();
+ }
+
+ public void writeToBuffer(ByteBuffer data)
+ {
+ getHeaders().writeToBuffer(data);
+ }
+
+ public Enumeration getMapNames()
+ {
+ return getPropertyNames();
+ }
+
+ protected static void checkPropertyName(CharSequence propertyName)
+ {
+ if (propertyName == null)
+ {
+ throw new IllegalArgumentException("Property name must not be null");
+ }
+ else if (propertyName.length() == 0)
+ {
+ throw new IllegalArgumentException("Property name must not be the empty string");
+ }
+
+ checkIdentiferFormat(propertyName);
+ }
+
+ protected static void checkIdentiferFormat(CharSequence propertyName)
+ {
+// JMS requirements 3.5.1 Property Names
+// Identifiers:
+// - An identifier is an unlimited-length character sequence that must begin
+// with a Java identifier start character; all following characters must be Java
+// identifier part characters. An identifier start character is any character for
+// which the method Character.isJavaIdentifierStart returns true. This includes
+// '_' and '$'. An identifier part character is any character for which the
+// method Character.isJavaIdentifierPart returns true.
+// - Identifiers cannot be the names NULL, TRUE, or FALSE.
+// – Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or
+// ESCAPE.
+// – Identifiers are either header field references or property references. The
+// type of a property value in a message selector corresponds to the type
+// used to set the property. If a property that does not exist in a message is
+// referenced, its value is NULL. The semantics of evaluating NULL values
+// in a selector are described in Section 3.8.1.2, “Null Values.”
+// – The conversions that apply to the get methods for properties do not
+// apply when a property is used in a message selector expression. For
+// example, suppose you set a property as a string value, as in the
+// following:
+// myMessage.setStringProperty("NumberOfOrders", "2");
+// The following expression in a message selector would evaluate to false,
+// because a string cannot be used in an arithmetic expression:
+// "NumberOfOrders > 1"
+// – Identifiers are case sensitive.
+// – Message header field references are restricted to JMSDeliveryMode,
+// JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and
+// JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be
+// null and if so are treated as a NULL value.
+
+ if (Boolean.getBoolean("strict-jms"))
+ {
+ // JMS start character
+ if (!(Character.isJavaIdentifierStart(propertyName.charAt(0))))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid JMS identifier start character");
+ }
+
+ // JMS part character
+ int length = propertyName.length();
+ for (int c = 1; c < length; c++)
+ {
+ if (!(Character.isJavaIdentifierPart(propertyName.charAt(c))))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' contains an invalid JMS identifier character");
+ }
+ }
+
+ // JMS invalid names
+ if ((propertyName.equals("NULL")
+ || propertyName.equals("TRUE")
+ || propertyName.equals("FALSE")
+ || propertyName.equals("NOT")
+ || propertyName.equals("AND")
+ || propertyName.equals("OR")
+ || propertyName.equals("BETWEEN")
+ || propertyName.equals("LIKE")
+ || propertyName.equals("IN")
+ || propertyName.equals("IS")
+ || propertyName.equals("ESCAPE")))
+ {
+ throw new IllegalArgumentException("Identifier '" + propertyName + "' is not allowed in JMS");
+ }
+ }
+
+ }
+}
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 04bb8602bf..10be047388 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 @@ -25,13 +25,14 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.AMQException; import javax.jms.JMSException; import javax.jms.MessageFormatException; import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jms.MapMessage { @@ -39,10 +40,11 @@ public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jm public static final String MIME_TYPE = "jms/map-message"; + private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); private Map<String,Object> _map = new HashMap<String, Object>(); - JMSMapMessage() throws JMSException + public JMSMapMessage() throws JMSException { this(null); } @@ -67,15 +69,14 @@ public class JMSMapMessage extends AbstractBytesTypedMessage implements javax.jm } } - public String toBodyString() throws JMSException { return _map.toString(); } - public String getMimeType() + public AMQShortString getMimeTypeAsShortString() { - return MIME_TYPE; + return MIME_TYPE_SHORT_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 072c9b0f16..ddbf65e408 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 @@ -23,6 +23,7 @@ package org.apache.qpid.client.message; import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.AMQException; public class JMSMapMessageFactory extends AbstractJMSMessageFactory 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 f8a61b32d3..a2985161ae 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 @@ -27,6 +27,7 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; +import org.apache.qpid.framing.AMQShortString; import javax.jms.JMSException; import javax.jms.MessageFormatException; @@ -37,14 +38,15 @@ import org.apache.qpid.AMQException; public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage { - static final String MIME_TYPE = "application/java-object-stream"; + public static final String MIME_TYPE = "application/java-object-stream"; + private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); private static final int DEFAULT_BUFFER_SIZE = 1024; /** * Creates empty, writable message for use by producers */ - JMSObjectMessage() + public JMSObjectMessage() { this(null); } @@ -57,7 +59,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); _data.setAutoExpand(true); } - getMessageHeaders().setContentType(MIME_TYPE); + getMessageHeaders().setContentType(MIME_TYPE_SHORT_STRING); } /** @@ -83,9 +85,9 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag return toString(_data); } - public String getMimeType() + public AMQShortString getMimeTypeAsShortString() { - return MIME_TYPE; + return MIME_TYPE_SHORT_STRING; } public void setObject(Serializable serializable) throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java index 6980022746..9613ded522 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessageFactory.java @@ -24,6 +24,7 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; public class JMSObjectMessageFactory extends AbstractJMSMessageFactory { 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 index 6be367f07a..7bf5c760b5 100644 --- 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 @@ -25,6 +25,7 @@ import javax.jms.StreamMessage; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; /** * @author Apache Software Foundation @@ -32,6 +33,7 @@ import org.apache.qpid.AMQException; public class JMSStreamMessage extends AbstractBytesTypedMessage implements StreamMessage { public static final String MIME_TYPE="jms/stream-message"; + private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); /** @@ -40,7 +42,7 @@ public class JMSStreamMessage extends AbstractBytesTypedMessage implements Strea */ private int _byteArrayRemaining = -1; - JMSStreamMessage() + public JMSStreamMessage() { this(null); } @@ -69,9 +71,9 @@ public class JMSStreamMessage extends AbstractBytesTypedMessage implements Strea _readableMessage = true; } - public String getMimeType() + public AMQShortString getMimeTypeAsShortString() { - return MIME_TYPE; + return MIME_TYPE_SHORT_STRING; } 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 index 7517fea16d..86b9a2a899 100644 --- 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 @@ -23,6 +23,7 @@ package org.apache.qpid.client.message; import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.AMQException; public class JMSStreamMessageFactory extends AbstractJMSMessageFactory 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 a436f2b0f1..51712ef88d 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 @@ -20,6 +20,9 @@ */ package org.apache.qpid.client.message; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.AMQException; + import java.io.UnsupportedEncodingException; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; @@ -27,42 +30,49 @@ import java.nio.charset.Charset; import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.TextMessage { private static final String MIME_TYPE = "text/plain"; + private static final AMQShortString MIME_TYPE_SHORT_STRING = new AMQShortString(MIME_TYPE); + 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"; + private static final AMQShortString PAYLOAD_NULL_PROPERTY = new AMQShortString("JMS_QPID_NULL"); + private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); - JMSTextMessage() throws JMSException + public JMSTextMessage() throws JMSException { - this(null, null); + this(null, (AMQShortString)null); } - JMSTextMessage(ByteBuffer data, String encoding) throws JMSException + JMSTextMessage(ByteBuffer data, AMQShortString encoding) throws JMSException { super(data); // this instantiates a content header - getMessageHeaders().setContentType(MIME_TYPE); + getMessageHeaders().setContentType(MIME_TYPE_SHORT_STRING); getMessageHeaders().setEncoding(encoding); } + JMSTextMessage(ByteBuffer data, String encoding) throws JMSException + { + this(data, new AMQShortString(encoding)); + } + JMSTextMessage(long deliveryTag, MessageHeaders contentHeader, ByteBuffer data) throws AMQException { super(deliveryTag, contentHeader, data); - contentHeader.setContentType(MIME_TYPE); + contentHeader.setContentType(MIME_TYPE_SHORT_STRING); _data = data; } JMSTextMessage(ByteBuffer data) throws JMSException { - this(data, null); + this(data, (AMQShortString)null); } JMSTextMessage(String text) throws JMSException @@ -91,9 +101,9 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text _data = data; } - public String getMimeType() + public AMQShortString getMimeTypeAsShortString() { - return MIME_TYPE; + return MIME_TYPE_SHORT_STRING; } public void setText(String text) throws JMSException @@ -115,7 +125,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text } else { - _data.put(text.getBytes(getMessageHeaders().getEncoding())); + _data.put(text.getBytes(getMessageHeaders().getEncoding().asString())); } _changedData=true; } @@ -151,7 +161,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text { try { - _decodedValue = _data.getString(Charset.forName(getMessageHeaders().getEncoding()).newDecoder()); + _decodedValue = _data.getString(Charset.forName(getMessageHeaders().getEncoding().asString()).newDecoder()); } catch (CharacterCodingException e) { @@ -164,7 +174,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text { try { - _decodedValue = _data.getString(Charset.defaultCharset().newDecoder()); + _decodedValue = _data.getString(DEFAULT_CHARSET.newDecoder()); } catch (CharacterCodingException e) { diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java index 64b1fc3892..27882b65fc 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessageFactory.java @@ -24,6 +24,7 @@ import javax.jms.JMSException; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; public class JMSTextMessageFactory extends AbstractJMSMessageFactory { diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java new file mode 100644 index 0000000000..58089f595b --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageConverter.java @@ -0,0 +1,179 @@ +/* + * + * 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.log4j.Logger; + +import javax.jms.*; +import java.util.Enumeration; + +public class MessageConverter { + + /** + * Log4J logger + */ + protected final Logger _logger = Logger.getLogger(getClass()); + + /** + * AbstractJMSMessage which will hold the converted message + */ + private AbstractJMSMessage _newMessage; + + public MessageConverter(AbstractJMSMessage message) throws JMSException + { + _newMessage = message; + } + + public MessageConverter(BytesMessage message) throws JMSException + { + BytesMessage bytesMessage = (BytesMessage) message; + bytesMessage.reset(); + + JMSBytesMessage nativeMsg = new JMSBytesMessage(); + + byte[] buf = new byte[1024]; + + int len; + + while ((len = bytesMessage.readBytes(buf)) != -1) + { + nativeMsg.writeBytes(buf, 0, len); + } + + _newMessage = nativeMsg; + setMessageProperties(message); + } + + public MessageConverter(MapMessage message) throws JMSException + { + MapMessage nativeMessage = new JMSMapMessage(); + + Enumeration mapNames = message.getMapNames(); + while (mapNames.hasMoreElements()) + { + String name = (String) mapNames.nextElement(); + nativeMessage.setObject(name, message.getObject(name)); + } + _newMessage = (AbstractJMSMessage) nativeMessage; + setMessageProperties(message); + } + + public MessageConverter(ObjectMessage message) throws JMSException + { + ObjectMessage origMessage = (ObjectMessage) message; + ObjectMessage nativeMessage = new JMSObjectMessage(); + + nativeMessage.setObject(origMessage.getObject()); + + _newMessage = (AbstractJMSMessage) nativeMessage; + setMessageProperties(message); + + } + + public MessageConverter(TextMessage message) throws JMSException + { + TextMessage nativeMessage = new JMSTextMessage(); + + nativeMessage.setText(message.getText()); + + _newMessage = (AbstractJMSMessage) nativeMessage; + setMessageProperties(message); + } + + public MessageConverter(StreamMessage message) throws JMSException + { + StreamMessage nativeMessage = new JMSStreamMessage(); + + try + { + message.reset(); + while (true) + { + nativeMessage.writeObject(message.readObject()); + } + } + catch (MessageEOFException e) + { + //we're at the end so don't mind the exception + } + _newMessage = (AbstractJMSMessage) nativeMessage; + setMessageProperties(message); + } + + public AbstractJMSMessage getConvertedMessage() + { + return _newMessage; + } + + /** + * Sets all message properties + */ + protected void setMessageProperties(Message message) throws JMSException + { + setNonJMSProperties(message); + setJMSProperties(message); + } + + /** + * Sets all non-JMS defined properties on converted message + */ + protected void setNonJMSProperties(Message message) throws JMSException + { + Enumeration propertyNames = message.getPropertyNames(); + while (propertyNames.hasMoreElements()) + { + String propertyName = String.valueOf(propertyNames.nextElement()); + //TODO: Shouldn't need to check for JMS properties here as don't think getPropertyNames() should return them + if (!propertyName.startsWith("JMSX_")) + { + Object value = message.getObjectProperty(propertyName); + _newMessage.setObjectProperty(propertyName, value); + } + } + } + + /** + * Exposed JMS defined properties on converted message: + * JMSDestination - we don't set here + * JMSDeliveryMode - set + * JMSExpiration - we don't set here + * JMSPriority - we don't set here + * JMSMessageID - we don't set here + * JMSTimestamp - we don't set here + * JMSCorrelationID - set + * JMSReplyTo - set + * JMSType - set + * JMSRedlivered - we don't set here + */ + protected void setJMSProperties(Message message) throws JMSException + { + _newMessage.setJMSDeliveryMode(message.getJMSDeliveryMode()); + + if (message.getJMSReplyTo() != null) + { + _newMessage.setJMSReplyTo(message.getJMSReplyTo()); + } + _newMessage.setJMSType(message.getJMSType()); + + _newMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java index 17c735fd0e..027c7d7728 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactory.java @@ -23,6 +23,7 @@ package org.apache.qpid.client.message; import java.util.List; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; import javax.jms.JMSException; 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 c7a7cd892b..d16b7f6b02 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 @@ -28,10 +28,12 @@ import javax.jms.JMSException; import org.apache.qpid.AMQException; import org.apache.qpid.framing.Content; +import org.apache.qpid.framing.AMQShortString; public class MessageFactoryRegistry { - private final Map _mimeToFactoryMap = new HashMap(); + private final Map<String, MessageFactory> _mimeStringToFactoryMap = new HashMap<String, MessageFactory>(); + private final Map<AMQShortString, MessageFactory> _mimeShortStringToFactoryMap = new HashMap<AMQShortString, MessageFactory>(); public void registerFactory(String mimeType, MessageFactory mf) { @@ -39,12 +41,14 @@ public class MessageFactoryRegistry { throw new IllegalArgumentException("Message factory must not be null"); } - _mimeToFactoryMap.put(mimeType, mf); + _mimeStringToFactoryMap.put(mimeType, mf); + _mimeShortStringToFactoryMap.put(new AMQShortString(mimeType), mf); } public MessageFactory deregisterFactory(String mimeType) { - return (MessageFactory) _mimeToFactoryMap.remove(mimeType); + _mimeShortStringToFactoryMap.remove(new AMQShortString(mimeType)); + return _mimeStringToFactoryMap.remove(mimeType); } /** @@ -62,7 +66,7 @@ public class MessageFactoryRegistry MessageHeaders contentHeader, List contents) throws AMQException, JMSException { - MessageFactory mf = (MessageFactory) _mimeToFactoryMap.get(contentHeader.getContentType()); + MessageFactory mf = _mimeShortStringToFactoryMap.get(contentHeader.getContentType()); if (mf == null) { throw new AMQException("Unsupport MIME type of " + contentHeader.getContentType()); @@ -79,7 +83,7 @@ public class MessageFactoryRegistry { throw new IllegalArgumentException("Mime type must not be null"); } - MessageFactory mf = (MessageFactory) _mimeToFactoryMap.get(mimeType); + MessageFactory mf = _mimeStringToFactoryMap.get(mimeType); if (mf == null) { throw new AMQException("Unsupport MIME type of " + mimeType); @@ -100,7 +104,7 @@ public class MessageFactoryRegistry mf.registerFactory(JMSMapMessage.MIME_TYPE, new JMSMapMessageFactory()); mf.registerFactory("text/plain", new JMSTextMessageFactory()); mf.registerFactory("text/xml", new JMSTextMessageFactory()); - mf.registerFactory("application/octet-stream", new JMSBytesMessageFactory()); + mf.registerFactory(JMSBytesMessage.MIME_TYPE, new JMSBytesMessageFactory()); mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory()); mf.registerFactory(JMSStreamMessage.MIME_TYPE, new JMSStreamMessageFactory()); mf.registerFactory(null, new JMSBytesMessageFactory()); diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageHeaders.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageHeaders.java index 72e920ffd3..1ab03ee34e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageHeaders.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageHeaders.java @@ -24,6 +24,7 @@ package org.apache.qpid.client.message; import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQPInvalidClassException; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.FieldTableFactory; @@ -35,13 +36,13 @@ public class MessageHeaders { private static final Logger _logger = Logger.getLogger(MessageHeaders.class); - private String _contentType; + private AMQShortString _contentType; - private String _encoding; + private AMQShortString _encoding; - private String _destination; + private AMQShortString _destination; - private String _exchange; + private AMQShortString _exchange; private FieldTable _jmsHeaders; @@ -49,33 +50,35 @@ public class MessageHeaders private short _priority; - private String _correlationId; + private AMQShortString _correlationId; - private String _replyTo; + private AMQShortString _replyTo; private long _expiration; - private String _messageId; + private AMQShortString _messageId; private long _timestamp; - private String _type; + private AMQShortString _type; - private String _userId; + private AMQShortString _userId; - private String _appId; + private AMQShortString _appId; - private String _transactionId; + private AMQShortString _transactionId; - private String _routingKey; + private AMQShortString _routingKey; private int _size; - public int getSize() { + public int getSize() + { return _size; } - public void setSize(int size) { + public void setSize(int size) + { this._size = size; } @@ -83,29 +86,24 @@ public class MessageHeaders { } - public String getContentTypeShortString() + public AMQShortString getContentType() { return _contentType; } - public String getContentType() + public void setContentType(AMQShortString contentType) { - return _contentType == null ? null : _contentType.toString(); + _contentType = contentType; } - public void setContentType(String contentType) + public AMQShortString getEncoding() { - _contentType = contentType == null ? null : new String(contentType); + return _encoding; } - public String getEncoding() + public void setEncoding(AMQShortString encoding) { - return _encoding == null ? null : _encoding.toString(); - } - - public void setEncoding(String encoding) - { - _encoding = encoding == null ? null : new String(encoding); + _encoding = encoding; } public FieldTable getJMSHeaders() @@ -144,22 +142,22 @@ public class MessageHeaders _priority = priority; } - public String getCorrelationId() + public AMQShortString getCorrelationId() { - return _correlationId == null ? null : _correlationId.toString(); + return _correlationId; } - public void setCorrelationId(String correlationId) + public void setCorrelationId(AMQShortString correlationId) { - _correlationId = correlationId == null ? null : new String(correlationId); + _correlationId = correlationId; } - public String getReplyTo() + public AMQShortString getReplyTo() { - return _replyTo == null ? null : _replyTo.toString(); + return _replyTo; } - public void setReplyTo(String replyTo) + public void setReplyTo(AMQShortString replyTo) { _replyTo = replyTo; } @@ -175,12 +173,12 @@ public class MessageHeaders } - public String getMessageId() + public AMQShortString getMessageId() { return _messageId; } - public void setMessageId(String messageId) + public void setMessageId(AMQShortString messageId) { _messageId = messageId; } @@ -195,39 +193,39 @@ public class MessageHeaders _timestamp = timestamp; } - public String getType() + public AMQShortString getType() { - return _type == null ? null : _type.toString(); + return _type; } - public void setType(String type) + public void setType(AMQShortString type) { - _type = type == null ? null : new String(type); + _type = type; } - public String getUserId() + public AMQShortString getUserId() { - return _userId == null ? null : _userId.toString(); + return _userId; } - public void setUserId(String userId) + public void setUserId(AMQShortString userId) { - _userId = userId == null ? null : new String(userId); + _userId = userId; } - public String getAppId() + public AMQShortString getAppId() { - return _appId == null ? null : _appId.toString(); + return _appId; } - public void setAppId(String appId) + public void setAppId(AMQShortString appId) { - _appId = appId == null ? null : new String(appId); + _appId = appId; } // MapMessage Interface - public boolean getBoolean(String string) throws JMSException + public boolean getBoolean(AMQShortString string) throws JMSException { Boolean b = getJMSHeaders().getBoolean(string); @@ -237,13 +235,13 @@ public class MessageHeaders { Object str = getJMSHeaders().getObject(string); - if (str == null || !(str instanceof String)) + if (str == null || !(str instanceof AMQShortString)) { throw new MessageFormatException("getBoolean can't use " + string + " item."); } else { - return Boolean.valueOf((String) str); + return Boolean.valueOf(((AMQShortString)str).asString()); } } else @@ -255,13 +253,13 @@ public class MessageHeaders return b; } - public char getCharacter(String string) throws JMSException + public char getCharacter(AMQShortString string) throws JMSException { Character c = getJMSHeaders().getCharacter(string); if (c == null) { - if (getJMSHeaders().isNullStringValue(string)) + if (getJMSHeaders().isNullStringValue(string.asString())) { throw new NullPointerException("Cannot convert null char"); } @@ -276,7 +274,7 @@ public class MessageHeaders } } - public byte[] getBytes(String string) throws JMSException + public byte[] getBytes(AMQShortString string) throws JMSException { byte[] bs = getJMSHeaders().getBytes(string); @@ -290,7 +288,7 @@ public class MessageHeaders } } - public byte getByte(String string) throws JMSException + public byte getByte(AMQShortString string) throws JMSException { Byte b = getJMSHeaders().getByte(string); if (b == null) @@ -299,13 +297,13 @@ public class MessageHeaders { Object str = getJMSHeaders().getObject(string); - if (str == null || !(str instanceof String)) + if (str == null || !(str instanceof AMQShortString)) { throw new MessageFormatException("getByte can't use " + string + " item."); } else { - return Byte.valueOf((String) str); + return Byte.valueOf(((AMQShortString)str).asString()); } } else @@ -317,7 +315,7 @@ public class MessageHeaders return b; } - public short getShort(String string) throws JMSException + public short getShort(AMQShortString string) throws JMSException { Short s = getJMSHeaders().getShort(string); @@ -329,7 +327,7 @@ public class MessageHeaders return s; } - public int getInteger(String string) throws JMSException + public int getInteger(AMQShortString string) throws JMSException { Integer i = getJMSHeaders().getInteger(string); @@ -341,7 +339,7 @@ public class MessageHeaders return i; } - public long getLong(String string) throws JMSException + public long getLong(AMQShortString string) throws JMSException { Long l = getJMSHeaders().getLong(string); @@ -353,7 +351,7 @@ public class MessageHeaders return l; } - public float getFloat(String string) throws JMSException + public float getFloat(AMQShortString string) throws JMSException { Float f = getJMSHeaders().getFloat(string); @@ -363,13 +361,13 @@ public class MessageHeaders { Object str = getJMSHeaders().getObject(string); - if (str == null || !(str instanceof String)) + if (str == null || !(str instanceof AMQShortString)) { throw new MessageFormatException("getFloat can't use " + string + " item."); } else { - return Float.valueOf((String) str); + return Float.valueOf(((AMQShortString)str).asString()); } } else @@ -382,7 +380,7 @@ public class MessageHeaders return f; } - public double getDouble(String string) throws JMSException + public double getDouble(AMQShortString string) throws JMSException { Double d = getJMSHeaders().getDouble(string); @@ -394,9 +392,9 @@ public class MessageHeaders return d; } - public String getString(String string) throws JMSException + public AMQShortString getString(AMQShortString string) throws JMSException { - String s = getJMSHeaders().getString(string); + AMQShortString s = new AMQShortString(getJMSHeaders().getString(string.asString())); if (s == null) { @@ -415,7 +413,7 @@ public class MessageHeaders } else { - s = String.valueOf(o); + s = (AMQShortString) o; } } } @@ -424,76 +422,76 @@ public class MessageHeaders return s; } - public Object getObject(String string) throws JMSException + public Object getObject(AMQShortString string) throws JMSException { return getJMSHeaders().getObject(string); } - public void setBoolean(String string, boolean b) throws JMSException + public void setBoolean(AMQShortString string, boolean b) throws JMSException { checkPropertyName(string); getJMSHeaders().setBoolean(string, b); } - public void setChar(String string, char c) throws JMSException + public void setChar(AMQShortString string, char c) throws JMSException { checkPropertyName(string); getJMSHeaders().setChar(string, c); } - public Object setBytes(String string, byte[] bytes) + public Object setBytes(AMQShortString string, byte[] bytes) { return getJMSHeaders().setBytes(string, bytes); } - public Object setBytes(String string, byte[] bytes, int start, int length) + public Object setBytes(AMQShortString string, byte[] bytes, int start, int length) { return getJMSHeaders().setBytes(string, bytes, start, length); } - public void setByte(String string, byte b) throws JMSException + public void setByte(AMQShortString string, byte b) throws JMSException { checkPropertyName(string); getJMSHeaders().setByte(string, b); } - public void setShort(String string, short i) throws JMSException + public void setShort(AMQShortString string, short i) throws JMSException { checkPropertyName(string); getJMSHeaders().setShort(string, i); } - public void setInteger(String string, int i) throws JMSException + public void setInteger(AMQShortString string, int i) throws JMSException { checkPropertyName(string); getJMSHeaders().setInteger(string, i); } - public void setLong(String string, long l) throws JMSException + public void setLong(AMQShortString string, long l) throws JMSException { checkPropertyName(string); getJMSHeaders().setLong(string, l); } - public void setFloat(String string, float v) throws JMSException + public void setFloat(AMQShortString string, float v) throws JMSException { checkPropertyName(string); getJMSHeaders().setFloat(string, v); } - public void setDouble(String string, double v) throws JMSException + public void setDouble(AMQShortString string, double v) throws JMSException { checkPropertyName(string); getJMSHeaders().setDouble(string, v); } - public void setString(String string, String string1) throws JMSException + public void setString(AMQShortString string, AMQShortString string1) throws JMSException { checkPropertyName(string); - getJMSHeaders().setString(string, string1); + getJMSHeaders().setString(string.asString(), string1.asString()); } - public void setObject(String string, Object object) throws JMSException + public void setObject(AMQShortString string, Object object) throws JMSException { checkPropertyName(string); try @@ -506,7 +504,7 @@ public class MessageHeaders } } - public boolean itemExists(String string) throws JMSException + public boolean itemExists(AMQShortString string) throws JMSException { return getJMSHeaders().containsKey(string); } @@ -521,7 +519,7 @@ public class MessageHeaders getJMSHeaders().clear(); } - public boolean propertyExists(String propertyName) + public boolean propertyExists(AMQShortString propertyName) { return getJMSHeaders().propertyExists(propertyName); } @@ -531,7 +529,7 @@ public class MessageHeaders return getJMSHeaders().setObject(key.toString(), value); } - public Object remove(String propertyName) + public Object remove(AMQShortString propertyName) { return getJMSHeaders().remove(propertyName); } @@ -637,35 +635,43 @@ public class MessageHeaders } - public String getTransactionId() { + public AMQShortString getTransactionId() + { return _transactionId; } - public void setTransactionId(String id) { + public void setTransactionId(AMQShortString id) + { _transactionId = id; } - public String getDestination() { + public AMQShortString getDestination() + { return _destination; } - public void setDestination(String destination) { + public void setDestination(AMQShortString destination) + { this._destination = destination; } - public String getExchange() { + public AMQShortString getExchange() + { return _exchange; } - public void setExchange(String exchange) { + public void setExchange(AMQShortString exchange) + { this._exchange = exchange; } - public String getRoutingKey() { + public AMQShortString getRoutingKey() + { return _routingKey; } - public void setRoutingKey(String routingKey) { + public void setRoutingKey(AMQShortString routingKey) + { this._routingKey = routingKey; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java index ea1c3c02c8..dd3140e8d8 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/UnprocessedMessage.java @@ -24,28 +24,69 @@ import java.util.LinkedList; import java.util.List; /** - * This class contains everything needed to process a JMS message. It assembles the - * deliver body, the content header and the content body/ies. + * This class contains everything needed to process a JMS message. * * Note that the actual work of creating a JMS message for the client code's use is done * outside of the MINA dispatcher thread in order to minimise the amount of work done in * the MINA dispatcher thread. * */ -public class UnprocessedMessage { - public int bytesReceived = 0; +public class UnprocessedMessage +{ + private int bytesReceived = 0; + private int channelId; + private List<byte[]> contents = new LinkedList(); + private long deliveryTag; + private MessageHeaders messageHeaders; + + public UnprocessedMessage(int channelId, long deliveryTag, MessageHeaders messageHeaders) + { + this.channelId = channelId; + this.deliveryTag = deliveryTag; + this.messageHeaders = messageHeaders; + } + + public UnprocessedMessage(int channelId, long deliveryTag, MessageHeaders messageHeaders, byte[] content) + { + this.channelId = channelId; + this.deliveryTag = deliveryTag; + this.messageHeaders = messageHeaders; + addContent(content); + } - public List contents = new LinkedList(); - - public int channelId; - - public long deliveryTag; - - public MessageHeaders contentHeader; - - public void addContent(byte[] content) { + public void addContent(byte[] content) + { contents.add(content); - bytesReceived = bytesReceived + content.length; + bytesReceived += content.length; } + public int getBytesReceived() + { + return bytesReceived; + } + + public int getChannelId() + { + return channelId; + } + + public List<byte[]> getContents() + { + return contents; + } + + public long getDeliveryTag() + { + return deliveryTag; + } + + public MessageHeaders getMessageHeaders() + { + return messageHeaders; + } + + public String toString() + { + return "UnprocessedMessage: ch=" + channelId + "; bytesReceived=" + bytesReceived + "; deliveryTag=" + deliveryTag + "; MsgHdrs=" + messageHeaders + "Num contents=" + contents.size() + "; First content=" + new String(contents.get(0)); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java index 4d15c3cb35..c38f925b1e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java @@ -24,11 +24,15 @@ import org.apache.log4j.Logger; import org.apache.mina.common.IdleStatus; import org.apache.mina.common.IoHandlerAdapter; import org.apache.mina.common.IoSession; +import org.apache.mina.common.IoServiceConfig; import org.apache.mina.filter.SSLFilter; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.qpid.AMQConnectionClosedException; import org.apache.qpid.AMQDisconnectedException; import org.apache.qpid.AMQException; +import org.apache.qpid.AMQTimeoutException; +import org.apache.qpid.pool.ReadWriteThreadModel; +import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.failover.FailoverHandler; @@ -37,11 +41,13 @@ import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; import org.apache.qpid.codec.AMQCodecFactory; +import org.apache.qpid.framing.AMQBody; import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.AMQRequestBody; import org.apache.qpid.framing.AMQResponseBody; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionCloseOkBody; import org.apache.qpid.framing.HeartbeatBody; @@ -54,6 +60,7 @@ import java.util.Iterator; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CountDownLatch; + public class AMQProtocolHandler extends IoHandlerAdapter { private static final Logger _logger = Logger.getLogger(AMQProtocolHandler.class); @@ -95,24 +102,11 @@ public class AMQProtocolHandler extends IoHandlerAdapter private CountDownLatch _failoverLatch; + private final long DEFAULT_SYNC_TIMEOUT = 1000 * 30; + public AMQProtocolHandler(AMQConnection con) { _connection = con; - - // We add a proxy for the state manager so that we can substitute the state manager easily in this class. - // We substitute the state manager when performing failover - _frameListeners.add(new AMQMethodListener() - { - public boolean methodReceived(AMQMethodEvent evt) throws AMQException - { - return _stateManager.methodReceived(evt); - } - - public void error(Exception e) - { - _stateManager.error(e); - } - }); } public boolean isUseSSL() @@ -149,13 +143,25 @@ public class AMQProtocolHandler extends IoHandlerAdapter session.getFilterChain().addBefore("protocolFilter", "ssl", sslFilter); } + try + { + + ReadWriteThreadModel threadModel = ReadWriteThreadModel.getInstance(); + threadModel.getAsynchronousReadFilter().createNewJobForSession(session); + threadModel.getAsynchronousWriteFilter().createNewJobForSession(session); + } + catch (RuntimeException e) + { + e.printStackTrace(); + } + _protocolSession = new AMQProtocolSession(this, session, _connection, getStateManager()); _protocolSession.init(); } public void sessionOpened(IoSession session) throws Exception { - System.setProperty("foo", "bar"); + //System.setProperty("foo", "bar"); } /** @@ -286,11 +292,14 @@ public class AMQProtocolHandler extends IoHandlerAdapter public void propagateExceptionToWaiters(Exception e) { getStateManager().error(e); - final Iterator it = _frameListeners.iterator(); - while (it.hasNext()) + if (!_frameListeners.isEmpty()) { - final AMQMethodListener ml = (AMQMethodListener) it.next(); - ml.error(e); + final Iterator it = _frameListeners.iterator(); + while (it.hasNext()) + { + final AMQMethodListener ml = (AMQMethodListener) it.next(); + ml.error(e); + } } } @@ -298,59 +307,26 @@ public class AMQProtocolHandler extends IoHandlerAdapter public void messageReceived(IoSession session, Object message) throws Exception { + final boolean debug = _logger.isDebugEnabled(); + final long msgNumber = ++_messageReceivedCount; - if (_messageReceivedCount++ % 1000 == 0) + if (debug && (msgNumber % 1000 == 0)) { _logger.debug("Received " + _messageReceivedCount + " protocol messages"); } - Iterator it = _frameListeners.iterator(); - AMQFrame frame = (AMQFrame) message; - HeartbeatDiagnostics.received(frame.bodyFrame instanceof HeartbeatBody); + AMQFrame frame = (AMQFrame) message; + final AMQBody bodyFrame = frame.getBodyFrame(); - if (frame.bodyFrame instanceof AMQRequestBody) + if (bodyFrame instanceof AMQRequestBody) { - _protocolSession.messageRequestBodyReceived(frame.channel, (AMQRequestBody)frame.bodyFrame); + _protocolSession.messageRequestBodyReceived(frame.getChannel(), (AMQRequestBody)bodyFrame); } - else if (frame.bodyFrame instanceof AMQResponseBody) + else if (bodyFrame instanceof AMQResponseBody) { - _protocolSession.messageResponseBodyReceived(frame.channel, (AMQResponseBody)frame.bodyFrame); + _protocolSession.messageResponseBodyReceived(frame.getChannel(), (AMQResponseBody)bodyFrame); } -// if (frame.bodyFrame instanceof AMQMethodBody) -// { -// if (_logger.isDebugEnabled()) -// { -// _logger.debug("Method frame received: " + frame); -// } -// -// final AMQMethodEvent<AMQMethodBody> evt = new AMQMethodEvent<AMQMethodBody>(frame.channel, (AMQMethodBody) frame.bodyFrame); -// try -// { -// boolean wasAnyoneInterested = false; -// Q -// } -// catch (AMQException e) -// { -// it = _frameListeners.iterator(); -// while (it.hasNext()) -// { -// final AMQMethodListener listener = (AMQMethodListener) it.next(); -// listener.error(e); -// } -// exceptionCaught(session, e); -// } -// } -// else if (frame.bodyFrame instanceof ContentHeaderBody) -// { -// _protocolSession.messageContentHeaderReceived(frame.channel, -// (ContentHeaderBody) frame.bodyFrame); -// } -// else if (frame.bodyFrame instanceof ContentBody) -// { -// _protocolSession.messageContentBodyReceived(frame.channel, -// (ContentBody) frame.bodyFrame); -// } - else if (frame.bodyFrame instanceof HeartbeatBody) + else if (bodyFrame instanceof HeartbeatBody) { _logger.debug("Received heartbeat"); } @@ -361,27 +337,32 @@ public class AMQProtocolHandler extends IoHandlerAdapter public void messageSent(IoSession session, Object message) throws Exception { - if (_messagesOut++ % 1000 == 0) + final long sentMessages = _messagesOut++; + + final boolean debug = _logger.isDebugEnabled(); + + if (debug && (sentMessages % 1000 == 0)) { _logger.debug("Sent " + _messagesOut + " protocol messages"); } _connection.bytesSent(session.getWrittenBytes()); - if (_logger.isDebugEnabled()) + if (debug) { _logger.debug("Sent frame " + message); } } - public void addFrameListener(AMQMethodListener listener) - { - _frameListeners.add(listener); - } - - public void removeFrameListener(AMQMethodListener listener) - { - _frameListeners.remove(listener); - } + /* + public void addFrameListener(AMQMethodListener listener) + { + _frameListeners.add(listener); + } + public void removeFrameListener(AMQMethodListener listener) + { + _frameListeners.remove(listener); + } + */ public void attainState(AMQState s) throws AMQException { getStateManager().attainState(s); @@ -418,19 +399,36 @@ public class AMQProtocolHandler extends IoHandlerAdapter * a particular response. Equivalent to calling getProtocolSession().write() then * waiting for the response. * + * @param channelNum * @param methodBody - * @param listener the blocking listener. Note the calling thread will block. + * @param listener The blocking listener. Note the calling thread will block. */ private AMQMethodEvent writeCommandFrameAndWaitForReply(int channelNum, AMQMethodBody methodBody, BlockingMethodFrameListener listener) throws AMQException { + return writeCommandFrameAndWaitForReply(channelNum, methodBody, listener, DEFAULT_SYNC_TIMEOUT); + } + + /** + * Convenience method that writes a frame to the protocol session and waits for + * a particular response. Equivalent to calling getProtocolSession().write() then + * waiting for the response. + * + * @param channelNum + * @param methodBody + * @param listener The blocking listener. Note the calling thread will block. + */ + private AMQMethodEvent writeCommandFrameAndWaitForReply(int channelNum, AMQMethodBody methodBody, + BlockingMethodFrameListener listener, long timeout) + throws AMQException + { try { _frameListeners.add(listener); _protocolSession.writeRequest(channelNum, methodBody, listener); - AMQMethodEvent e = listener.blockForFrame(); + AMQMethodEvent e = listener.blockForFrame(timeout); return e; // When control resumes before this line, a reply will have been received // that matches the criteria defined in the blocking listener @@ -440,7 +438,6 @@ public class AMQProtocolHandler extends IoHandlerAdapter // If we don't remove the listener then no-one will _frameListeners.remove(listener); } - } /** @@ -484,19 +481,26 @@ public class AMQProtocolHandler extends IoHandlerAdapter { getStateManager().changeState(AMQState.CONNECTION_CLOSING); - // AMQP version change: Hardwire the version to 0-9 (major=0, minor=9) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. AMQMethodBody methodBody = ConnectionCloseBody.createMethodBody( - (byte)0, (byte)9, // AMQP version (major, minor) + _protocolSession.getProtocolMajorVersion(), // AMQP major version + _protocolSession.getProtocolMinorVersion(), // AMQP minor version 0, // classId 0, // methodId AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - "JMS client is closing the connection."); // replyText - - syncWrite(0, methodBody, ConnectionCloseOkBody.class); + new AMQShortString("JMS client is closing the connection.")); // replyText + + try + { + syncWrite(0, methodBody, ConnectionCloseOkBody.class); + _protocolSession.closeProtocolSession(); + } + catch (AMQTimeoutException e) + { + _protocolSession.closeProtocolSession(false); + } + - _protocolSession.closeProtocolSession(); } /** @@ -531,7 +535,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter } } - public String generateQueueName() + public AMQShortString generateQueueName() { return _protocolSession.generateQueueName(); } @@ -567,7 +571,7 @@ public class AMQProtocolHandler extends IoHandlerAdapter return _protocolSession; } - FailoverState getFailoverState() + public FailoverState getFailoverState() { return _failoverState; } @@ -577,8 +581,18 @@ public class AMQProtocolHandler extends IoHandlerAdapter _failoverState = failoverState; } - public int getConnectionId() + public long getConnectionId() { return _connection.getConnectionId(); } + + public byte getProtocolMajorVersion() + { + return _protocolSession.getProtocolMajorVersion(); + } + + public byte getProtocolMinorVersion() + { + return _protocolSession.getProtocolMinorVersion(); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java index de5cd4821d..77ecd1f4c0 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java @@ -37,28 +37,32 @@ import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.ConnectionTuneParameters; import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.AMQRequestBody; import org.apache.qpid.framing.AMQResponseBody; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.MainRegistry; import org.apache.qpid.framing.MessageAppendBody; import org.apache.qpid.framing.ProtocolInitiation; import org.apache.qpid.framing.ProtocolVersionList; import org.apache.qpid.framing.RequestManager; import org.apache.qpid.framing.RequestResponseMappingException; import org.apache.qpid.framing.ResponseManager; +import org.apache.qpid.framing.VersionSpecificRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.protocol.AMQProtocolWriter; +import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; /** * Wrapper for protocol session that provides type-safe access to session attributes. - * + * <p/> * The underlying protocol session is still available but clients should not * use it to obtain session attributes. */ -public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionList +public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareProtocolSession { protected static final int LAST_WRITE_FUTURE_JOIN_TIMEOUT = 1000 * 60 * 2; @@ -107,7 +111,12 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis protected int _queueId = 1; protected final Object _queueIdLock = new Object(); - protected int _ConnectionId; + protected long _ConnectionId; + + private byte _protocolMinorVersion; + private byte _protocolMajorVersion; + private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(pv[pv.length-1][PROTOCOL_MAJOR],pv[pv.length-1][PROTOCOL_MINOR]); + /** * No-arg constructor for use by test subclass - has to initialise final vars @@ -130,6 +139,8 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis _protocolHandler = protocolHandler; _minaProtocolSession = protocolSession; // properties of the connection are made available to the event handlers + _minaProtocolSession.setWriteTimeout(LAST_WRITE_FUTURE_JOIN_TIMEOUT); + //fixme - real value needed _minaProtocolSession.setAttribute(AMQ_CONNECTION, connection); _stateManager = new AMQStateManager(this); @@ -143,6 +154,7 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis { _protocolHandler = protocolHandler; _minaProtocolSession = protocolSession; + _minaProtocolSession.setAttachment(this); // properties of the connection are made available to the event handlers _minaProtocolSession.setAttribute(AMQ_CONNECTION, connection); @@ -221,8 +233,9 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis /** * Store the SASL client currently being used for the authentication handshake + * * @param client if non-null, stores this in the session. if null clears any existing client - * being stored + * being stored */ public void setSaslClient(SaslClient client) { @@ -253,6 +266,7 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis /** * This is involed from MessageTransferMethodHandler if type is CONTENT_TYPE_REFERENCE * This is invoked on the MINA dispatcher thread. + * * @param message * @throws AMQException if this was not expected */ @@ -296,13 +310,14 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis * This is involed from MessageTransferMethodHandler if type is CONTENT_TYPE_INLINE * Deliver a message to the appropriate session, removing the unprocessed message * from our map + * * @param channelId the channel id the message should be delivered to - * @param msg the message + * @param msg the message */ public void deliverMessageToAMQSession(int channelId, UnprocessedMessage msg) { AMQSession session = (AMQSession) _channelId2SessionMap.get(channelId); - msg.contentHeader.setSize(msg.bytesReceived); + msg.getMessageHeaders().setSize(msg.getBytesReceived()); session.messageReceived(msg); } @@ -360,6 +375,7 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis WriteFuture f = _minaProtocolSession.write(frame); if (wait) { + //fixme -- time out? f.join(); } else @@ -404,6 +420,7 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis /** * Starts the process of closing a session + * * @param session the AMQSession being closed */ public void closeSession(AMQSession session) @@ -425,19 +442,27 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis * This method decides whether this is a response or an initiation. The latter * case causes the AMQSession to be closed and an exception to be thrown if * appropriate. + * * @param channelId the id of the channel (session) * @return true if the client must respond to the server, i.e. if the server - * initiated the channel close, false if the channel close is just the server - * responding to the client's earlier request to close the channel. + * initiated the channel close, false if the channel close is just the server + * responding to the client's earlier request to close the channel. */ - public boolean channelClosed(int channelId, int code, String text) + public boolean channelClosed(int channelId, int code, String text) throws AMQException { final Integer chId = channelId; // if this is not a response to an earlier request to close the channel if (_closingChannels.remove(chId) == null) { final AMQSession session = (AMQSession) _channelId2SessionMap.get(chId); - session.closed(new AMQException(_logger, code, text)); + try + { + session.closed(new AMQException(_logger, code, text)); + } + catch (JMSException e) + { + throw new AMQException("JMSException received while closing session", e); + } return true; } else @@ -453,15 +478,20 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis public void closeProtocolSession() { + closeProtocolSession(true); + } + + public void closeProtocolSession(boolean waitLast) + { _logger.debug("Waiting for last write to join."); - if (_lastWriteFuture != null) + if (waitLast && _lastWriteFuture != null) { _lastWriteFuture.join(LAST_WRITE_FUTURE_JOIN_TIMEOUT); } _logger.debug("Closing protocol session"); final CloseFuture future = _minaProtocolSession.close(); - future.join(); + future.join(LAST_WRITE_FUTURE_JOIN_TIMEOUT); } public void failover(String host, int port) @@ -469,20 +499,19 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis _protocolHandler.failover(host, port); } - protected String generateQueueName() + protected AMQShortString generateQueueName() { int id; - synchronized(_queueIdLock) + synchronized (_queueIdLock) { id = _queueId++; } //get rid of / and : and ; from address for spec conformance - String localAddress = StringUtils.replaceChars(_minaProtocolSession.getLocalAddress().toString(),"/;:",""); - return "tmp_" + localAddress + "_" + id; + String localAddress = StringUtils.replaceChars(_minaProtocolSession.getLocalAddress().toString(), "/;:", ""); + return new AMQShortString("tmp_" + localAddress + "_" + id); } /** - * * @param delay delay in seconds (not ms) */ void initHeartbeats(int delay) @@ -495,11 +524,39 @@ public class AMQProtocolSession implements AMQProtocolWriter, ProtocolVersionLis } } - public void confirmConsumerCancelled(int channelId, String consumerTag) + public void confirmConsumerCancelled(int channelId, AMQShortString consumerTag) { final Integer chId = channelId; final AMQSession session = (AMQSession) _channelId2SessionMap.get(chId); session.confirmConsumerCancelled(consumerTag); } + + public void setProtocolVersion(final byte versionMajor, final byte versionMinor) + { + _protocolMajorVersion = versionMajor; + _protocolMinorVersion = versionMinor; + _registry = MainRegistry.getVersionSpecificRegistry(versionMajor, versionMinor); + } + + public byte getProtocolMinorVersion() + { + return _protocolMinorVersion; + } + + public byte getProtocolMajorVersion() + { + return _protocolMajorVersion; + } + + public boolean isProtocolVersionEqual(byte major, byte minor) + { + return _protocolMinorVersion == major && _protocolMajorVersion == minor; + } + + public VersionSpecificRegistry getRegistry() + { + return _registry; + } + } 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 c05e6faf53..ff38b96e63 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 @@ -21,10 +21,13 @@ package org.apache.qpid.client.protocol; import org.apache.qpid.AMQException; +import org.apache.qpid.AMQDisconnectedException; +import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.failover.FailoverException; public abstract class BlockingMethodFrameListener implements AMQMethodListener { @@ -52,6 +55,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener /** * This method is called by the MINA dispatching thread. Note that it could * be called before blockForFrame() has been called. + * * @param evt the frame event * @return true if the listener has dealt with this frame * @throws AMQException @@ -89,7 +93,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener /** * This method is called by the thread that wants to wait for a frame. */ - public AMQMethodEvent blockForFrame() throws AMQException + public AMQMethodEvent blockForFrame(long timeout) throws AMQException { synchronized (_lock) { @@ -97,11 +101,29 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener { try { - _lock.wait(); + if (timeout == -1) + { + _lock.wait(); + } + else + { + + _lock.wait(timeout); + if (!_ready) + { + _error = new AMQTimeoutException("Server did not respond in a timely fashion"); + _ready = true; + } + } } catch (InterruptedException e) { - // IGNORE + // IGNORE -- //fixme this isn't ideal as being interrupted isn't equivellant to sucess +// if (!_ready && timeout != -1) +// { +// _error = new AMQException("Server did not respond timely"); +// _ready = true; +// } } } } @@ -109,11 +131,16 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener { if (_error instanceof AMQException) { - throw (AMQException)_error; + throw(AMQException) _error; + } + else if (_error instanceof FailoverException) + { + // This should ensure that FailoverException is not wrapped and can be caught. + throw(FailoverException) _error; // needed to expose FailoverException. } else { - throw new AMQException("Woken up due to " + _error.getClass(), _error); // FIXME: This will wrap FailoverException and prevent it being caught. + throw new AMQException("Woken up due to " + _error.getClass(), _error); } } @@ -123,6 +150,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) diff --git a/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java b/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java index 4291cb3259..ddbea9a557 100644 --- a/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java +++ b/java/client/src/main/java/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java @@ -73,8 +73,8 @@ public class AmqPlainSaslClient implements SaslClient throw new SaslException("Error handling SASL callbacks: " + e, e); } FieldTable table = FieldTableFactory.newFieldTable(); - table.put("LOGIN", nameCallback.getName()); - table.put("PASSWORD", pwdCallback.getPassword()); + table.setString("LOGIN", nameCallback.getName()); + table.setString("PASSWORD", new String(pwdCallback.getPassword())); return table.getDataAsBytes(); } 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 5ace6dde69..e268cabf6c 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 @@ -55,11 +55,15 @@ public class AMQStateManager implements AMQMethodListener private final Map _state2HandlersMap = new HashMap(); private final CopyOnWriteArraySet _stateListeners = new CopyOnWriteArraySet(); - + + private final Object _stateLock = new Object(); + private static final long MAXIMUM_STATE_WAIT_TIME = 30000l; + public AMQStateManager() { this(null); } + public AMQStateManager(AMQProtocolSession protocolSession) { @@ -133,17 +137,11 @@ public class AMQStateManager implements AMQMethodListener public void changeState(AMQState newState) throws AMQException { _logger.debug("State changing to " + newState + " from old state " + _currentState); - final AMQState oldState = _currentState; - _currentState = newState; - synchronized (_stateListeners) + synchronized (_stateLock) { - final Iterator it = _stateListeners.iterator(); - while (it.hasNext()) - { - final StateListener l = (StateListener) it.next(); - l.stateChanged(oldState, newState); - } + _currentState = newState; + _stateLock.notifyAll(); } } @@ -161,7 +159,7 @@ public class AMQStateManager implements AMQMethodListener } } - public boolean methodReceived(AMQMethodEvent evt) throws AMQException + public <B extends AMQMethodBody> boolean methodReceived(AMQMethodEvent<B> evt) throws AMQException { StateAwareMethodListener handler = findStateTransitionHandler(_currentState, evt.getMethod()); if (handler != null) @@ -210,36 +208,35 @@ public class AMQStateManager implements AMQMethodListener } } - public void addStateListener(StateListener listener) - { - _logger.debug("Adding state listener"); - _stateListeners.add(listener); - } - - public void removeStateListener(StateListener listener) - { - _stateListeners.remove(listener); - } - public void attainState(AMQState s) throws AMQException + public void attainState(final AMQState s) throws AMQException { - boolean needToWait = false; - StateWaiter sw = null; - synchronized (_stateListeners) + synchronized(_stateLock) { - if (_currentState != s) + final long waitUntilTime = System.currentTimeMillis() + MAXIMUM_STATE_WAIT_TIME; + long waitTime = MAXIMUM_STATE_WAIT_TIME; + + while(_currentState != s && waitTime > 0) { - _logger.debug("Adding state wait to reach state " + s); - sw = new StateWaiter(s); - addStateListener(sw); - // we use a boolean since we must release the lock before starting to wait - needToWait = true; + try + { + _stateLock.wait(MAXIMUM_STATE_WAIT_TIME); + } + catch (InterruptedException e) + { + _logger.warn("Thread interrupted"); + } + if(_currentState != s) + { + waitTime = waitUntilTime - System.currentTimeMillis(); + } + } + if(_currentState != s) + { + throw new AMQException("State not achieved within permitted time. Current state " + _currentState + ", desired state: " + s); } } - if (needToWait) - { - sw.waituntilStateHasChanged(); - } + // at this point the state will have changed. } 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 18e1fdad82..b2940d73ae 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 @@ -25,7 +25,6 @@ import org.apache.qpid.AMQException; /** * Waits for a particular state to be reached. - * */ public class StateWaiter implements StateListener { @@ -38,6 +37,7 @@ public class StateWaiter implements StateListener private volatile Throwable _throwable; private final Object _monitor = new Object(); + private static final long TIME_OUT = 1000 * 60 * 2; public StateWaiter(AMQState state) { @@ -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 @@ -57,7 +57,7 @@ public class StateWaiter implements StateListener try { _logger.debug("State " + _state + " not achieved so waiting..."); - _monitor.wait(); + _monitor.wait(TIME_OUT); } catch (InterruptedException e) { @@ -82,7 +82,7 @@ public class StateWaiter implements StateListener public void stateChanged(AMQState oldState, AMQState newState) { - synchronized(_monitor) + synchronized (_monitor) { if (_logger.isDebugEnabled()) { @@ -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 d6364f45b0..5e6244d7cc 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 @@ -71,7 +71,7 @@ public class SocketTransportConnection implements ITransportConnection boolean readWriteThreading = Boolean.getBoolean("amqj.shared_read_write_pool"); if (readWriteThreading) { - cfg.setThreadModel(new ReadWriteThreadModel()); + cfg.setThreadModel(ReadWriteThreadModel.getInstance()); } SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig(); 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 e9e23aefdb..99a4c5f30d 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 @@ -70,7 +70,7 @@ public class TransportConnection IoServiceConfig config = _acceptor.getDefaultConfig(); - config.setThreadModel(new ReadWriteThreadModel()); + config.setThreadModel(ReadWriteThreadModel.getInstance()); } public static ITransportConnection getInstance() throws AMQTransportConnectionException diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java index 1fc43f3496..a2189ba248 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java @@ -49,10 +49,10 @@ public class VmPipeTransportConnection implements ITransportConnection final VmPipeConnector ioConnector = new VmPipeConnector(); final IoServiceConfig cfg = ioConnector.getDefaultConfig(); ReferenceCountingExecutorService executorService = ReferenceCountingExecutorService.getInstance(); - PoolingFilter asyncRead = new PoolingFilter(executorService, PoolingFilter.READ_EVENTS, + PoolingFilter asyncRead = PoolingFilter.createAynschReadPoolingFilter(executorService, "AsynchronousReadFilter"); cfg.getFilterChain().addFirst("AsynchronousReadFilter", asyncRead); - PoolingFilter asyncWrite = new PoolingFilter(executorService, PoolingFilter.WRITE_EVENTS, + PoolingFilter asyncWrite = PoolingFilter.createAynschWritePoolingFilter(executorService, "AsynchronousWriteFilter"); cfg.getFilterChain().addLast("AsynchronousWriteFilter", asyncWrite); 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 5497cafed4..c6d6731967 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 @@ -29,6 +29,7 @@ import org.apache.qpid.client.AMQDestination; import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.BindingURL; import org.apache.qpid.url.URLSyntaxException; +import org.apache.qpid.framing.AMQShortString; import javax.jms.ConnectionFactory; import javax.jms.Destination; @@ -63,7 +64,7 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor { String file = null; - if (environment.contains(Context.PROVIDER_URL)) + if (environment.containsKey(Context.PROVIDER_URL)) { file = (String) environment.get(Context.PROVIDER_URL); } @@ -85,7 +86,7 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor } else { - _logger.warn("No Provider URL specified."); + _logger.info("No Provider URL specified."); } } catch (IOException ioe) @@ -232,10 +233,14 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor */ protected Queue createQueue(Object value) { - if (value instanceof String) + if(value instanceof AMQShortString) + { + return new AMQQueue((AMQShortString) value); + } + else if (value instanceof String) { - return new AMQQueue((String) value); + return new AMQQueue(new AMQShortString((String) value)); } else if (value instanceof BindingURL) @@ -251,9 +256,13 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor */ protected Topic createTopic(Object value) { - if (value instanceof String) + if(value instanceof AMQShortString) + { + return new AMQTopic((AMQShortString)value); + } + else if (value instanceof String) { - return new AMQTopic((String) value); + return new AMQTopic(new AMQShortString((String) value)); } else if (value instanceof BindingURL) diff --git a/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java index 892b349cea..1db7e200bd 100644 --- a/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.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 @@ -64,15 +64,21 @@ public class BasicDeliverTest long min = Long.MAX_VALUE; long max = 0; long total = 0; - for(int i = 0; i < iterations; i++) + for (int i = 0; i < iterations; i++) { long time = decode(size, count); total += time; - if(time < min) min = time; - if(time > max) max = time; + if (time < min) + { + min = time; + } + if (time > max) + { + max = time; + } } System.out.println("Decoded " + count + " messages of " + size + - " bytes: avg=" + (total / iterations) + ", min=" + min + ", max=" + max) ; + " bytes: avg=" + (total / iterations) + ", min=" + min + ", max=" + max); } @@ -84,7 +90,7 @@ public class BasicDeliverTest data.flip(); AMQDecoder decoder = new AMQDecoder(false); long start = System.currentTimeMillis(); - for(int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { decoder.decode(session, data, decoderOutput); data.rewind(); @@ -97,15 +103,21 @@ public class BasicDeliverTest long min = Long.MAX_VALUE; long max = 0; long total = 0; - for(int i = 0; i < iterations; i++) + for (int i = 0; i < iterations; i++) { long time = encode(size, count); total += time; - if(time < min) min = time; - if(time > max) max = time; + if (time < min) + { + min = time; + } + if (time > max) + { + max = time; + } } System.out.println("Encoded " + count + " messages of " + size + - " bytes: avg=" + (total / iterations) + ", min=" + min + ", max=" + max) ; + " bytes: avg=" + (total / iterations) + ", min=" + min + ", max=" + max); } long encode(int size, int count) throws Exception @@ -114,14 +126,15 @@ public class BasicDeliverTest AMQDataBlock block = getDataBlock(size); AMQEncoder encoder = new AMQEncoder(); long start = System.currentTimeMillis(); - for(int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { encoder.encode(session, block, encoderOutput); } return System.currentTimeMillis() - start; } - private final ProtocolEncoderOutput encoderOutput = new ProtocolEncoderOutput(){ + private final ProtocolEncoderOutput encoderOutput = new ProtocolEncoderOutput() + { public void write(ByteBuffer byteBuffer) { @@ -137,7 +150,8 @@ public class BasicDeliverTest } }; - private final ProtocolDecoderOutput decoderOutput = new ProtocolDecoderOutput(){ + private final ProtocolDecoderOutput decoderOutput = new ProtocolDecoderOutput() + { public void write(Object object) { } @@ -147,7 +161,8 @@ public class BasicDeliverTest } }; - private final IoSession session = new BaseIoSession(){ + private final IoSession session = new BaseIoSession() + { protected void updateTrafficMask() { @@ -216,19 +231,16 @@ public class BasicDeliverTest { //create a frame representing message delivery AMQFrame[] frames = new AMQFrame[3]; - frames[0] = wrapBody( createBasicDeliverBody() ); - frames[1] = wrapBody( createContentHeaderBody() ); - frames[2] = wrapBody( createContentBody(size) ); + frames[0] = wrapBody(createBasicDeliverBody()); + frames[1] = wrapBody(createContentHeaderBody()); + frames[2] = wrapBody(createContentBody(size)); return new CompositeAMQDataBlock(frames); } static AMQFrame wrapBody(AMQBody body) { - AMQFrame frame = new AMQFrame(); - frame.bodyFrame = body; - frame.channel = 1; - + AMQFrame frame = new AMQFrame(1, body); return frame; } @@ -236,7 +248,7 @@ public class BasicDeliverTest { ContentBody body = new ContentBody(); body.payload = ByteBuffer.allocate(size); - for(int i = 0; i < size; i++) + for (int i = 0; i < size; i++) { body.payload.put((byte) DATA[i % DATA.length]); } @@ -254,12 +266,12 @@ public class BasicDeliverTest static BasicDeliverBody createBasicDeliverBody() { - BasicDeliverBody body = new BasicDeliverBody(); - body.consumerTag = "myConsumerTag"; - body.deliveryTag = 1; - body.exchange = "myExchange"; - body.redelivered = false; - body.routingKey = "myRoutingKey"; + BasicDeliverBody body = new BasicDeliverBody((byte) 8, (byte) 0, + BasicDeliverBody.getClazz((byte) 8, (byte) 0), + BasicDeliverBody.getMethod((byte) 8, (byte) 0), + new AMQShortString("myConsumerTag"), 1, + new AMQShortString("myExchange"), false, + new AMQShortString("myRoutingKey")); return body; } } diff --git a/java/client/src/old_test/java/org/apache/qpid/codec/Client.java b/java/client/src/old_test/java/org/apache/qpid/codec/Client.java index c0de5ab133..3886021277 100644 --- a/java/client/src/old_test/java/org/apache/qpid/codec/Client.java +++ b/java/client/src/old_test/java/org/apache/qpid/codec/Client.java @@ -106,12 +106,12 @@ public class Client extends IoHandlerAdapter private static boolean isDeliver(Object o) { - return o instanceof AMQFrame && ((AMQFrame) o).bodyFrame instanceof BasicDeliverBody; + return o instanceof AMQFrame && ((AMQFrame) o).getBodyFrame() instanceof BasicDeliverBody; } private static boolean isContent(Object o) { - return o instanceof AMQFrame && ((AMQFrame) o).bodyFrame instanceof ContentBody; + return o instanceof AMQFrame && ((AMQFrame) o).getBodyFrame() instanceof ContentBody; } public static void main(String[] argv) throws Exception diff --git a/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java b/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java index 2a7cb8be30..955f82fab5 100644 --- a/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.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,6 +20,7 @@ */ package org.apache.qpid.framing; +import junit.framework.TestCase; import org.apache.mina.common.ByteBuffer; import java.io.BufferedReader; @@ -29,8 +30,6 @@ import java.io.Reader; import java.util.Enumeration; import java.util.Properties; -import junit.framework.TestCase; - public class FieldTableTest extends TestCase { @@ -40,17 +39,17 @@ public class FieldTableTest extends TestCase String key = "String"; String value = "Hello"; - table.put(key, value); + table.setString(key, value); //Add one for the type encoding int size = EncodingUtils.encodedShortStringLength(key) + 1 + EncodingUtils.encodedLongStringLength(value); assertEquals(table.getEncodedSize(), size); - + key = "Integer"; Integer number = new Integer(60); - table.put(key, number); + table.setInteger(key, number); //Add one for the type encoding size += EncodingUtils.encodedShortStringLength(key) + 1 + 4; @@ -87,22 +86,22 @@ public class FieldTableTest extends TestCase doTestEncoding(load("FieldTableTest2.properties")); } */ - void doTestEncoding(FieldTable table) throws AMQFrameDecodingException + void doTestEncoding(FieldTable table) throws AMQFrameDecodingException, AMQProtocolVersionException { assertEquivalent(table, encodeThenDecode(table)); } public void assertEquivalent(FieldTable table1, FieldTable table2) { - for (Object o : table1.keySet()) + for (String key : table1.keys()) { - String key = (String) o; - assertEquals("Values for " + key + " did not match", table1.get(key), table2.get(key)); + + assertEquals("Values for " + key + " did not match", table1.getObject(key), table2.getObject(key)); //System.out.println("Values for " + key + " matched (" + table1.get(key) + ")"); } } - FieldTable encodeThenDecode(FieldTable table) throws AMQFrameDecodingException + FieldTable encodeThenDecode(FieldTable table) throws AMQFrameDecodingException, AMQProtocolVersionException { ContentHeaderBody header = new ContentHeaderBody(); header.classId = 6; @@ -153,11 +152,11 @@ public class FieldTableTest extends TestCase try { int ival = Integer.parseInt(value); - table.put(key, (long) ival); + table.setLong(key, (long) ival); } catch (NumberFormatException e) { - table.put(key, value); + table.setObject(key, value); } } return table; diff --git a/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java b/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java index d97fc22a35..cb5caefc1e 100644 --- a/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java +++ b/java/client/src/old_test/java/org/apache/qpid/headers/Listener.java @@ -23,7 +23,7 @@ package org.apache.qpid.headers; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.jms.Session; -import org.apache.qpid.testutil.Config; +//import org.apache.qpid.testutil.Config; import javax.jms.MessageListener; import javax.jms.Message; @@ -31,9 +31,9 @@ import javax.jms.Destination; import javax.jms.MessageProducer; import javax.jms.JMSException; -public class Listener implements MessageListener +public class Listener //implements MessageListener { - private final AMQConnection _connection; +/* private final AMQConnection _connection; private final MessageProducer _controller; private final AMQSession _session; private final MessageFactory _factory; @@ -113,5 +113,5 @@ public class Listener implements MessageListener config.setName("test_headers_exchange"); config.setOptions(argv); new Listener((AMQConnection) config.getConnection(), config.getDestination()); - } + }*/ } diff --git a/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java b/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java index 6f538d068c..a2d575fdd4 100644 --- a/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java +++ b/java/client/src/old_test/java/org/apache/qpid/headers/MessageFactory.java @@ -129,14 +129,14 @@ class MessageFactory FieldTable getConsumerBinding() { FieldTable binding = FieldTableFactory.newFieldTable(); - binding.put("SF0000", "value"); + binding.setString("SF0000", "value"); return binding; } FieldTable getControllerBinding() { FieldTable binding = FieldTableFactory.newFieldTable(); - binding.put("SCONTROL", "value"); + binding.setString("SCONTROL", "value"); return binding; } diff --git a/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java b/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java index a4ac5f670d..d9ef702c48 100644 --- a/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java +++ b/java/client/src/old_test/java/org/apache/qpid/headers/Publisher.java @@ -22,13 +22,13 @@ package org.apache.qpid.headers; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.testutil.Config; +//import org.apache.qpid.testutil.Config; import javax.jms.*; -public class Publisher implements MessageListener +public class Publisher // implements MessageListener { - private final Object _lock = new Object(); +/* private final Object _lock = new Object(); private final AMQConnection _connection; private final AMQSession _session; private final Destination _exchange; @@ -129,5 +129,5 @@ public class Publisher implements MessageListener new Publisher(config).test(msgCount, consumerCount); } - } + }*/ } diff --git a/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java b/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java index de3d558f7c..f0ac0e6902 100644 --- a/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/mina/AcceptorTest.java @@ -82,7 +82,7 @@ public class AcceptorTest extends TestCase sc.setSendBufferSize(32768); sc.setReceiveBufferSize(32768); - config.setThreadModel(new ReadWriteThreadModel()); + config.setThreadModel(ReadWriteThreadModel.getInstance()); acceptor.bind(new InetSocketAddress(PORT), new TestHandler()); diff --git a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingClient.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingClient.java deleted file mode 100644 index b060498d9b..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingClient.java +++ /dev/null @@ -1,131 +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.ping; - -import org.apache.log4j.Logger; -import org.apache.log4j.Level; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.jms.Session; - -import javax.jms.*; -import java.net.InetAddress; - -public class TestPingClient -{ - private static final Logger _logger = Logger.getLogger(TestPingClient.class); - - private static class TestPingMessageListener implements MessageListener - { - public TestPingMessageListener() - { - } - - long _lastTimestamp = 0L; - long _lastTimestampString = 0L; - - public void onMessage(javax.jms.Message message) - { - if (_logger.isInfoEnabled()) - { - long timestamp = 0L; - long timestampString = 0L; - - try - { - timestamp = message.getLongProperty("timestamp"); - timestampString = Long.parseLong(message.getStringProperty("timestampString")); - - if (timestampString != timestamp) - { - _logger.info("Timetamps differ!:\n" + - "timestamp:" + timestamp + "\n" + - "timestampString:" + timestampString); - } - - } - catch (JMSException jmse) - { - } - - long diff = timestamp - _lastTimestamp; - _lastTimestamp = timestamp; - - long stringDiff = timestampString - _lastTimestampString; - - _lastTimestampString = timestampString; - - _logger.info("Ping: T:" + diff + "ms, TS:" + stringDiff); - - // _logger.info(_name + " got message '" + message + "\n"); - } - } - } - - public static void main(String[] args) - { - _logger.setLevel(Level.INFO); - - _logger.info("Starting..."); - - if (args.length < 4) - { - System.out.println("Usage: brokerdetails username password virtual-path [selector] "); - System.exit(1); - } - try - { - InetAddress address = InetAddress.getLocalHost(); - AMQConnection con1 = new AMQConnection(args[0], args[1], args[2], - address.getHostName(), args[3]); - - final org.apache.qpid.jms.Session session1 = (org.apache.qpid.jms.Session) - con1.createSession(false, Session.AUTO_ACKNOWLEDGE); - - - String selector = null; - - if (args.length == 5) - { - selector = args[4]; - } - - _logger.info("Message selector is <" + selector + ">..."); - - Queue q = new AMQQueue("ping"); - - MessageConsumer consumer1 = session1.createConsumer(q, - 1, false, false, selector); - - consumer1.setMessageListener(new TestPingMessageListener()); - con1.start(); - } - catch (Throwable t) - { - System.err.println("Fatal error: " + t); - t.printStackTrace(); - } - - System.out.println("Waiting..."); - } -} - diff --git a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingProducer.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingProducer.java deleted file mode 100644 index 458dca0d56..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingProducer.java +++ /dev/null @@ -1,213 +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.ping; - -import org.apache.log4j.Logger; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.AMQException; -import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.client.AMQNoConsumersException; -import org.apache.qpid.client.BasicMessageProducer; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.jms.MessageProducer; -import org.apache.qpid.jms.Session; - -import javax.jms.*; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * A client that behaves as follows: - * <ul><li>Connects to a queue, whose name is specified as a cmd-line argument</li> - * <li>Creates a temporary queue</li> - * <li>Creates messages containing a property that is the name of the temporary queue</li> - * <li>Fires off a message on the original queue and waits for a response on the temporary queue</li> - * </ul> - */ -public class TestPingProducer implements ExceptionListener -{ - private static final Logger _log = Logger.getLogger(TestPingProducer.class); - - private AMQConnection _connection; - - private Session _session; - - private boolean _publish; - - private long SLEEP_TIME = 250L; - - private class CallbackHandler implements MessageListener - { - - private int _actualMessageCount; - - - public void onMessage(Message m) - { - if (_log.isDebugEnabled()) - { - _log.debug("Message received: " + m); - } - _actualMessageCount++; - if (_actualMessageCount % 1000 == 0) - { - _log.info("Received message count: " + _actualMessageCount); - } - } - } - - public TestPingProducer(boolean TRANSACTED, String brokerDetails, String clientID, - String virtualpath) throws AMQException, URLSyntaxException - { - try - { - createConnection(brokerDetails, clientID, virtualpath); - - if (TRANSACTED) - { - _session = (Session) _connection.createSession(true, Session.SESSION_TRANSACTED); - } - else - { - _session = (Session) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - } - - AMQQueue destination = new AMQQueue("ping"); - MessageProducer producer = (MessageProducer) _session.createProducer(destination); - - _connection.setExceptionListener(this); - - _connection.start(); - - int messageNumber = 0; - - while (_publish) - { -/* - TextMessage msg = _session.createTextMessage( - "Presented to in conjunction with Mahnah Mahnah and the Snowths: " + ++messageNumber); -*/ - ObjectMessage msg = _session.createObjectMessage(); - - msg.setStringProperty("timestampString", Long.toString(System.currentTimeMillis())); - msg.setLongProperty("timestamp", System.currentTimeMillis()); - - ((BasicMessageProducer) producer).send(msg, DeliveryMode.NON_PERSISTENT, true); - - - if (TRANSACTED) - { - try{ - _session.commit(); - _log.info("Message Sent.");// +"\n"+ msg); - }catch (JMSException e) - { - try - { - _session.rollback(); - } - catch (JMSException jsme) - { - _log.info(jsme); - } - - - if (e.getLinkedException() instanceof AMQNoConsumersException) - { - _log.info("No Consumers never mind."); - - continue; - } - } - } - - - if (SLEEP_TIME > 0) - { - try - { - Thread.sleep(SLEEP_TIME); - } - catch (InterruptedException ie) - { - //do nothing - } - } - - - } - - } - catch (JMSException e) - { - _publish = false; - e.printStackTrace(); - } - } - - private void createConnection(String brokerDetails, String clientID, String virtualpath) throws AMQException, URLSyntaxException - { - _publish = true; - _connection = new AMQConnection(brokerDetails, "guest", "guest", - clientID, virtualpath); - } - - /** - * @param args argument 1 if present specifies the name of the temporary queue to create. Leaving it blank - * means the server will allocate a name. - */ - public static void main(String[] args) throws URLSyntaxException - { - if (args.length == 0) - { - System.err.println("Usage: TestPingPublisher <brokerDetails> <virtual path> [transacted]"); - System.exit(0); - } - try - { - InetAddress address = InetAddress.getLocalHost(); - String clientID = address.getHostName() + System.currentTimeMillis(); - new TestPingProducer(args.length == 3, args[0], clientID, args[1]); - } - catch (UnknownHostException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - catch (AMQException e) - { - System.err.println("Error in client: " + e); - e.printStackTrace(); - } - - //System.exit(0); - } - - /** - * @see javax.jms.ExceptionListener#onException(javax.jms.JMSException) - */ - public void onException(JMSException e) - { - System.err.println(e.getMessage()); - - _publish = false; - e.printStackTrace(System.err); - } -} diff --git a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingPublisher.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingPublisher.java deleted file mode 100644 index c7742be042..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingPublisher.java +++ /dev/null @@ -1,180 +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.ping; - -import org.apache.log4j.Logger; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.AMQException; -import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.BasicMessageProducer; -import org.apache.qpid.jms.MessageProducer; -import org.apache.qpid.jms.Session; - -import javax.jms.*; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * A client that behaves as follows: - * <ul><li>Connects to a queue, whose name is specified as a cmd-line argument</li> - * <li>Creates a temporary queue</li> - * <li>Creates messages containing a property that is the name of the temporary queue</li> - * <li>Fires off a message on the original queue and waits for a response on the temporary queue</li> - * </ul> - */ -public class TestPingPublisher implements ExceptionListener -{ - private static final Logger _log = Logger.getLogger(TestPingPublisher.class); - - private AMQConnection _connection; - - private Session _session; - - private boolean _publish; - - private long SLEEP_TIME = 0L; - - private class CallbackHandler implements MessageListener - { - - private int _actualMessageCount; - - - public void onMessage(Message m) - { - if (_log.isDebugEnabled()) - { - _log.debug("Message received: " + m); - } - _actualMessageCount++; - if (_actualMessageCount % 1000 == 0) - { - _log.info("Received message count: " + _actualMessageCount); - } - } - } - - public TestPingPublisher(String brokerDetails, String clientID, String virtualpath) throws AMQException, URLSyntaxException - { - try - { - createConnection(brokerDetails, clientID, virtualpath); - - _session = (Session) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - //AMQQueue destination = new AMQQueue("ping"); - AMQTopic destination = new AMQTopic("ping"); - MessageProducer producer = (MessageProducer) _session.createProducer(destination); - - _connection.setExceptionListener(this); - - _connection.start(); - - int messageNumber = 0; - - while (_publish) - { -/* - TextMessage msg = _session.createTextMessage( - "Presented to in conjunction with Mahnah Mahnah and the Snowths: " + ++messageNumber); -*/ - ObjectMessage msg = _session.createObjectMessage(); - - Long time = System.nanoTime(); - msg.setStringProperty("timestampString", Long.toString(time)); - msg.setLongProperty("timestamp", time); - - ((BasicMessageProducer) producer).send(msg, DeliveryMode.PERSISTENT, true); - - _log.info("Message Sent:\n" + msg); - - if (SLEEP_TIME > 0) - { - try - { - Thread.sleep(SLEEP_TIME); - } - catch (InterruptedException ie) - { - //do nothing - } - } - - - } - - } - catch (JMSException e) - { - e.printStackTrace(); - } - } - - private void createConnection(String brokerDetails, String clientID, String virtualpath) throws AMQException, URLSyntaxException - { - _publish = true; - _connection = new AMQConnection(brokerDetails, "guest", "guest", - clientID, virtualpath); - - } - - /** - * @param args argument 1 if present specifies the name of the temporary queue to create. Leaving it blank - * means the server will allocate a name. - */ - public static void main(String[] args) throws URLSyntaxException - { - if (args.length == 0) - { - System.err.println("Usage: TestPingPublisher <brokerDetails> <virtual path>"); - System.exit(0); - } - try - { - InetAddress address = InetAddress.getLocalHost(); - String clientID = address.getHostName() + System.currentTimeMillis(); - new TestPingPublisher(args[0], clientID, args[1]); - } - catch (UnknownHostException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - catch (AMQException e) - { - System.err.println("Error in client: " + e); - e.printStackTrace(); - } - - //System.exit(0); - } - - /** - * @see javax.jms.ExceptionListener#onException(javax.jms.JMSException) - */ - public void onException(JMSException e) - { - System.err.println(e.getMessage()); - - _publish = false; - e.printStackTrace(System.err); - } -} diff --git a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingSubscriber.java b/java/client/src/old_test/java/org/apache/qpid/ping/TestPingSubscriber.java deleted file mode 100644 index 8e8c3f2e6e..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/ping/TestPingSubscriber.java +++ /dev/null @@ -1,132 +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.ping; - -import org.apache.log4j.Logger; -import org.apache.log4j.Level; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.jms.Session; - -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.Topic; -import javax.jms.JMSException; -import java.net.InetAddress; - -public class TestPingSubscriber -{ - private static final Logger _logger = Logger.getLogger(TestPingClient.class); - - private static class TestPingMessageListener implements MessageListener - { - public TestPingMessageListener() - { - } - - long _lastTimestamp = 0L; - long _lastTimestampString = 0L; - - public void onMessage(javax.jms.Message message) - { - Long time = System.nanoTime(); - - if (_logger.isInfoEnabled()) - { - long timestamp = 0L; - long timestampString = 0L; - - try - { - timestamp = message.getLongProperty("timestamp"); - timestampString = Long.parseLong(message.getStringProperty("timestampString")); - - if (timestampString != timestamp) - { - _logger.info("Timetamps differ!:\n" + - "timestamp:" + timestamp + "\n" + - "timestampString:" + timestampString); - } - - } - catch (JMSException jmse) - { - } - - long diff = time - timestamp; - - long stringDiff = time - timestampString; - - _logger.info("Ping: TS:" + stringDiff/1000+"us"); - - // _logger.info(_name + " got message '" + message + "\n"); - } - } - } - - public static void main(String[] args) - { - _logger.setLevel(Level.INFO); - - _logger.info("Starting..."); - - if (args.length < 4) - { - System.out.println("Usage: brokerdetails username password virtual-path [selector] "); - System.exit(1); - } - try - { - InetAddress address = InetAddress.getLocalHost(); - AMQConnection con1 = new AMQConnection(args[0], args[1], args[2], - address.getHostName(), args[3]); - - final org.apache.qpid.jms.Session session1 = (org.apache.qpid.jms.Session) - con1.createSession(false, Session.AUTO_ACKNOWLEDGE); - - - String selector = null; - - if (args.length == 5) - { - selector = args[4]; - } - - _logger.info("Message selector is <" + selector + ">..."); - - Topic t = new AMQTopic("ping"); - - MessageConsumer consumer1 = session1.createConsumer(t, - 1, false, false, selector); - - consumer1.setMessageListener(new TestPingMessageListener()); - con1.start(); - } - catch (Throwable t) - { - System.err.println("Fatal error: " + t); - t.printStackTrace(); - } - - System.out.println("Waiting..."); - } -} - diff --git a/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java b/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java deleted file mode 100644 index 7cbec7c85c..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceProvidingClient.java +++ /dev/null @@ -1,201 +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.requestreply1; - -import org.apache.log4j.Logger; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.jms.Session; -import org.apache.qpid.jms.ConnectionListener; -import org.apache.qpid.AMQException; -import org.apache.qpid.url.URLSyntaxException; - -import javax.jms.*; -import java.net.InetAddress; -import java.net.UnknownHostException; - -public class ServiceProvidingClient -{ - private static final Logger _logger = Logger.getLogger(ServiceProvidingClient.class); - - private MessageProducer _destinationProducer; - - private Destination _responseDest; - - private AMQConnection _connection; - - public ServiceProvidingClient(String brokerDetails, String username, String password, - String clientName, String virtualPath, String serviceName) - throws AMQException, JMSException, URLSyntaxException - { - _connection = new AMQConnection(brokerDetails, username, password, - clientName, virtualPath); - _connection.setConnectionListener(new ConnectionListener() - { - - public void bytesSent(long count) - { - } - - public void bytesReceived(long count) - { - } - - public boolean preFailover(boolean redirect) - { - return true; - } - - public boolean preResubscribe() - { - return true; - } - - public void failoverComplete() - { - _logger.info("App got failover complete callback"); - } - }); - final Session session = (Session) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - _logger.info("Service (queue) name is '" + serviceName + "'..."); - - AMQQueue destination = new AMQQueue(serviceName); - - MessageConsumer consumer = session.createConsumer(destination, - 100, true, false, null); - - consumer.setMessageListener(new MessageListener() - { - private int _messageCount; - - public void onMessage(Message message) - { - //_logger.info("Got message '" + message + "'"); - - TextMessage tm = (TextMessage) message; - - try - { - Destination responseDest = tm.getJMSReplyTo(); - if (responseDest == null) - { - _logger.info("Producer not created because the response destination is null."); - return; - } - - if (!responseDest.equals(_responseDest)) - { - _responseDest = responseDest; - - _logger.info("About to create a producer"); - _destinationProducer = session.createProducer(responseDest); - _destinationProducer.setDisableMessageTimestamp(true); - _destinationProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - _logger.info("After create a producer"); - } - } - catch (JMSException e) - { - _logger.error("Error creating destination"); - } - _messageCount++; - if (_messageCount % 1000 == 0) - { - _logger.info("Received message total: " + _messageCount); - _logger.info("Sending response to '" + _responseDest + "'"); - } - - try - { - String payload = "This is a response: sing together: 'Mahnah mahnah...'" + tm.getText(); - TextMessage msg = session.createTextMessage(payload); - if (tm.propertyExists("timeSent")) - { - _logger.info("timeSent property set on message"); - _logger.info("timeSent value is: " + tm.getLongProperty("timeSent")); - msg.setStringProperty("timeSent", tm.getStringProperty("timeSent")); - } - _destinationProducer.send(msg); - if (_messageCount % 1000 == 0) - { - _logger.info("Sent response to '" + _responseDest + "'"); - } - } - catch (JMSException e) - { - _logger.error("Error sending message: " + e, e); - } - } - }); - } - - public void run() throws JMSException - { - _connection.start(); - _logger.info("Waiting..."); - } - - public static void main(String[] args) - { - _logger.info("Starting..."); - - if (args.length < 5) - { - System.out.println("Usage: brokerDetails username password virtual-path serviceQueue [selector]"); - System.exit(1); - } - String clientId = null; - try - { - InetAddress address = InetAddress.getLocalHost(); - clientId = address.getHostName() + System.currentTimeMillis(); - } - catch (UnknownHostException e) - { - _logger.error("Error: " + e, e); - } - - try - { - ServiceProvidingClient client = new ServiceProvidingClient(args[0], args[1], args[2], - clientId, args[3], args[4]); - client.run(); - } - catch (JMSException e) - { - _logger.error("Error: " + e, e); - } - catch (AMQException e) - { - _logger.error("Error: " + e, e); - } - catch (URLSyntaxException e) - { - _logger.error("Error: " + e, e); - } - - - - } - -} - diff --git a/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java b/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java deleted file mode 100644 index 74becfd9bb..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/requestreply1/ServiceRequestingClient.java +++ /dev/null @@ -1,303 +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.requestreply1; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.jms.MessageConsumer; -import org.apache.qpid.jms.MessageProducer; -import org.apache.qpid.jms.Session; - -import javax.jms.*; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * A client that behaves as follows: - * <ul><li>Connects to a queue, whose name is specified as a cmd-line argument</li> - * <li>Creates a temporary queue</li> - * <li>Creates messages containing a property that is the name of the temporary queue</li> - * <li>Fires off a message on the original queue and waits for a response on the temporary queue</li> - * </ul> - * - */ -public class ServiceRequestingClient implements ExceptionListener -{ - private static final Logger _log = Logger.getLogger(ServiceRequestingClient.class); - - private static final String MESSAGE_DATA_BYTES = "jfd ghljgl hjvhlj cvhvjf ldhfsj lhfdsjf hldsjfk hdslkfj hsdflk "; - - private String MESSAGE_DATA; - - private AMQConnection _connection; - - private Session _session; - - private long _averageLatency; - - private int _messageCount; - - private volatile boolean _completed; - - private AMQDestination _tempDestination; - - private MessageProducer _producer; - - private Object _waiter; - - private static String createMessagePayload(int size) - { - _log.info("Message size set to " + size + " bytes"); - StringBuffer buf = new StringBuffer(size); - int count = 0; - while (count < size + MESSAGE_DATA_BYTES.length()) - { - buf.append(MESSAGE_DATA_BYTES); - count += MESSAGE_DATA_BYTES.length(); - } - if (count < size) - { - buf.append(MESSAGE_DATA_BYTES, 0, size - count); - } - - return buf.toString(); - } - - private class CallbackHandler implements MessageListener - { - private int _expectedMessageCount; - - private int _actualMessageCount; - - private long _startTime; - - public CallbackHandler(int expectedMessageCount, long startTime) - { - _expectedMessageCount = expectedMessageCount; - _startTime = startTime; - } - - public void onMessage(Message m) - { - if (_log.isDebugEnabled()) - { - _log.debug("Message received: " + m); - } - try - { - m.getPropertyNames(); - if (m.propertyExists("timeSent")) - { - long timeSent = Long.parseLong(m.getStringProperty("timeSent")); - long now = System.currentTimeMillis(); - if (_averageLatency == 0) - { - _averageLatency = now - timeSent; - _log.info("Latency " + _averageLatency); - } - else - { - _log.info("Individual latency: " + (now - timeSent)); - _averageLatency = (_averageLatency + (now - timeSent)) / 2; - _log.info("Average latency now: " + _averageLatency); - } - } - } - catch (JMSException e) - { - _log.error("Error getting latency data: " + e, e); - } - _actualMessageCount++; - if (_actualMessageCount % 1000 == 0) - { - _log.info("Received message count: " + _actualMessageCount); - } - - if (_actualMessageCount == _expectedMessageCount) - { - _completed = true; - notifyWaiter(); - long timeTaken = System.currentTimeMillis() - _startTime; - _log.info("Total time taken to receive " + _expectedMessageCount + " messages was " + - timeTaken + "ms, equivalent to " + - (_expectedMessageCount / (timeTaken / 1000.0)) + " messages per second"); - - try - { - _connection.close(); - _log.info("Connection closed"); - } - catch (JMSException e) - { - _log.error("Error closing connection"); - } - } - } - } - - private void notifyWaiter() - { - if (_waiter != null) - { - synchronized (_waiter) - { - _waiter.notify(); - } - } - } - public ServiceRequestingClient(String brokerHosts, String clientID, String username, String password, - String vpath, String commandQueueName, - final int messageCount, final int messageDataLength) throws AMQException, URLSyntaxException - { - _messageCount = messageCount; - MESSAGE_DATA = createMessagePayload(messageDataLength); - try - { - createConnection(brokerHosts, clientID, username, password, vpath); - _session = (Session) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - - _connection.setExceptionListener(this); - - - AMQQueue destination = new AMQQueue(commandQueueName); - _producer = (MessageProducer) _session.createProducer(destination); - _producer.setDisableMessageTimestamp(true); - _producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); - - _tempDestination = new AMQQueue("TempResponse" + - Long.toString(System.currentTimeMillis()), true); - MessageConsumer messageConsumer = (MessageConsumer) _session.createConsumer(_tempDestination, 100, true, - true, null); - - //Send first message, then wait a bit to allow the provider to get initialised - TextMessage first = _session.createTextMessage(MESSAGE_DATA); - first.setJMSReplyTo(_tempDestination); - _producer.send(first); - try - { - Thread.sleep(1000); - } - catch (InterruptedException ignore) - { - } - - //now start the clock and the test... - final long startTime = System.currentTimeMillis(); - - messageConsumer.setMessageListener(new CallbackHandler(messageCount, startTime)); - } - catch (JMSException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - - /** - * Run the test and notify an object upon receipt of all responses. - * @param waiter the object that will be notified - * @throws JMSException - */ - public void run(Object waiter) throws JMSException - { - _waiter = waiter; - _connection.start(); - for (int i = 1; i < _messageCount; i++) - { - TextMessage msg = _session.createTextMessage(MESSAGE_DATA + i); - msg.setJMSReplyTo(_tempDestination); - if (i % 1000 == 0) - { - long timeNow = System.currentTimeMillis(); - msg.setStringProperty("timeSent", String.valueOf(timeNow)); - } - _producer.send(msg); - } - _log.info("Finished sending " + _messageCount + " messages"); - } - - public boolean isCompleted() - { - return _completed; - } - - private void createConnection(String brokerHosts, String clientID, String username, String password, - String vpath) throws AMQException, URLSyntaxException - { - _connection = new AMQConnection(brokerHosts, username, password, - clientID, vpath); - } - - /** - * @param args argument 1 if present specifies the name of the temporary queue to create. Leaving it blank - * means the server will allocate a name. - */ - public static void main(String[] args) - { - if (args.length < 6) - { - System.err.println( - "Usage: ServiceRequestingClient <brokerDetails - semicolon separated host:port list> <username> <password> <vpath> <command queue name> <number of messages> <message size>"); - } - try - { - int messageDataLength = args.length > 6 ? Integer.parseInt(args[6]) : 4096; - - InetAddress address = InetAddress.getLocalHost(); - String clientID = address.getHostName() + System.currentTimeMillis(); - ServiceRequestingClient client = new ServiceRequestingClient(args[0], clientID, args[1], args[2], args[3], - args[4], Integer.parseInt(args[5]), - messageDataLength); - Object waiter = new Object(); - client.run(waiter); - synchronized (waiter) - { - while (!client.isCompleted()) - { - waiter.wait(); - } - } - - } - catch (UnknownHostException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - catch (Exception e) - { - System.err.println("Error in client: " + e); - e.printStackTrace(); - } - } - - /** - * @see javax.jms.ExceptionListener#onException(javax.jms.JMSException) - */ - public void onException(JMSException e) - { - System.err.println(e.getMessage()); - e.printStackTrace(System.err); - } -} diff --git a/java/client/src/old_test/java/org/apache/qpid/requestreply1/VmRequestReply.java b/java/client/src/old_test/java/org/apache/qpid/requestreply1/VmRequestReply.java deleted file mode 100644 index 56d1ce9b6d..0000000000 --- a/java/client/src/old_test/java/org/apache/qpid/requestreply1/VmRequestReply.java +++ /dev/null @@ -1,72 +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.requestreply1; - -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.test.VMBrokerSetup; -import org.apache.log4j.Logger; - -import junit.framework.TestCase; - -public class VmRequestReply extends TestCase -{ - private static final Logger _logger = Logger.getLogger(VmRequestReply.class); - - public void testSimpleClient() throws Exception - { - ServiceProvidingClient serviceProvider = new ServiceProvidingClient("vm://:1", "guest", "guest", - "serviceProvidingClient", "/test", - "serviceQ"); - - ServiceRequestingClient serviceRequester = new ServiceRequestingClient("vm://:1", "myClient", "guest", "guest", - "/test", "serviceQ", 5000, 512); - - serviceProvider.run(); - Object waiter = new Object(); - serviceRequester.run(waiter); - synchronized (waiter) - { - while (!serviceRequester.isCompleted()) - { - waiter.wait(); - } - } - } - - public static void main(String[] args) - { - VmRequestReply rr = new VmRequestReply(); - try - { - rr.testSimpleClient(); - } - catch (Exception e) - { - _logger.error("Error: " + e, e); - } - } - - public static junit.framework.Test suite() - { - return new VMBrokerSetup(new junit.framework.TestSuite(VmRequestReply.class)); - } -} diff --git a/java/client/src/old_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..f59b36166a 100644 --- a/java/client/src/old_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 @@ -46,7 +46,7 @@ public class TestManyConnections extends TestCase long startTime = System.currentTimeMillis(); for (int i = 0; i < count; i++) { - createConnection(i, "vm://:1", "myClient" + i, "guest", "guest", "/test"); + createConnection(i, "vm://:1", "myClient" + i, "guest", "guest", "test"); } long endTime = System.currentTimeMillis(); _log.info("Time to create " + count + " connections: " + (endTime - startTime) + diff --git a/java/client/src/old_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..9fc186f19a 100644 --- a/java/client/src/old_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 @@ -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,15 +20,12 @@ */ package org.apache.qpid.test.unit.jndi.referenceabletest; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; -import org.apache.qpid.test.VMBrokerSetup; +import junit.framework.TestCase; +//import org.apache.qpid.testutil.VMBrokerSetup; import javax.naming.NameAlreadyBoundException; import javax.naming.NoInitialContextException; -import junit.framework.TestCase; - /** * Usage: To run these you need to have the sun JNDI SPI for the FileSystem. * This can be downloaded from sun here: @@ -41,7 +38,7 @@ import junit.framework.TestCase; */ public class JNDIReferenceableTest extends TestCase { - // FIXME FSContext has been removed from repository. This needs redone with the PropertiesFileInitialContextFactory. QPID-84 +/* // FIXME FSContext has been removed from repository. This needs redone with the PropertiesFileInitialContextFactory. QPID-84 public void testReferenceable() { Bind b = null; @@ -101,4 +98,5 @@ public class JNDIReferenceableTest extends TestCase { return new VMBrokerSetup(new junit.framework.TestSuite(JNDIReferenceableTest.class)); } + */ } diff --git a/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java index a1e15258c3..2f64a1dde5 100644 --- a/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.java +++ b/java/client/src/old_test/java/org/apache/qpid/weblogic/ServiceRequestingClient.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,20 +20,13 @@ */ package org.apache.qpid.weblogic; -import org.apache.qpid.jms.*; import org.apache.log4j.Logger; -import javax.naming.NamingException; -import javax.naming.InitialContext; -import javax.naming.Context; import javax.jms.*; -import javax.jms.MessageConsumer; -import javax.jms.Session; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; import java.util.Hashtable; -import java.io.File; -import java.io.FilenameFilter; -import java.io.Reader; -import java.io.FileReader; /** * Created by IntelliJ IDEA. diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java new file mode 100644 index 0000000000..6b03dd32e8 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java @@ -0,0 +1,213 @@ +/* + * 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; + +import junit.framework.TestCase; +import org.apache.log4j.Logger; +import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; + +import javax.jms.Connection; +import javax.jms.Session; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.Message; +import javax.jms.ConnectionFactory; +import javax.naming.Context; +import javax.naming.spi.InitialContextFactory; +import java.util.Hashtable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery queue + * <p/> + * The message delivery process: + * Mina puts a message on _queue in AMQSession and the dispatcher thread take()s + * from here and dispatches to the _consumers. If the _consumer1 doesn't have a message listener set at connection start + * then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple consumers on a + * session can run in any order and a synchronous put/poll will block the dispatcher). + * <p/> + * When setting the message listener later the _synchronousQueue is just poll()'ed and the first message delivered + * the remaining messages will be left on the queue and lost, subsequent messages on the session will arrive first. + */ +public class MessageListenerMultiConsumerTest extends TestCase +{ + private static final Logger _logger = Logger.getLogger(MessageListenerMultiConsumerTest.class); + + Context _context; + + private static final int MSG_COUNT = 6; + private int receivedCount1 = 0; + private int receivedCount2 = 0; + private Connection _clientConnection; + private MessageConsumer _consumer1; + private MessageConsumer _consumer2; + + private boolean _testAsync; + private final CountDownLatch _allMessagesSent = new CountDownLatch(2); //all messages Sent Lock + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + + InitialContextFactory factory = new PropertiesFileInitialContextFactory(); + + Hashtable<String, String> env = new Hashtable<String, String>(); + + env.put("connectionfactory.connection", "amqp://client:client@MLT_ID/test?brokerlist='vm://:1'"); + env.put("queue.queue", "direct://amq.direct//MessageListenerTest"); + + _context = factory.getInitialContext(env); + + Queue queue = (Queue) _context.lookup("queue"); + + //Create Client 1 + _clientConnection = ((ConnectionFactory) _context.lookup("connection")).createConnection(); + + _clientConnection.start(); + + Session clientSession1 = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + _consumer1 = clientSession1.createConsumer(queue); + + //Create Client 2 + Session clientSession2 = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + _consumer2 = clientSession2.createConsumer(queue); + + //Create Producer + Connection producerConnection = ((ConnectionFactory) _context.lookup("connection")).createConnection(); + + producerConnection.start(); + + + Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + MessageProducer producer = producerSession.createProducer(queue); + + for (int msg = 0; msg < MSG_COUNT; msg++) + { + producer.send(producerSession.createTextMessage("Message " + msg)); + } + + producerConnection.close(); + + _testAsync = false; + } + + protected void tearDown() throws Exception + { + //Should have recieved all async messages + if (_testAsync) + { + assertEquals(MSG_COUNT, receivedCount1 + receivedCount2); + } + _clientConnection.close(); + + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + + + public void testRecieveC1thenC2() throws Exception + { + + for (int msg = 0; msg < MSG_COUNT / 2; msg++) + { + + assertTrue(_consumer1.receive() != null); + } + + for (int msg = 0; msg < MSG_COUNT / 2; msg++) + { + assertTrue(_consumer2.receive() != null); + } + } + + public void testRecieveInterleaved() throws Exception + { + + for (int msg = 0; msg < MSG_COUNT / 2; msg++) + { + assertTrue(_consumer1.receive() != null); + assertTrue(_consumer2.receive() != null); + } + } + + + public void testAsynchronousRecieve() throws Exception + { + _testAsync = true; + + _consumer1.setMessageListener(new MessageListener() + { + public void onMessage(Message message) + { + _logger.info("Client 1 Received Message(" + receivedCount1 + "):" + message); + + receivedCount1++; + + if (receivedCount1 == MSG_COUNT / 2) + { + _allMessagesSent.countDown(); + } + + } + }); + + _consumer2.setMessageListener(new MessageListener() + { + public void onMessage(Message message) + { + _logger.info("Client 2 Received Message(" + receivedCount2 + "):" + message); + + receivedCount2++; + if (receivedCount2 == MSG_COUNT / 2) + { + _allMessagesSent.countDown(); + } + } + }); + + + _logger.info("Waiting upto 2 seconds for messages"); + + try + { + _allMessagesSent.await(2000, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) + { + //do nothing + } + + } + + + public static junit.framework.Test suite() + { + return new junit.framework.TestSuite(MessageListenerMultiConsumerTest.class); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java new file mode 100644 index 0000000000..0739acfabd --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java @@ -0,0 +1,164 @@ +/* + * 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; + +import junit.framework.TestCase; +import org.apache.log4j.Logger; +import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; + +import javax.jms.Connection; +import javax.jms.Session; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.Message; +import javax.jms.ConnectionFactory; +import javax.naming.Context; +import javax.naming.spi.InitialContextFactory; +import java.util.Hashtable; + +/** + * QPID-293 Setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery queue + * <p/> + * The message delivery process: + * Mina puts a message on _queue in AMQSession and the dispatcher thread take()s + * from here and dispatches to the _consumers. If the _consumer doesn't have a message listener set at connection start + * then messages are stored on _synchronousQueue (which needs to be > 1 to pass JMS TCK as multiple consumers on a + * session can run in any order and a synchronous put/poll will block the dispatcher). + * <p/> + * When setting the message listener later the _synchronousQueue is just poll()'ed and the first message delivered + * the remaining messages will be left on the queue and lost, subsequent messages on the session will arrive first. + */ +public class MessageListenerTest extends TestCase implements MessageListener +{ + private static final Logger _logger = Logger.getLogger(MessageListenerTest.class); + + Context _context; + + private static final int MSG_COUNT = 5; + private int receivedCount = 0; + private MessageConsumer _consumer; + private Connection _clientConnection; + private boolean _testAsync; + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + + InitialContextFactory factory = new PropertiesFileInitialContextFactory(); + + Hashtable<String, String> env = new Hashtable<String, String>(); + + env.put("connectionfactory.connection", "amqp://client:client@MLT_ID/test?brokerlist='vm://:1'"); + env.put("queue.queue", "direct://amq.direct//MessageListenerTest"); + + _context = factory.getInitialContext(env); + + Queue queue = (Queue) _context.lookup("queue"); + + //Create Client + _clientConnection = ((ConnectionFactory) _context.lookup("connection")).createConnection(); + + _clientConnection.start(); + + Session clientSession = _clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + + _consumer = clientSession.createConsumer(queue); + + //Create Producer + + Connection producerConnection = ((ConnectionFactory) _context.lookup("connection")).createConnection(); + + producerConnection.start(); + + Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + MessageProducer producer = producerSession.createProducer(queue); + + for (int msg = 0; msg < MSG_COUNT; msg++) + { + producer.send(producerSession.createTextMessage("Message " + msg)); + } + + producerConnection.close(); + + _testAsync = false; + } + + protected void tearDown() throws Exception + { + //Should have recieved all async messages + if (_testAsync) + { + assertEquals(MSG_COUNT, receivedCount); + } + _clientConnection.close(); + + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + + + public void testSynchronousRecieve() throws Exception + { + + for (int msg = 0; msg < MSG_COUNT; msg++) + { + assertTrue(_consumer.receive(2000) != null); + } + } + + public void testAsynchronousRecieve() throws Exception + { + _testAsync = true; + + _consumer.setMessageListener(this); + + + _logger.info("Waiting 3 seconds for messages"); + + try + { + Thread.sleep(2000); + } + catch (InterruptedException e) + { + //do nothing + } + + } + + public void onMessage(Message message) + { + _logger.info("Received Message(" + receivedCount + "):" + message); + + receivedCount++; + } + + public static junit.framework.Test suite() + { + return new junit.framework.TestSuite(MessageListenerTest.class); + } +} diff --git a/java/client/src/test/java/org/apache/qpid/client/message/TestNonQpidTextMessage.java b/java/client/src/test/java/org/apache/qpid/client/message/TestNonQpidTextMessage.java new file mode 100644 index 0000000000..f7bea1b36a --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/client/message/TestNonQpidTextMessage.java @@ -0,0 +1,231 @@ +/* + * + * 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 javax.jms.*; +import java.util.Enumeration; +import java.io.Serializable; + +public class TestNonQpidTextMessage implements ObjectMessage { + + private JMSObjectMessage _realMessage; + private String _contentString; + + /** + * Allows us to construct a JMS message which + * does not inherit from the Qpid message superclasses + * and expand our unit testing of MessageConverter et al + */ + public TestNonQpidTextMessage() + { + _realMessage = new JMSObjectMessage(); + } + + public String getJMSMessageID() throws JMSException { + return _realMessage.getJMSMessageID(); + } + + public void setJMSMessageID(String string) throws JMSException { + _realMessage.setJMSMessageID(string); + } + + public long getJMSTimestamp() throws JMSException { + return _realMessage.getJMSTimestamp(); + } + + public void setJMSTimestamp(long l) throws JMSException { + _realMessage.setJMSTimestamp(l); + } + + public byte[] getJMSCorrelationIDAsBytes() throws JMSException { + return _realMessage.getJMSCorrelationIDAsBytes(); + } + + public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException { + _realMessage.setJMSCorrelationIDAsBytes(bytes); + } + + public void setJMSCorrelationID(String string) throws JMSException { + _realMessage.setJMSCorrelationID(string); + } + + public String getJMSCorrelationID() throws JMSException { + return _realMessage.getJMSCorrelationID(); + } + + public Destination getJMSReplyTo() throws JMSException { + return _realMessage.getJMSReplyTo(); + } + + public void setJMSReplyTo(Destination destination) throws JMSException { + _realMessage.setJMSReplyTo(destination); + } + + public Destination getJMSDestination() throws JMSException { + return _realMessage.getJMSDestination(); + } + + public void setJMSDestination(Destination destination) throws JMSException { + _realMessage.setJMSDestination(destination); + } + + public int getJMSDeliveryMode() throws JMSException { + return _realMessage.getJMSDeliveryMode(); + } + + public void setJMSDeliveryMode(int i) throws JMSException { + _realMessage.setJMSDeliveryMode(i); + } + + public boolean getJMSRedelivered() throws JMSException { + return _realMessage.getJMSRedelivered(); + } + + public void setJMSRedelivered(boolean b) throws JMSException { + _realMessage.setJMSRedelivered(b); + } + + public String getJMSType() throws JMSException { + return _realMessage.getJMSType(); + } + + public void setJMSType(String string) throws JMSException { + _realMessage.setJMSType(string); + } + + public long getJMSExpiration() throws JMSException { + return _realMessage.getJMSExpiration(); + } + + public void setJMSExpiration(long l) throws JMSException { + _realMessage.setJMSExpiration(l); + } + + public int getJMSPriority() throws JMSException { + return _realMessage.getJMSPriority(); + } + + public void setJMSPriority(int i) throws JMSException { + _realMessage.setJMSPriority(i); + } + + public void clearProperties() throws JMSException { + _realMessage.clearProperties(); + } + + public boolean propertyExists(String string) throws JMSException { + return _realMessage.propertyExists(string); + } + + public boolean getBooleanProperty(String string) throws JMSException { + return _realMessage.getBooleanProperty(string); + } + + public byte getByteProperty(String string) throws JMSException { + return _realMessage.getByteProperty(string); + } + + public short getShortProperty(String string) throws JMSException { + return _realMessage.getShortProperty(string); + } + + public int getIntProperty(String string) throws JMSException { + return _realMessage.getIntProperty(string); + } + + public long getLongProperty(String string) throws JMSException { + return _realMessage.getLongProperty(string); + } + + public float getFloatProperty(String string) throws JMSException { + return _realMessage.getFloatProperty(string); + } + + public double getDoubleProperty(String string) throws JMSException { + return _realMessage.getDoubleProperty(string); + } + + public String getStringProperty(String string) throws JMSException { + return _realMessage.getStringProperty(string); + } + + public Object getObjectProperty(String string) throws JMSException { + return _realMessage.getObjectProperty(string); + } + + public Enumeration getPropertyNames() throws JMSException { + return _realMessage.getPropertyNames(); + } + + public void setBooleanProperty(String string, boolean b) throws JMSException { + _realMessage.setBooleanProperty(string,b); + } + + public void setByteProperty(String string, byte b) throws JMSException { + _realMessage.setByteProperty(string,b); + } + + public void setShortProperty(String string, short i) throws JMSException { + _realMessage.setShortProperty(string,i); + } + + public void setIntProperty(String string, int i) throws JMSException { + _realMessage.setIntProperty(string,i); + } + + public void setLongProperty(String string, long l) throws JMSException { + _realMessage.setLongProperty(string,l); + } + + public void setFloatProperty(String string, float v) throws JMSException { + _realMessage.setFloatProperty(string,v); + } + + public void setDoubleProperty(String string, double v) throws JMSException { + _realMessage.setDoubleProperty(string,v); + } + + public void setStringProperty(String string, String string1) throws JMSException { + _realMessage.setStringProperty(string,string1); + } + + public void setObjectProperty(String string, Object object) throws JMSException { + _realMessage.setObjectProperty(string,object); + } + + public void acknowledge() throws JMSException { + _realMessage.acknowledge(); + } + + public void clearBody() throws JMSException { + _realMessage.clearBody(); + } + + public void setObject(Serializable serializable) throws JMSException { + if (serializable instanceof String) + { + _contentString = (String)serializable; + } + } + + public Serializable getObject() throws JMSException { + return _contentString; } +} 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 d12ab01bdc..4a8c0145c4 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 @@ -25,37 +25,46 @@ import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.exchange.ExchangeDefaults; import javax.jms.*; +import java.util.concurrent.atomic.AtomicInteger; public class RecoverTest extends TestCase { private static final Logger _logger = Logger.getLogger(RecoverTest.class); + private Exception _error; + private AtomicInteger count; + protected void setUp() throws Exception { super.setUp(); TransportConnection.createVMBroker(1); + _error = null; + count = new AtomicInteger(); } protected void tearDown() throws Exception { super.tearDown(); TransportConnection.killAllVMBrokers(); + count = null; } public void testRecoverResendsMsgs() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + 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); + Queue queue = new AMQQueue(new AMQShortString("someQ"), new AMQShortString("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"); + ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS); - Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test"); Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(queue); @@ -104,15 +113,15 @@ public class RecoverTest extends TestCase public void testRecoverResendsMsgsAckOnEarlier() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + 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); + Queue queue = new AMQQueue(new AMQShortString("someQ"), new AMQShortString("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"); + ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS); - Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test"); Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(queue); @@ -168,15 +177,15 @@ public class RecoverTest extends TestCase public void testAcknowledgePerConsumer() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "test"); Session consumerSession = con.createSession(false, Session.CLIENT_ACKNOWLEDGE); - Queue queue = new AMQQueue("Q1", "Q1", false, true); - Queue queue2 = new AMQQueue("Q2", "Q2", false, true); + Queue queue = new AMQQueue(new AMQShortString("Q1"), new AMQShortString("Q1"), false, true); + Queue queue2 = new AMQQueue(new AMQShortString("Q2"), new AMQShortString("Q2"), false, true); MessageConsumer consumer = consumerSession.createConsumer(queue); MessageConsumer consumer2 = consumerSession.createConsumer(queue2); - Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test"); Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(queue); MessageProducer producer2 = producerSession.createProducer(queue2); @@ -207,41 +216,96 @@ public class RecoverTest extends TestCase public void testRecoverInAutoAckListener() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "test"); final Session consumerSession = con.createSession(false, Session.AUTO_ACKNOWLEDGE); - Queue queue = new AMQQueue("Q1", "Q1", false, true); + Queue queue = new AMQQueue(new AMQShortString("Q3"), new AMQShortString("Q3"), false, true); + MessageConsumer consumer = consumerSession.createConsumer(queue); MessageProducer producer = consumerSession.createProducer(queue); producer.send(consumerSession.createTextMessage("hello")); - MessageConsumer consumer = consumerSession.createConsumer(queue); + + + final Object lock = new Object(); + consumer.setMessageListener(new MessageListener() { - private int count = 0; + + public void onMessage(Message message) { try { - if (count++ == 0) + count.incrementAndGet(); + if (count.get() == 1) { - assertFalse(message.getJMSRedelivered()); + if(message.getJMSRedelivered()) + { + setError(new Exception("Message marked as redilvered on what should be first delivery attempt")); + } consumerSession.recover(); } - else if (count++ == 1) + else if (count.get() == 2) { - assertTrue(message.getJMSRedelivered()); + if(!message.getJMSRedelivered()) + { + setError(new Exception("Message not marked as redilvered on what should be second delivery attempt")); + } } else { - fail("Message delivered too many times!"); + System.err.println(message); + fail("Message delivered too many times!: " + count); } } catch (JMSException e) { _logger.error("Error recovering session: " + e, e); + setError(e); + } + synchronized(lock) + { + lock.notify(); } } }); + + con.start(); + + long waitTime = 300000L; + long waitUntilTime = System.currentTimeMillis() + waitTime; + + synchronized(lock) + { + while((count.get() <= 1) && (waitTime > 0)) + { + lock.wait(waitTime); + if(count.get() <= 1) + { + waitTime = waitUntilTime - System.currentTimeMillis(); + } + } + } + + Thread.sleep(1000); + + if(count.get() != 2) + { + System.err.println("Count != 2 : " + count); + } + assertTrue(count.get() == 2); + + con.close(); + + if(_error != null) + { + throw _error; + } + } + + private void setError(Exception e) + { + _error = e; } public static junit.framework.Test suite() 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 59be38f0dd..cf5b5c76e5 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 @@ -48,7 +48,7 @@ public class BytesMessageTest extends TestCase implements MessageListener protected void setUp() throws Exception { super.setUp(); - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } protected void tearDown() throws Exception diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java index ad180e3a89..fb347053c7 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/FieldTableKeyEnumeratorTest.java @@ -35,16 +35,20 @@ import junit.framework.TestCase; public class FieldTableKeyEnumeratorTest extends TestCase { + public void testTrue() + { + + } public void testKeyEnumeration() { FieldTable result = FieldTableFactory.newFieldTable(); - result.put("one", 1L); - result.put("two", 2L); - result.put("three", 3L); - result.put("four", 4L); - result.put("five", 5L); + result.setObject("one", 1L); + result.setObject("two", 2L); + result.setObject("three", 3L); + result.setObject("four", 4L); + result.setObject("five", 5L); - Iterator iterator = result.keySet().iterator(); + Iterator iterator = result.keys().iterator(); try { 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 f4efd64dbb..d1e90e7bcd 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 @@ -54,7 +54,7 @@ public class FieldTableMessageTest extends TestCase implements MessageListener protected void setUp() throws Exception { super.setUp(); - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } protected void tearDown() throws Exception @@ -85,11 +85,11 @@ public class FieldTableMessageTest extends TestCase implements MessageListener private FieldTable load() throws IOException { FieldTable result = FieldTableFactory.newFieldTable(); - result.put("one", 1L); - result.put("two", 2L); - result.put("three", 3L); - result.put("four", 4L); - result.put("five", 5L); + result.setLong("one", 1L); + result.setLong("two", 2L); + result.setLong("three", 3L); + result.setLong("four", 4L); + result.setLong("five", 5L); return result; } @@ -133,10 +133,9 @@ public class FieldTableMessageTest extends TestCase implements MessageListener { ByteBuffer buffer = ((JMSBytesMessage) m).getData(); FieldTable actual = FieldTableFactory.newFieldTable(buffer, buffer.remaining()); - for (Object o : _expected.keySet()) - { - String key = (String) o; - assertEquals("Values for " + key + " did not match", _expected.get(key), actual.get(key)); + for (String key : _expected.keys()) + { + assertEquals("Values for " + key + " did not match", _expected.getObject(key), actual.getObject(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 bc2def1c64..29770704c5 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 @@ -56,7 +56,7 @@ public class MapMessageTest extends TestCase implements MessageListener try { TransportConnection.createVMBroker(1); - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } catch (Exception e) { @@ -144,13 +144,29 @@ public class MapMessageTest extends TestCase implements MessageListener } - void waitFor(int count) throws InterruptedException + void waitFor(int count) throws Exception { + long waitTime = 30000L; + long waitUntilTime = System.currentTimeMillis() + 30000L; + + synchronized(received) { - while (received.size() < count) + while(received.size() < count && waitTime>0) + { + if (received.size() < count) + { + received.wait(waitTime); + } + + if (received.size() < count) + { + waitTime = waitUntilTime - System.currentTimeMillis(); + } + } + if (received.size() < count) { - received.wait(); + throw new Exception("Timed-out. Waiting for " + count + " only got " + received.size()); } } } 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 1e9de221d4..66d82a991e 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 @@ -41,7 +41,7 @@ public class MultipleConnectionTest extends TestCase Receiver(String broker, AMQDestination dest, int sessions) throws Exception { - this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test_path"), dest, sessions); + this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "test"), dest, sessions); } Receiver(AMQConnection connection, AMQDestination dest, int sessions) throws Exception @@ -72,7 +72,7 @@ public class MultipleConnectionTest extends TestCase Publisher(String broker, AMQDestination dest) throws Exception { - this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test_path"), dest); + this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "test"), dest); } Publisher(AMQConnection connection, AMQDestination dest) throws Exception 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 3f726ae5ab..dc1aadaa6c 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 @@ -50,7 +50,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener TransportConnection.createVMBroker(1); try { - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } catch (Exception e) { 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 17679788bd..d0126e1917 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 @@ -29,12 +29,7 @@ import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.message.JMSTextMessage; import org.apache.qpid.testutil.VMBrokerSetup; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; +import javax.jms.*; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -58,7 +53,7 @@ public class PropertyValueTest extends TestCase implements MessageListener super.setUp(); try { - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } catch (Exception e) { @@ -81,7 +76,7 @@ public class PropertyValueTest extends TestCase implements MessageListener { _connection = connection; _destination = destination; - _session = (AMQSession) connection.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); + _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //set up a slow consumer _session.createConsumer(destination).setMessageListener(this); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionRefTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionRefTest.java new file mode 100644 index 0000000000..c54ea8c6e6 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/PubSubTwoConnectionRefTest.java @@ -0,0 +1,81 @@ +/* + * + * 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 org.apache.qpid.client.BasicMessageProducer; + +import javax.jms.*; + +/** + * @author Apache Software Foundation + */ +public class PubSubTwoConnectionRefTest 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 + { + AMQTopic topic = new AMQTopic("MyTopic"); + AMQConnection con1 = new AMQConnection("vm://:1", "guest", "guest", "Client1", "test"); + AMQSession session1 = con1.createAMQSession(false, AMQSession.NO_ACKNOWLEDGE); + BasicMessageProducer producer = session1.createBasicProducer(topic); + + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "Client2", "test"); + Session session2 = con2.createSession(false, AMQSession.NO_ACKNOWLEDGE); + MessageConsumer consumer = session2.createConsumer(topic); + con2.start(); + producer.sendRef(session1.createTextMessage("Hello ref")); +// producer.sendRef(session1.createTextMessage("Goodbye ref")); + TextMessage tm1 = (TextMessage) consumer.receive(2000); + assertNotNull(tm1); + assertEquals("Hello ref", tm1.getText()); +// assertEquals("Goodbye ref", tm1.getText()); + } + + public static void main(String[] args){ + PubSubTwoConnectionRefTest test = new PubSubTwoConnectionRefTest(); + try { + test.setUp(); + test.testTwoConnections(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} 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 index b853963c96..937944e340 100644 --- 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 @@ -51,11 +51,11 @@ public class PubSubTwoConnectionTest extends TestCase public void testTwoConnections() throws Exception { Topic topic = new AMQTopic("MyTopic"); - Connection con1 = new AMQConnection("vm://:1", "guest", "guest", "Client1", "/test_path"); + Connection con1 = new AMQConnection("vm://:1", "guest", "guest", "Client1", "test"); Session session1 = con1.createSession(false, AMQSession.NO_ACKNOWLEDGE); MessageProducer producer = session1.createProducer(topic); - Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "Client2", "/test_path"); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "Client2", "test"); Session session2 = con2.createSession(false, AMQSession.NO_ACKNOWLEDGE); MessageConsumer consumer = session2.createConsumer(topic); con2.start(); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java index 302551b05c..1db62cffa9 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/basic/ReceiveTest.java @@ -48,7 +48,7 @@ public class ReceiveTest extends TestCase { createVMBroker(); String broker = _connectionString; - init(new AMQConnection(broker, "guest", "guest", "ReceiveTestClient", "/test_path")); + init(new AMQConnection(broker, "guest", "guest", "ReceiveTestClient", "test")); } } 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 27a2ccb32e..fe15e151a3 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 @@ -51,7 +51,7 @@ public class SelectorTest extends TestCase implements MessageListener { super.setUp(); TransportConnection.createVMBroker(1); - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } protected void tearDown() throws Exception 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 726c7e39d7..cce02accd8 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 @@ -43,7 +43,7 @@ public class SessionStartTest extends TestCase implements MessageListener protected void setUp() throws Exception { super.setUp(); - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } protected void tearDown() throws Exception 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 903f6a9da9..b50cd39780 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 @@ -52,7 +52,7 @@ public class TextMessageTest extends TestCase implements MessageListener super.setUp(); try { - init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path")); + init(new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test")); } catch (Exception e) { @@ -75,7 +75,7 @@ public class TextMessageTest extends TestCase implements MessageListener { _connection = connection; _destination = destination; - _session = (AMQSession) connection.createSession(false, AMQSession.AUTO_ACKNOWLEDGE); + _session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //set up a slow consumer _session.createConsumer(destination).setMessageListener(this); 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 68bdc6ddf2..db4e18a4a1 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 @@ -24,7 +24,7 @@ import org.apache.qpid.client.AMQTopic; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.testutil.VMBrokerSetup; +import org.apache.qpid.client.transport.TransportConnection; import javax.jms.*; @@ -41,13 +41,15 @@ public class AMQConnectionTest extends TestCase protected void setUp() throws Exception { super.setUp(); - _connection = new AMQConnection("vm://:1", "guest", "guest", "fred", "/test"); + TransportConnection.createVMBroker(1); + _connection = new AMQConnection("vm://:1", "guest", "guest", "fred", "test"); _topic = new AMQTopic("mytopic"); _queue = new AMQQueue("myqueue"); } protected void tearDown() throws Exception { + super.tearDown(); try { _connection.close(); @@ -55,8 +57,8 @@ public class AMQConnectionTest extends TestCase catch (JMSException e) { //ignore - } - super.tearDown(); + } + TransportConnection.killAllVMBrokers(); } /** @@ -195,6 +197,6 @@ public class AMQConnectionTest extends TestCase public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(AMQConnectionTest.class)); + return new junit.framework.TestSuite(AMQConnectionTest.class); } } 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 67c4f1dd6b..b01a129bf2 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 @@ -46,7 +46,7 @@ public class AMQSessionTest extends TestCase protected void setUp() throws Exception { super.setUp(); - _connection = new AMQConnection("vm://:1", "guest", "guest", "fred", "/test"); + _connection = new AMQConnection("vm://:1", "guest", "guest", "fred", "test"); _topic = new AMQTopic("mytopic"); _queue = new AMQQueue("myqueue"); _session = (AMQSession) _connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); 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 ac789eb915..05d83be47f 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 @@ -20,17 +20,17 @@ */ package org.apache.qpid.test.unit.client.channelclose; +import junit.framework.TestCase; +import junit.textui.TestRunner; +import org.apache.log4j.Logger; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.testutil.VMBrokerSetup; -import org.apache.log4j.Logger; +import org.apache.qpid.client.transport.TransportConnection; import javax.jms.*; import java.util.ArrayList; import java.util.List; -import junit.framework.TestCase; -import junit.textui.TestRunner; /** * Due to bizarre exception handling all sessions are closed if you get @@ -64,7 +64,8 @@ public class ChannelCloseOkTest extends TestCase { super.setUp(); - _connection = new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "/test_path"); + TransportConnection.createVMBroker(1); + _connection = new AMQConnection(_connectionString, "guest", "guest", randomize("Client"), "test"); _destination1 = new AMQQueue("q1", true); _destination2 = new AMQQueue("q2", true); @@ -192,7 +193,15 @@ public class ChannelCloseOkTest extends TestCase { while (received.size() < count) { - received.wait(); + try + { + received.wait(); + } + catch (InterruptedException e) + { + _log.info("Interrupted: " + e); + throw e; + } } } } @@ -209,6 +218,6 @@ public class ChannelCloseOkTest extends TestCase public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(ChannelCloseOkTest.class)); + return new junit.framework.TestSuite(ChannelCloseOkTest.class); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java index 0b3ed931f8..7a665daeb3 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java @@ -49,7 +49,7 @@ public class CloseWithBlockingReceiveTest extends TestCase public void testReceiveReturnsNull() throws Exception { final Connection connection = new AMQConnection("vm://:1", "guest", "guest", - "fred", "/test"); + "fred", "test"); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer consumer = session.createConsumer(new AMQTopic("banana")); connection.start(); 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 c7fc3efc87..2ee9fad5d4 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 @@ -26,6 +26,7 @@ import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.AMQException; import org.apache.qpid.AMQConnectionFailureException; import org.apache.qpid.AMQUnresolvedAddressException; +import org.apache.qpid.AMQConnectionFailureException; import javax.jms.Connection; @@ -47,14 +48,15 @@ public class ConnectionTest extends TestCase protected void tearDown() throws Exception { - TransportConnection.killAllVMBrokers(); + TransportConnection.killVMBroker(1); } public void testSimpleConnection() { try { - new AMQConnection(_broker, "guest", "guest", "fred", "/test"); + AMQConnection conn = new AMQConnection(_broker, "guest", "guest", "fred", "test"); + conn.close(); } catch (Exception e) { @@ -93,6 +95,7 @@ public class ConnectionTest extends TestCase fail("Correct exception not thrown. Excpected 'AMQConnectionFailureException' got: " + amqe); } } + } public void testUnresolvedHostFailure() throws Exception @@ -114,7 +117,7 @@ public class ConnectionTest extends TestCase public void testClientIdCannotBeChanged() throws Exception { Connection connection = new AMQConnection(_broker, "guest", "guest", - "fred", "/test"); + "fred", "test"); try { connection.setClientID("someClientId"); @@ -129,7 +132,7 @@ public class ConnectionTest extends TestCase public void testClientIdIsPopulatedAutomatically() throws Exception { Connection connection = new AMQConnection(_broker, "guest", "guest", - null, "/test"); + null, "test"); assertNotNull(connection.getClientID()); } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java index 147d2ae43e..a23c78822f 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java @@ -33,14 +33,14 @@ public class ConnectionURLTest extends TestCase public void testFailoverURL() throws URLSyntaxException { - String url = "amqp://ritchiem:bob@/temp?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'"; + String url = "amqp://ritchiem:bob@/test?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod().equals("roundrobin")); assertTrue(connectionurl.getUsername().equals("ritchiem")); assertTrue(connectionurl.getPassword().equals("bob")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 2); @@ -60,14 +60,14 @@ public class ConnectionURLTest extends TestCase public void testSingleTransportUsernamePasswordURL() throws URLSyntaxException { - String url = "amqp://ritchiem:bob@/temp?brokerlist='tcp://localhost:5672'"; + String url = "amqp://ritchiem:bob@/test?brokerlist='tcp://localhost:5672'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("ritchiem")); assertTrue(connectionurl.getPassword().equals("bob")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 1); @@ -80,14 +80,14 @@ public class ConnectionURLTest extends TestCase public void testSingleTransportUsernameBlankPasswordURL() throws URLSyntaxException { - String url = "amqp://ritchiem:@/temp?brokerlist='tcp://localhost:5672'"; + String url = "amqp://ritchiem:@/test?brokerlist='tcp://localhost:5672'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("ritchiem")); assertTrue(connectionurl.getPassword().equals("")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 1); @@ -100,7 +100,7 @@ public class ConnectionURLTest extends TestCase public void testFailedURLNullPassword() { - String url = "amqp://ritchiem@/temp?brokerlist='tcp://localhost:5672'"; + String url = "amqp://ritchiem@/test?brokerlist='tcp://localhost:5672'"; try { @@ -140,7 +140,7 @@ public class ConnectionURLTest extends TestCase public void testSingleTransportWithClientURLURL() throws URLSyntaxException { - String url = "amqp://guest:guest@clientname/temp?brokerlist='tcp://localhost:5672'"; + String url = "amqp://guest:guest@clientname/test?brokerlist='tcp://localhost:5672'"; ConnectionURL connectionurl = new AMQConnectionURL(url); @@ -148,7 +148,7 @@ public class ConnectionURLTest extends TestCase assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("guest")); assertTrue(connectionurl.getPassword().equals("guest")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getClientName().equals("clientname")); @@ -164,14 +164,14 @@ public class ConnectionURLTest extends TestCase public void testSingleTransport1OptionURL() throws URLSyntaxException { - String url = "amqp://guest:guest@/temp?brokerlist='tcp://localhost:5672',routingkey='jim'"; + String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672',routingkey='jim'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("guest")); assertTrue(connectionurl.getPassword().equals("guest")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 1); @@ -187,14 +187,14 @@ public class ConnectionURLTest extends TestCase public void testSingleTransportDefaultedBroker() throws URLSyntaxException { - String url = "amqp://guest:guest@/temp?brokerlist='localhost'"; + String url = "amqp://guest:guest@/test?brokerlist='localhost'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("guest")); assertTrue(connectionurl.getPassword().equals("guest")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 1); @@ -207,17 +207,83 @@ public class ConnectionURLTest extends TestCase assertTrue(service.getPort() == 5672); } + public void testSingleTransportDefaultedBrokerWithPort() throws URLSyntaxException + { + String url = "amqp://guest:guest@/test?brokerlist='localhost:1234'"; + + ConnectionURL connectionurl = new AMQConnectionURL(url); + + assertTrue(connectionurl.getFailoverMethod() == null); + assertTrue(connectionurl.getUsername().equals("guest")); + assertTrue(connectionurl.getPassword().equals("guest")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); + + + assertTrue(connectionurl.getBrokerCount() == 1); + + BrokerDetails service = connectionurl.getBrokerDetails(0); + + assertTrue(service.getTransport().equals("tcp")); + + assertTrue(service.getHost().equals("localhost")); + assertTrue(service.getPort() == 1234); + } + + public void testSingleTransportDefaultedBrokerWithIP() throws URLSyntaxException + { + String url = "amqp://guest:guest@/test?brokerlist='127.0.0.1'"; + + ConnectionURL connectionurl = new AMQConnectionURL(url); + + assertTrue(connectionurl.getFailoverMethod() == null); + assertTrue(connectionurl.getUsername().equals("guest")); + assertTrue(connectionurl.getPassword().equals("guest")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); + + + assertTrue(connectionurl.getBrokerCount() == 1); + + BrokerDetails service = connectionurl.getBrokerDetails(0); + + assertTrue(service.getTransport().equals("tcp")); + + assertTrue(service.getHost().equals("127.0.0.1")); + assertTrue(service.getPort() == 5672); + } + + public void testSingleTransportDefaultedBrokerWithIPandPort() throws URLSyntaxException + { + String url = "amqp://guest:guest@/test?brokerlist='127.0.0.1:1234'"; + +// ConnectionURL connectionurl = new AMQConnectionURL(url); +// +// assertTrue(connectionurl.getFailoverMethod() == null); +// assertTrue(connectionurl.getUsername().equals("guest")); +// assertTrue(connectionurl.getPassword().equals("guest")); +// assertTrue(connectionurl.getVirtualHost().equals("/temp")); +// +// +// assertTrue(connectionurl.getBrokerCount() == 1); +// +// BrokerDetails service = connectionurl.getBrokerDetails(0); +// +// assertTrue(service.getTransport().equals("tcp")); +// +// assertTrue(service.getHost().equals("127.0.0.1")); +// assertTrue(service.getPort() == 1234); + } + public void testSingleTransportMultiOptionURL() throws URLSyntaxException { - String url = "amqp://guest:guest@/temp?brokerlist='tcp://localhost:5672',routingkey='jim',timeout='200',immediatedelivery='true'"; + String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672',routingkey='jim',timeout='200',immediatedelivery='true'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("guest")); assertTrue(connectionurl.getPassword().equals("guest")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 1); @@ -235,14 +301,14 @@ public class ConnectionURLTest extends TestCase public void testSinglevmURL() throws URLSyntaxException { - String url = "amqp://guest:guest@/messages?brokerlist='vm://:2'"; + String url = "amqp://guest:guest@/test?brokerlist='vm://:2'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod() == null); assertTrue(connectionurl.getUsername().equals("guest")); assertTrue(connectionurl.getPassword().equals("guest")); - assertTrue(connectionurl.getVirtualHost().equals("/messages")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 1); @@ -256,14 +322,14 @@ public class ConnectionURLTest extends TestCase public void testFailoverVMURL() throws URLSyntaxException { - String url = "amqp://ritchiem:bob@/temp?brokerlist='vm://:2;vm://:3',failover='roundrobin'"; + String url = "amqp://ritchiem:bob@/test?brokerlist='vm://:2;vm://:3',failover='roundrobin'"; ConnectionURL connectionurl = new AMQConnectionURL(url); assertTrue(connectionurl.getFailoverMethod().equals("roundrobin")); assertTrue(connectionurl.getUsername().equals("ritchiem")); assertTrue(connectionurl.getPassword().equals("bob")); - assertTrue(connectionurl.getVirtualHost().equals("/temp")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); assertTrue(connectionurl.getBrokerCount() == 2); @@ -309,7 +375,6 @@ public class ConnectionURLTest extends TestCase } - public void testWrongOptionSeparatorInOptions() { String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'+failover='roundrobin'"; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java index 6c2c684362..db0d3e0eab 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Client.java @@ -65,29 +65,35 @@ public class Client implements MessageListener _connection.close(); } - public void onMessage(Message response) + public synchronized void onMessage(Message response) { + System.out.println("Received " + (++_count) + " of " + _expected + " responses."); if(_count == _expected) { - synchronized(this) - { - notifyAll(); - } + + notifyAll(); } + + } - synchronized void waitUntilComplete() throws InterruptedException + synchronized void waitUntilComplete() throws Exception { - while(_count < _expected) + + if(_count < _expected) + { + wait(10000L); + } + if(_count < _expected) { - wait(); + throw new Exception("Didn't receive all messages... got " + _count + " expected " + _expected); } } static AMQConnection connect(String broker) throws Exception { - return new AMQConnection(broker, "guest", "guest", "Client" + System.currentTimeMillis(), "/test_path"); + return new AMQConnection(broker, "guest", "guest", "Client" + System.currentTimeMillis(), "test"); } public static void main(String[] argv) throws Exception diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java index a1c64e2246..58f9c6fc19 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/Service.java @@ -73,7 +73,7 @@ public class Service implements MessageListener static AMQConnection connect(String broker) throws Exception { - return new AMQConnection(broker, "guest", "guest", "Client" + System.currentTimeMillis(), "/test_path"); + return new AMQConnection(broker, "guest", "guest", "Client" + System.currentTimeMillis(), "test"); } // public static void main(String[] argv) throws Exception diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java index 22015dbc93..691acbb213 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/SpecialQueue.java @@ -21,6 +21,7 @@ package org.apache.qpid.test.unit.client.forwardall; import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.framing.AMQShortString; /** * Queue that allows several private queues to be registered and bound @@ -29,15 +30,19 @@ import org.apache.qpid.client.AMQQueue; */ class SpecialQueue extends AMQQueue { - private final String name; + private final AMQShortString name; SpecialQueue(String name) { + this(new AMQShortString(name)); + } + SpecialQueue(AMQShortString name) + { super(name, true); this.name = name; } - public String getRoutingKey() + public AMQShortString getRoutingKey() { return name; } 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 bbd1870168..0e4603ed24 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 @@ -54,7 +54,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener protected void setUp() throws Exception { super.setUp(); - connection = new AMQConnection(_broker, "guest", "guest", randomize("Client"), "/test_path"); + connection = new AMQConnection(_broker, "guest", "guest", randomize("Client"), "test"); destination = new AMQQueue(randomize("LatencyTest"), true); session = (AMQSession) connection.createSession(false, AMQSession.NO_ACKNOWLEDGE); @@ -101,6 +101,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener } catch (Exception e) { + e.printStackTrace(); fail("This Test should succeed but failed due to: " + e); } finally @@ -236,7 +237,7 @@ public class ObjectMessageTest extends TestCase implements MessageListener public void onMessage(Message message) { - received++; + try { if (message instanceof ObjectMessage) @@ -255,13 +256,11 @@ public class ObjectMessageTest extends TestCase implements MessageListener items.add(e); } - if (waiting) - { synchronized(this) { + received++; notify(); } - } } 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 eee9b2de9f..64898a1b9a 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 @@ -23,6 +23,7 @@ package org.apache.qpid.test.unit.client.protocol; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.framing.AMQShortString; import org.apache.mina.common.IoSession; import junit.framework.TestCase; @@ -45,7 +46,7 @@ public class AMQProtocolSessionTest extends TestCase return (TestIoSession) _minaProtocolSession; } - public String genQueueName() + public AMQShortString genQueueName() { return generateQueueName(); } @@ -80,26 +81,26 @@ public class AMQProtocolSessionTest extends TestCase public void testGenerateQueueName() { - String testAddress; + AMQShortString testAddress; - //test address with / and ; chars which generateQueueName should remove + //test address with / and ; chars which generateQueueName should removeKey _testSession.getMinaProtocolSession().setStringLocalAddress(_brokenAddress); _testSession.getMinaProtocolSession().setLocalPort(_port); testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue exchange from an address with special chars",_generatedAddress,testAddress); + assertEquals("Failure when generating a queue exchange from an address with special chars",_generatedAddress,testAddress.toString()); //test empty address _testSession.getMinaProtocolSession().setStringLocalAddress(_emptyAddress); testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue exchange from an empty address",_generatedAddress_2,testAddress); + assertEquals("Failure when generating a queue exchange from an empty address",_generatedAddress_2,testAddress.toString()); //test address with no special chars _testSession.getMinaProtocolSession().setStringLocalAddress(_validAddress); testAddress = _testSession.genQueueName(); - assertEquals("Failure when generating a queue exchange 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.toString()); } 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 index 6c064e3853..b6c539d91c 100644 --- 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 @@ -28,7 +28,7 @@ public class TemporaryQueueTest extends TestCase protected Connection createConnection() throws AMQException, URLSyntaxException
{
return new AMQConnection(_broker, "guest", "guest",
- "fred", "/test");
+ "fred", "test");
}
public void testTempoaryQueue() throws Exception
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 index c9240e9be7..7cbd4e8bdd 100644 --- 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 @@ -51,7 +51,7 @@ public class TopicPublisherCloseTest extends TestCase public void testAllMethodsThrowAfterConnectionClose() throws Exception { - AMQConnection connection = new AMQConnection(_connectionString, "guest", "guest", "Client", "/test_path"); + AMQConnection connection = new AMQConnection(_connectionString, "guest", "guest", "Client", "test"); Topic destination1 = new AMQTopic("t1"); TopicSession session1 = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java index c14b5317c7..1f53d7de65 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSDestinationTest.java @@ -11,6 +11,7 @@ import org.apache.qpid.url.AMQBindingURL; import org.apache.qpid.url.BindingURL;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.AMQShortString;
import javax.jms.*;
@@ -39,12 +40,12 @@ public class JMSDestinationTest extends TestCase public void testJMSDestination() throws Exception
{
- Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test");
+ Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "test");
AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE);
- Queue queue = new AMQQueue("someQ", "someQ", false, true);
+ Queue queue = new AMQQueue(new AMQShortString("someQ"), new AMQShortString("someQ"), false, true);
MessageConsumer consumer = consumerSession.createConsumer(queue);
- Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test");
+ Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test");
Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
MessageProducer producer = producerSession.createProducer(queue);
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java new file mode 100644 index 0000000000..c09d2504eb --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java @@ -0,0 +1,100 @@ +/* + * + * 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.message; + +import junit.framework.TestCase; +import org.apache.log4j.Logger; +import org.apache.qpid.client.transport.TransportConnection; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.client.message.TestNonQpidTextMessage; +import org.apache.qpid.framing.AMQShortString; + +import javax.jms.*; + +/** + * @author Apache Software Foundation + */ +public class JMSPropertiesTest extends TestCase +{ + + private static final Logger _logger = Logger.getLogger(JMSPropertiesTest.class); + + public String _connectionString = "vm://:1"; + + public static final String JMS_CORR_ID = "QPIDID_01"; + public static final int JMS_DELIV_MODE = 1; + public static final String JMS_TYPE = "test.jms.type"; + public static final Destination JMS_REPLY_TO = new AMQQueue("my.replyto"); + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + + public void testJMSProperties() throws Exception + { + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "test"); + AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); + Queue queue = new AMQQueue(new AMQShortString("someQ"), new AMQShortString("someQ"), false, true); + MessageConsumer consumer = consumerSession.createConsumer(queue); + + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test"); + Session producerSession = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); + MessageProducer producer = producerSession.createProducer(queue); + + //create a test message to send + ObjectMessage sentMsg = new TestNonQpidTextMessage(); + sentMsg.setJMSCorrelationID(JMS_CORR_ID); + sentMsg.setJMSDeliveryMode(JMS_DELIV_MODE); + sentMsg.setJMSType(JMS_TYPE); + sentMsg.setJMSReplyTo(JMS_REPLY_TO); + + //send it + producer.send(sentMsg); + + con2.close(); + + con.start(); + + //get message and check JMS properties + ObjectMessage rm = (ObjectMessage) consumer.receive(); + assertNotNull(rm); + + assertEquals("JMS Correlation ID mismatch",sentMsg.getJMSCorrelationID(),rm.getJMSCorrelationID()); + //TODO: Commented out as always overwritten by send delivery mode value - prob should not set in conversion + //assertEquals("JMS Delivery Mode mismatch",sentMsg.getJMSDeliveryMode(),rm.getJMSDeliveryMode()); + assertEquals("JMS Type mismatch",sentMsg.getJMSType(),rm.getJMSType()); + assertEquals("JMS Reply To mismatch",sentMsg.getJMSReplyTo(),rm.getJMSReplyTo()); + + con.close(); + } + +} diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java new file mode 100644 index 0000000000..6a335b8627 --- /dev/null +++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/MessageConverterTest.java @@ -0,0 +1,109 @@ +/* + * + * 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.message; + +import junit.framework.TestCase; +import org.apache.qpid.client.message.MessageConverter; +import org.apache.qpid.client.message.JMSTextMessage; +import org.apache.qpid.client.message.AbstractJMSMessage; +import org.apache.qpid.client.message.JMSMapMessage; +import org.apache.qpid.client.AMQQueue; + +import javax.jms.Message; +import javax.jms.Destination; +import javax.jms.TextMessage; +import javax.jms.MapMessage; +import java.util.HashMap; + + +public class MessageConverterTest extends TestCase { + + public static final String JMS_CORR_ID = "QPIDID_01"; + public static final int JMS_DELIV_MODE = 1; + public static final String JMS_TYPE = "test.jms.type"; + public static final Destination JMS_REPLY_TO = new AMQQueue("my.replyto"); + + protected JMSTextMessage testTextMessage; + + protected JMSMapMessage testMapMessage; + + protected void setUp() throws Exception + { + super.setUp(); + testTextMessage = new JMSTextMessage(); + + //Add JMSProperties + testTextMessage.setJMSCorrelationID(JMS_CORR_ID); + testTextMessage.setJMSDeliveryMode(JMS_DELIV_MODE); + testTextMessage.setJMSType(JMS_TYPE); + testTextMessage.setJMSReplyTo(JMS_REPLY_TO); + testTextMessage.setText("testTextMessage text"); + + //Add non-JMS properties + testTextMessage.setStringProperty("testProp1","testValue1"); + testTextMessage.setDoubleProperty("testProp2",Double.MIN_VALUE); + + testMapMessage = new JMSMapMessage(); + testMapMessage.setString("testMapString","testMapStringValue"); + testMapMessage.setDouble("testMapDouble",Double.MAX_VALUE); + } + + public void testSetProperties() throws Exception + { + AbstractJMSMessage newMessage = new MessageConverter((TextMessage)testTextMessage).getConvertedMessage(); + + //check JMS prop values on newMessage match + assertEquals("JMS Correlation ID mismatch",testTextMessage.getJMSCorrelationID(),newMessage.getJMSCorrelationID()); + assertEquals("JMS Delivery mode mismatch",testTextMessage.getJMSDeliveryMode(),newMessage.getJMSDeliveryMode()); + assertEquals("JMS Type mismatch",testTextMessage.getJMSType(),newMessage.getJMSType()); + assertEquals("JMS Reply To mismatch",testTextMessage.getJMSReplyTo(),newMessage.getJMSReplyTo()); + + //check non-JMS standard props ok too + assertEquals("Test String prop value mismatch",testTextMessage.getStringProperty("testProp1"), + newMessage.getStringProperty("testProp1")); + assertEquals("Test Double prop value mismatch",testTextMessage.getDoubleProperty("testProp2"), + newMessage.getDoubleProperty("testProp2")); + } + + public void testJMSTextMessageConversion() throws Exception + { + AbstractJMSMessage newMessage = new MessageConverter((TextMessage)testTextMessage).getConvertedMessage(); + assertEquals("Converted message text mismatch",((JMSTextMessage)newMessage).getText(),testTextMessage.getText()); + } + + public void testJMSMapMessageConversion() throws Exception + { + AbstractJMSMessage newMessage = new MessageConverter((MapMessage)testMapMessage).getConvertedMessage(); + assertEquals("Converted map message String mismatch",((JMSMapMessage)newMessage).getString("testMapString"), + testMapMessage.getString("testMapString")); + assertEquals("Converted map message Double mismatch",((JMSMapMessage)newMessage).getDouble("testMapDouble"), + testMapMessage.getDouble("testMapDouble")); + + } + + protected void tearDown() throws Exception + { + super.tearDown(); + testTextMessage = null; + } + + +} 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 index 184d7cb015..7d83d19d74 100644 --- 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 @@ -1,11 +1,23 @@ -/** - * 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 - ******************************************************************************/ +/* + * + * 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.message; import junit.framework.TestCase; @@ -47,7 +59,7 @@ public class StreamMessageTest extends TestCase public void testStreamMessageEOF() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "test"); AMQSession consumerSession = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE); @@ -60,7 +72,7 @@ public class StreamMessageTest extends TestCase //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"); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test"); AMQSession producerSession = (AMQSession) con2.createSession(false, Session.CLIENT_ACKNOWLEDGE); @@ -101,7 +113,7 @@ public class StreamMessageTest extends TestCase public void testModifyReceivedMessageExpandsBuffer() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + 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); @@ -123,7 +135,7 @@ public class StreamMessageTest extends TestCase } } }); - Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + 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(); 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 5ded8aaeef..7e645f1a26 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 @@ -25,7 +25,7 @@ import org.apache.qpid.url.URLSyntaxException; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.testutil.VMBrokerSetup; +import org.apache.qpid.client.transport.TransportConnection; import javax.jms.JMSException; import javax.jms.Message; @@ -39,10 +39,23 @@ import junit.framework.TestCase; public class DurableSubscriptionTest extends TestCase { + + protected void setUp() throws Exception + { + super.setUp(); + TransportConnection.createVMBroker(1); + } + + protected void tearDown() throws Exception + { + super.tearDown(); + TransportConnection.killAllVMBrokers(); + } + public void testUnsubscribe() throws AMQException, JMSException, URLSyntaxException { AMQTopic topic = new AMQTopic("MyTopic"); - AMQConnection con = new AMQConnection("vm://:1", "guest", "guest", "test", "/test"); + AMQConnection con = new AMQConnection("vm://:1", "guest", "guest", "test", "test"); Session session1 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE); MessageConsumer consumer1 = session1.createConsumer(topic); MessageProducer producer = session1.createProducer(topic); @@ -83,7 +96,7 @@ public class DurableSubscriptionTest extends TestCase public void testDurability() throws AMQException, JMSException, URLSyntaxException { AMQTopic topic = new AMQTopic("MyTopic"); - AMQConnection con = new AMQConnection("vm://:1", "guest", "guest", "test", "/test"); + AMQConnection con = new AMQConnection("vm://:1", "guest", "guest", "test", "test"); Session session1 = con.createSession(false, AMQSession.NO_ACKNOWLEDGE); MessageConsumer consumer1 = session1.createConsumer(topic); MessageProducer producer = session1.createProducer(topic); @@ -128,6 +141,6 @@ public class DurableSubscriptionTest extends TestCase public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(DurableSubscriptionTest.class)); + return new junit.framework.TestSuite(DurableSubscriptionTest.class); } } 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 index 4ffb3e8459..c4acf15a58 100644 --- 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 @@ -48,7 +48,7 @@ public class TopicPublisherTest extends TestCase public void testUnidentifiedProducer() throws Exception { AMQTopic topic = new AMQTopic("MyTopic"); - AMQConnection con = new AMQConnection("vm://:1", "guest", "guest", "test", "/test"); + 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); 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 index 794316d2f5..8e883a2184 100644 --- 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 @@ -51,7 +51,7 @@ public class TopicSessionTest extends TestCase public void testTopicSubscriptionUnsubscription() throws Exception { AMQTopic topic = new AMQTopic("MyTopic"); - AMQConnection con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + 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); @@ -97,7 +97,7 @@ public class TopicSessionTest extends TestCase { 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"); + 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); @@ -112,7 +112,7 @@ public class TopicSessionTest extends TestCase { session1.close(); con.close(); - con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "test"); con.start(); session1 = con.createTopicSession(false, AMQSession.NO_ACKNOWLEDGE); publisher = session1.createPublisher(null); @@ -134,11 +134,11 @@ public class TopicSessionTest extends TestCase public void testUnsubscriptionAfterConnectionClose() throws Exception { AMQTopic topic = new AMQTopic("MyTopic3"); - AMQConnection con1 = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + 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"); + 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"); @@ -149,7 +149,7 @@ public class TopicSessionTest extends TestCase assertNotNull(tm); con2.close(); publisher.publish(session1.createTextMessage("Hello2")); - con2 = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test2", "/test"); + 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(); @@ -163,14 +163,14 @@ public class TopicSessionTest extends TestCase public void testTextMessageCreation() throws Exception { AMQTopic topic = new AMQTopic("MyTopic4"); - AMQConnection con = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + 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); + tm = (TextMessage) consumer1.receive(200000L); assertNotNull(tm); String msgText = tm.getText(); assertEquals("Hello", msgText); @@ -178,7 +178,7 @@ public class TopicSessionTest extends TestCase msgText = tm.getText(); assertNull(msgText); publisher.publish(tm); - tm = (TextMessage) consumer1.receive(2000); + tm = (TextMessage) consumer1.receive(20000000L); assertNotNull(tm); msgText = tm.getText(); assertNull(msgText); @@ -202,7 +202,7 @@ public class TopicSessionTest extends TestCase public void testSendingSameMessage() throws Exception { - AMQConnection conn = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + 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); @@ -219,12 +219,13 @@ public class TopicSessionTest extends TestCase assertNotNull(receivedMessage); assertEquals(sentMessage.getText(),receivedMessage.getText()); + conn.close(); } public void testTemporaryTopic() throws Exception { - AMQConnection conn = new AMQConnection("vm://:1?retries='0'", "guest", "guest", "test", "/test"); + 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); 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 3e1fc04626..ce6df83baf 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 @@ -23,8 +23,11 @@ package org.apache.qpid.test.unit.transacted; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.testutil.VMBrokerSetup; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.mina.util.SessionLog; import org.apache.log4j.Logger; import javax.jms.*; @@ -54,10 +57,11 @@ public class TransactedTest extends TestCase protected void setUp() throws Exception { super.setUp(); - queue1 = new AMQQueue("Q1", "Q1", false, true); + TransportConnection.createVMBroker(1); + queue1 = new AMQQueue(new AMQShortString("Q1"), new AMQShortString("Q1"), false, true); queue2 = new AMQQueue("Q2", false); - con = new AMQConnection("vm://:1", "guest", "guest", "TransactedTest", "/test"); + con = new AMQConnection("vm://:1", "guest", "guest", "TransactedTest", "test"); session = con.createSession(true, 0); consumer1 = session.createConsumer(queue1); //Dummy just to create the queue. @@ -66,16 +70,26 @@ public class TransactedTest extends TestCase producer2 = session.createProducer(queue2); con.start(); - prepCon = new AMQConnection("vm://:1", "guest", "guest", "PrepConnection", "/test"); + prepCon = new AMQConnection("vm://:1", "guest", "guest", "PrepConnection", "test"); prepSession = prepCon.createSession(false, AMQSession.NO_ACKNOWLEDGE); prepProducer1 = prepSession.createProducer(queue1); prepCon.start(); + +// //add some messages +// prepProducer1.send(prepSession.createTextMessage("A")); +// prepProducer1.send(prepSession.createTextMessage("B")); +// prepProducer1.send(prepSession.createTextMessage("C")); +// +// testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "/test"); +// testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE); +// testConsumer2 = testSession.createConsumer(queue2); } protected void tearDown() throws Exception { con.close(); prepCon.close(); + TransportConnection.killAllVMBrokers(); super.tearDown(); } @@ -96,9 +110,9 @@ public class TransactedTest extends TestCase //commit session.commit(); - + testCon.start(); //ensure sent messages can be received and received messages are gone - testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "/test"); + testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test"); testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE); testConsumer1 = testSession.createConsumer(queue1); testConsumer2 = testSession.createConsumer(queue2); @@ -108,6 +122,7 @@ public class TransactedTest extends TestCase expect("Y", testConsumer2.receive(1000)); expect("Z", testConsumer2.receive(1000)); + testConsumer1 = testSession.createConsumer(queue1); assertTrue(null == testConsumer1.receive(1000)); assertTrue(null == testConsumer2.receive(1000)); testCon.close(); @@ -141,11 +156,12 @@ public class TransactedTest extends TestCase expect("A", consumer1.receive(1000)); expect("B", consumer1.receive(1000)); expect("C", consumer1.receive(1000)); - + testCon.start(); + testConsumer1 = testSession.createConsumer(queue1); //commit session.commit(); - testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "/test"); + testCon = new AMQConnection("vm://:1", "guest", "guest", "TestConnection", "test"); testSession = testCon.createSession(false, AMQSession.NO_ACKNOWLEDGE); testConsumer1 = testSession.createConsumer(queue1); testConsumer2 = testSession.createConsumer(queue2); @@ -164,7 +180,7 @@ public class TransactedTest extends TestCase public void testResendsMsgsAfterSessionClose() throws Exception { - Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "/test"); + Connection con = new AMQConnection("vm://:1", "guest", "guest", "consumer1", "test"); Session consumerSession = con.createSession(true, Session.CLIENT_ACKNOWLEDGE); AMQQueue queue3 = new AMQQueue("Q3", false); @@ -172,7 +188,7 @@ public class TransactedTest extends TestCase //force synch to ensure the consumer has resulted in a bound queue ((AMQSession) consumerSession).declareExchangeSynch(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS); - Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "/test"); + Connection con2 = new AMQConnection("vm://:1", "guest", "guest", "producer1", "test"); Session producerSession = con2.createSession(true, Session.CLIENT_ACKNOWLEDGE); MessageProducer producer = producerSession.createProducer(queue3); @@ -234,6 +250,7 @@ public class TransactedTest extends TestCase con.close(); con2.close(); + } // This checks that queue Q1 is in fact empty and does not have any stray @@ -251,6 +268,6 @@ public class TransactedTest extends TestCase public static junit.framework.Test suite() { - return new VMBrokerSetup(new junit.framework.TestSuite(TransactedTest.class)); + return new junit.framework.TestSuite(TransactedTest.class); } } |
