diff options
| author | Martin Ritchie <ritchiem@apache.org> | 2007-08-30 12:19:31 +0000 |
|---|---|---|
| committer | Martin Ritchie <ritchiem@apache.org> | 2007-08-30 12:19:31 +0000 |
| commit | 61a61c3716e42bf175004049976391407f28704d (patch) | |
| tree | 8ab343c1941a7565532189763dc79473a10beb3c /java/broker | |
| parent | e183227707d150b1f42e750df0e90cd7dac8744e (diff) | |
| download | qpid-python-61a61c3716e42bf175004049976391407f28704d.tar.gz | |
Remerge of M2. All tests pass locally
Testing done in Intelij and mvn command line via windows/cygwin.
Python tests removed from auto build pending Jython-siztion. Tested running broker in intelij and python run-tests from cygwin.
All tests pass. (CombinedTest still exhibts a race condition. but that has always been so.)
Additional Race condition identified (around MsgReject/AutoDeleteQueues) during testing patch to follow.
systests are inconsistent Some use TestableMemoryMessageStore some use MemoryMessgaeStore.
Lets not roll back this change if issues are discovered. Lets work together to go forward and address any issues. I have spent a lot of time ensuring the tests work for me so I hope that they work for you.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@571129 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker')
84 files changed, 5898 insertions, 1291 deletions
diff --git a/java/broker/bin/msTool.sh b/java/broker/bin/msTool.sh new file mode 100755 index 0000000000..b291ed9fe3 --- /dev/null +++ b/java/broker/bin/msTool.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# +# 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. +# + +die() { + if [[ $1 = -usage ]]; then + shift + usage=true + else + usage=false + fi + echo "$@" + $usage && echo + $usage && usage + exit 1 +} + +cygwin=false +if [[ "$(uname -a | fgrep Cygwin)" != "" ]]; then + cygwin=true +fi + +if [ -z "$QPID_TOOLS" ]; then + if [ -z "$QPID_HOME" ]; then + die "QPID_TOOLS must be set" + else + QPID_TOOLS=$QPID_HOME + fi +fi + +if $cygwin; then + QPID_TOOLS=$(cygpath -w $QPID_TOOLS) +fi + +# Set classpath to include Qpid jar with all required jars in manifest +QPID_LIBS=$QPID_TOOLS/lib/qpid-incubating.jar + +# Set other variables used by the qpid-run script before calling +export JAVA=java \ + JAVA_VM=-server \ + JAVA_OPTS=-Dlog4j.configuration=file:$QPID_TOOLS/etc/mstool-log4j.xml \ + QPID_CLASSPATH=$QPID_LIBS + +. qpid-run org.apache.qpid.tools.messagestore.MessageStoreTool "$@" diff --git a/java/broker/bin/qpid-passwd b/java/broker/bin/qpid-passwd index 6e64af6e70..f046252522 100644 --- a/java/broker/bin/qpid-passwd +++ b/java/broker/bin/qpid-passwd @@ -27,4 +27,4 @@ export JAVA=java \ JAVA_MEM=-Xmx1024m \
QPID_CLASSPATH=$QPID_LIBS
-. qpid-run org.apache.qpid.server.security.Passwd "$@"
+. qpid-run org.apache.qpid.tools.security.Passwd "$@"
diff --git a/java/broker/bin/qpid-server b/java/broker/bin/qpid-server index 76d0ad786d..0b1d91c914 100644 --- a/java/broker/bin/qpid-server +++ b/java/broker/bin/qpid-server @@ -1,31 +1,31 @@ -#!/bin/bash -# -# 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. -# - -# Set classpath to include Qpid jar with all required jars in manifest -QPID_LIBS=$QPID_HOME/lib/qpid-incubating.jar:$QPID_HOME/lib/bdbstore-launch.jar - -# Set other variables used by the qpid-run script before calling -export JAVA=java \ - JAVA_VM=-server \ - JAVA_MEM=-Xmx1024m \ - JAVA_GC=-XX:-UseConcMarkSweepGC - QPID_CLASSPATH=$QPID_LIBS - -. qpid-run org.apache.qpid.server.Main "$@" +#!/bin/bash
+#
+# 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.
+#
+
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_HOME/lib/qpid-incubating.jar:$QPID_HOME/lib/bdbstore-launch.jar
+
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_MEM=-Xmx1024m \
+ JAVA_GC="-XX:-UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError" \
+ QPID_CLASSPATH=$QPID_LIBS
+
+. qpid-run org.apache.qpid.server.Main "$@"
diff --git a/java/broker/distribution/src/main/assembly/broker-bin.xml b/java/broker/distribution/src/main/assembly/broker-bin.xml index 4b32630771..e66190a3f4 100644 --- a/java/broker/distribution/src/main/assembly/broker-bin.xml +++ b/java/broker/distribution/src/main/assembly/broker-bin.xml @@ -114,9 +114,9 @@ <fileMode>473</fileMode> </file> <file> - <source>../bin/passwd</source> + <source>../bin/qpid-passwd</source> <outputDirectory>qpid-${qpid.version}/bin</outputDirectory> - <destName>passwd</destName> + <destName>qpid-passwd</destName> <fileMode>473</fileMode> </file> <file> diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml index aee1267274..1bb2eb5157 100644 --- a/java/broker/etc/config.xml +++ b/java/broker/etc/config.xml @@ -90,18 +90,19 @@ <virtualhosts> <virtualhost> <name>localhost</name> - <localhost> - <store> - <environment-path>${work}/localhost-store</environment-path> - <!-- <class>org.apache.qpid.server.store.berkeleydb.messageStore.MessageStoreImpl</class> --> - <class>org.apache.qpid.server.messageStore.MemoryMessageStore</class> - </store> + <localhost> + <store> + <!-- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class> + <environment-path>${work}/localhost-store</environment-path> --> + + <class>org.apache.qpid.server.store.MemoryMessageStore</class> + </store> <txn> <environment-tx-timeout>60</environment-tx-timeout> <!-- <class>org.apache.qpid.server.store.berkeleydb.txn.TransactionManagerImpl</class> --> <class>org.apache.qpid.server.txn.MemoryTransactionManager</class> </txn> - + <security> <!-- Need protocol changes to allow this--> <authentication> @@ -129,8 +130,8 @@ <virtualhost> <name>development</name> <development> - <store> - <class>org.apache.qpid.server.messageStore.MemoryMessageStore</class> + <store> + <class>org.apache.qpid.server.store.MemoryMessageStore</class> </store> <txn> <class>org.apache.qpid.server.txn.MemoryTransactionManager</class> @@ -147,7 +148,7 @@ <name>test</name> <test> <store> - <class>org.apache.qpid.server.messageStore.MemoryMessageStore</class> + <class>org.apache.qpid.server.store.MemoryMessageStore</class> </store> <txn> <class>org.apache.qpid.server.txn.MemoryTransactionManager</class> diff --git a/java/broker/etc/debug.log4j.xml b/java/broker/etc/debug.log4j.xml new file mode 100644 index 0000000000..e8fd7e119d --- /dev/null +++ b/java/broker/etc/debug.log4j.xml @@ -0,0 +1,114 @@ +<?xml version="1.0"?> +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> + <appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender"> + <!-- Ensure that logs allways have the dateFormat set--> + <param name="StaticLogFileName" value="false"/> + <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> + <param name="Append" value="false"/> + <!-- Change the direction so newer files have bigger numbers --> + <!-- So log.1 is written then log.2 etc This prevents a lot of file renames at log rollover --> + <param name="CountDirection" value="1"/> + <!-- Use default 10MB --> + <!--param name="MaxFileSize" value="100000"/--> + <param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm"/> + <!-- Unlimited number of backups --> + <param name="MaxSizeRollBackups" value="-1"/> + <!-- Compress(gzip) the backup files--> + <param name="CompressBackupFiles" value="true"/> + <!-- Compress the backup files using a second thread --> + <param name="CompressAsync" value="true"/> + <!-- Start at zero numbered files--> + <param name="ZeroBased" value="true"/> + <!-- Backup Location --> + <param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </layout> + </appender> + + <appender name="FileAppender" class="org.apache.log4j.FileAppender"> + <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> + <param name="Append" value="false"/> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </layout> + </appender> + + <appender name="AlertFile" class="org.apache.log4j.FileAppender"> + <param name="File" value="${QPID_WORK}/log/alert.log"/> + <param name="Append" value="false"/> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </layout> + </appender> + + <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> + + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </layout> + </appender> + + <category name="Qpid.Broker"> + <priority value="debug"/> + <appender-ref ref="AlertFile"/> + <!--appender-ref ref="STDOUT"/--> + </category> + + + <category name="org.apache.qpid.server.queue.AMQQueueMBean"> + <priority value="info"/> + <appender-ref ref="AlertFile"/> + </category> + + + <!-- Provide warnings to standard output --> + <!--category name="org.apache.qpid"> + <priority value="warn"/> + <appender-ref ref="STDOUT"/> + </category--> + + + <!-- Additional level settings for debugging --> + <!-- Each class in the Broker is a category that can have its logging level adjusted. --> + <!-- This will provide more details if available about that classes processing. --> + <!--category name="org.apache.qpid.server.txn"> + <priority value="debug"/> + </category>--> + + <!--<category name="org.apache.qpid.server.store"> + <priority value="debug"/> + </category--> + + <!-- Log all info events to file --> + <root> + <priority value="info"/> + <appender-ref ref="STDOUT"/> + <appender-ref ref="FileAppender"/> + </root> + +</log4j:configuration> diff --git a/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml index 2fb7b80c96..f40da7751e 100644 --- a/java/broker/etc/log4j.xml +++ b/java/broker/etc/log4j.xml @@ -44,7 +44,7 @@ <param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/> <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> </layout> </appender> @@ -57,17 +57,47 @@ </layout> </appender> - <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> + <appender name="AlertFile" class="org.apache.log4j.FileAppender"> + <param name="File" value="${QPID_WORK}/log/alert.log"/> + <param name="Append" value="false"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> </layout> </appender> - <category name="Qpid.Broker"> + <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> + </layout> + </appender> + + <category name="Qpid.Broker"> + <priority value="debug"/> + <appender-ref ref="AlertFile"/> + + </category> + + <category name="org.apache.qpid.server.queue.AMQQueueMBean"> + <priority value="info"/> + <appender-ref ref="AlertFile"/> + </category> + + <!-- Provide warnings to standard output --> + <!--category name="org.apache.qpid"> + <priority value="warn"/> + <appender-ref ref="STDOUT"/> + </category--> + + <category name="org.apache.qpid"> <priority value="info"/> + <appender-ref ref="STDOUT"/> + <appender-ref ref="FileAppender"/> </category> + <!-- Examples of additional logging settings --> + <!-- Used to generate extra debug. See debug.log4j.xml --> + <!--<category name="org.apache.qpid.server.store"> <priority value="debug"/> </category--> @@ -80,10 +110,12 @@ <priority value="debug"/> </category>--> + <!-- Log all info events to file --> <root> <priority value="info"/> <appender-ref ref="STDOUT"/> <appender-ref ref="FileAppender"/> <!--appender-ref ref="ArchivingFileAppender"/--> </root> + </log4j:configuration> diff --git a/java/broker/etc/mstool-log4j.xml b/java/broker/etc/mstool-log4j.xml new file mode 100644 index 0000000000..8c46010e2d --- /dev/null +++ b/java/broker/etc/mstool-log4j.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - + --> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> + + <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> + + <layout class="org.apache.log4j.PatternLayout"> + <!--param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/--> + <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/> + </layout> + </appender> + + <category name="org.apache.qpid.tools"> + <priority value="info"/> + </category> + + <category name="org.apache.qpid"> + <priority value="error"/> + </category> + + <category name="org.apache.qpid.server.security"> + <priority value="error"/> + </category> + + <category name="org.apache.qpid.server.management"> + <priority value="error"/> + </category> + + + <root> + <priority value="info"/> + <appender-ref ref="STDOUT"/> + </root> +</log4j:configuration> diff --git a/java/broker/etc/persistent_config.xml b/java/broker/etc/persistent_config.xml index 90d014b6fb..ed0591256b 100644 --- a/java/broker/etc/persistent_config.xml +++ b/java/broker/etc/persistent_config.xml @@ -73,8 +73,8 @@ <virtualhosts> <virtualhost> <name>localhost</name> - <localhost> - <store> + <localhost> + <store> <environment-path>${work}/bdbstore/localhost-store</environment-path> <class>org.apache.qpid.server.store.berkeleydb.messageStore.MessageStoreImpl</class> </store> diff --git a/java/broker/etc/qpid.passwd b/java/broker/etc/qpid.passwd new file mode 100644 index 0000000000..79b5e11777 --- /dev/null +++ b/java/broker/etc/qpid.passwd @@ -0,0 +1,22 @@ +#
+# 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.
+#
+guest:CE4DQ6BIb/BVMN9scFyLtA==
+admin:ISMvKXpXpadDiUoOSoAfww==
+user:CE4DQ6BIb/BVMN9scFyLtA==
+
diff --git a/java/broker/pom.xml b/java/broker/pom.xml index f45795e25b..ac11ee704f 100644 --- a/java/broker/pom.xml +++ b/java/broker/pom.xml @@ -78,13 +78,6 @@ <!-- Test Dependencies --> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.4.0</version> - <scope>test</scope> - </dependency> - - <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> @@ -101,6 +94,25 @@ <build> <plugins> + + + <!--plugin> + <artifactId>minijar-maven-plugin</artifactId> + <groupId>org.codehaus.mojo</groupId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>minijars</goal> + </goals> + <configuration> + <stripUnusedClasses>true</stripUnusedClasses> + </configuration> + </execution> + </executions> + </plugin--> + + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> @@ -171,7 +183,8 @@ </testResource> </testResources> - <pluginManagement> + <!-- DISABLED - TOBE fixed by ritchiem - should use Jython. --> + <!--pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -204,7 +217,8 @@ <property name="command" value="python run-tests -v -I java_failing_0-8.txt"/> - <!--value="bash -c 'python run-tests -v -I java_failing.txt'"/>--> + + <-value="bash -c 'python run-tests -v -I java_failing.txt'"/>-> <ant antfile="python-test.xml" inheritRefs="true"> <target name="run-tests" /> @@ -219,7 +233,7 @@ </executions> </plugin> </plugins> - </pluginManagement> + </pluginManagement--> </build> diff --git a/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java b/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java index 931c15a664..7e0c4defe1 100644 --- a/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java +++ b/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java @@ -31,7 +31,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPOutputStream; import org.apache.log4j.helpers.CountingQuietWriter; @@ -39,8 +38,6 @@ import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.spi.LoggingEvent; -import org.apache.qpid.framing.FieldTable; - /** * <p>CompositeRollingAppender combines RollingFileAppender and DailyRollingFileAppender<br> It can function as either * or do both at the same time (making size based rolling files like RollingFileAppender until a data/time boundary is diff --git a/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java b/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java new file mode 100644 index 0000000000..40ff590a0a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java @@ -0,0 +1,188 @@ +/* + * 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.configuration; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class Configuration +{ + public static final String QPID_HOME = "QPID_HOME"; + + final String QPIDHOME = System.getProperty(QPID_HOME); + + private static Logger _devlog = LoggerFactory.getLogger(Configuration.class); + + public static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml"; + public static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; + + protected final Options _options = new Options(); + protected CommandLine _commandLine; + protected File _configFile; + + + public Configuration() + { + + } + + public void processCommandline(String[] args) throws InitException + { + try + { + _commandLine = new PosixParser().parse(_options, args); + } + catch (ParseException e) + { + throw new InitException("Unable to parse commmandline", e); + } + + final File defaultConfigFile = new File(QPIDHOME, DEFAULT_CONFIG_FILE); + setConfig(new File(_commandLine.getOptionValue("c", defaultConfigFile.getPath()))); + } + + public void setConfig(File file) + { + _configFile = file; + } + + /** + * @param option The option to set. + */ + public void setOption(Option option) + { + _options.addOption(option); + } + + /** + * getOptionValue from the configuration + * @param option variable argument, first string is option to get, second if present is the default value. + * @return the String for the given option or null if not present (if default value not specified) + */ + public String getOptionValue(String... option) + { + if (option.length == 1) + { + return _commandLine.getOptionValue(option[0]); + } + else if (option.length == 2) + { + return _commandLine.getOptionValue(option[0], option[1]); + } + return null; + } + + public void loadConfig(File file) throws InitException + { + setConfig(file); + loadConfig(); + } + + private void loadConfig() throws InitException + { + if (!_configFile.exists()) + { + String error = "File " + _configFile + " could not be found. Check the file exists and is readable."; + + if (QPIDHOME == null) + { + error = error + "\nNote: " + QPID_HOME + " is not set."; + } + + throw new InitException(error, null); + } + else + { + _devlog.debug("Using configuration file " + _configFile.getAbsolutePath()); + } + +// String logConfig = _commandLine.getOptionValue("l"); +// String logWatchConfig = _commandLine.getOptionValue("w", "0"); +// if (logConfig != null) +// { +// File logConfigFile = new File(logConfig); +// configureLogging(logConfigFile, logWatchConfig); +// } +// else +// { +// File configFileDirectory = _configFile.getParentFile(); +// File logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME); +// configureLogging(logConfigFile, logWatchConfig); +// } + } + + +// private void configureLogging(File logConfigFile, String logWatchConfig) +// { +// int logWatchTime = 0; +// try +// { +// logWatchTime = Integer.parseInt(logWatchConfig); +// } +// catch (NumberFormatException e) +// { +// _devlog.error("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " +// + "a non-negative integer. Using default of zero (no watching configured"); +// } +// +// if (logConfigFile.exists() && logConfigFile.canRead()) +// { +// _devlog.info("Configuring logger using configuration file " + logConfigFile.getAbsolutePath()); +// if (logWatchTime > 0) +// { +// _devlog.info("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every " +// + logWatchTime + " seconds"); +// // log4j expects the watch interval in milliseconds +// DOMConfigurator.configureAndWatch(logConfigFile.getAbsolutePath(), logWatchTime * 1000); +// } +// else +// { +// DOMConfigurator.configure(logConfigFile.getAbsolutePath()); +// } +// } +// else +// { +// System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath()); +// System.err.println("Using basic log4j configuration"); +// BasicConfigurator.configure(); +// } +// } + + public File getConfigFile() + { + return _configFile; + } + + + public class InitException extends Exception + { + InitException(String msg, Throwable cause) + { + super(msg, cause); + } + } +}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java index f2cc6e8bca..6d67686d1c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java @@ -37,19 +37,11 @@ */ package org.apache.qpid.server; -import javax.management.JMException; -import javax.management.MBeanException; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - import org.apache.commons.configuration.Configuration; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.configuration.Configurator; import org.apache.qpid.server.configuration.VirtualHostConfiguration; -import org.apache.qpid.server.exception.InternalErrorException; -import org.apache.qpid.server.exception.QueueAlreadyExistsException; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; @@ -58,11 +50,16 @@ import org.apache.qpid.server.management.MBeanConstructor; import org.apache.qpid.server.management.MBeanDescription; import org.apache.qpid.server.management.ManagedBroker; import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.messageStore.MessageStore; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueRegistry; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.VirtualHost; +import javax.management.JMException; +import javax.management.MBeanException; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + /** * This MBean implements the broker management interface and exposes the * Broker level management features like creating and deleting exchanges and queue. @@ -113,9 +110,8 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr Exchange exchange = _exchangeRegistry.getExchange(new AMQShortString(exchangeName)); if (exchange == null) { - exchange = - _exchangeFactory.createExchange(new AMQShortString(exchangeName), new AMQShortString(type), durable, - false, 0); + exchange = _exchangeFactory.createExchange(new AMQShortString(exchangeName), + new AMQShortString(type), durable, false, 0); _exchangeRegistry.registerExchange(exchange); } else @@ -181,20 +177,21 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr queue = new AMQQueue(new AMQShortString(queueName), durable, ownerShortString, false, getVirtualHost()); if (queue.isDurable() && !queue.isAutoDelete()) { - try - { + //DTX MessageStore +// try +// { _messageStore.createQueue(queue); - } - catch (Exception e) - { - JMException jme = new JMException("problem creating queue " + queue.getName()); - jme.initCause(e); - throw jme; - } +// } +// catch (Exception e) +// { +// JMException jme = new JMException("problem creating queue " + queue.getName()); +// jme.initCause(e); +// throw jme; +// } } Configuration virtualHostDefaultQueueConfiguration = - VirtualHostConfiguration.getDefaultQueueConfiguration(queue); + VirtualHostConfiguration.getDefaultQueueConfiguration(queue); if (virtualHostDefaultQueueConfiguration != null) { Configurator.configure(queue, virtualHostDefaultQueueConfiguration); @@ -230,10 +227,13 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr try { queue.delete(); - if (queue.isDurable()) - { - _messageStore.destroyQueue(queue); - } + + //DTX MessageStore +// if (queue.isDurable()) +// { +// _messageStore.destroyQueue(queue); + _messageStore.removeQueue(queue.getName()); +// } } catch (Exception ex) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index 28a9e85489..bd93ae2f85 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -21,8 +21,6 @@ package org.apache.qpid.server; import org.apache.log4j.Logger; - - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentBody; @@ -34,14 +32,17 @@ import org.apache.qpid.server.ack.UnacknowledgedMessageMap; import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl; import org.apache.qpid.server.exchange.MessageRouter; import org.apache.qpid.server.exchange.NoRouteException; -import org.apache.qpid.server.messageStore.MessageStore; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MessageHandleFactory; import org.apache.qpid.server.queue.Subscription; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.server.txn.*; +import org.apache.qpid.server.txn.LocalTransactionalContext; +import org.apache.qpid.server.txn.NonTransactionalContext; +import org.apache.qpid.server.txn.TransactionManager; +import org.apache.qpid.server.txn.TransactionalContext; import java.util.Collection; import java.util.HashMap; @@ -75,14 +76,10 @@ public class AMQChannel */ private AtomicLong _deliveryTag = new AtomicLong(0); - /** - * A channel has a default queue (the last declared) that is used when no queue name is explictily set - */ + /** A channel has a default queue (the last declared) that is used when no queue name is explictily set */ private AMQQueue _defaultQueue; - /** - * This tag is unique per subscription to a queue. The server returns this in response to a basic.consume request. - */ + /** This tag is unique per subscription to a queue. The server returns this in response to a basic.consume request. */ private int _consumerTag; /** @@ -92,9 +89,7 @@ public class AMQChannel */ private AMQMessage _currentMessage; - /** - * Maps from consumer tag to queue instance. Allows us to unsubscribe from a queue. - */ + /** Maps from consumer tag to queue instance. Allows us to unsubscribe from a queue. */ private final Map<AMQShortString, AMQQueue> _consumerTag2QueueMap = new HashMap<AMQShortString, AMQQueue>(); private final MessageStore _messageStore; @@ -126,7 +121,7 @@ public class AMQChannel private boolean _closing; public AMQChannel(AMQProtocolSession session, int channelId, TransactionManager transactionManager, - MessageStore messageStore, MessageRouter exchanges) throws AMQException + MessageStore messageStore, MessageRouter exchanges) throws AMQException { _session = session; _channelId = channelId; @@ -140,13 +135,15 @@ public class AMQChannel _txnContext = new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); } - /** - * Sets this channel to be part of a local transaction - */ + /** Sets this channel to be part of a local transaction */ public void setLocalTransactional() { - _txnContext = - new DistributedTransactionalContext(_transactionManager, _messageStore, _storeContext, _returnMessages); + + _txnContext = new LocalTransactionalContext(_messageStore, _storeContext, _returnMessages); + + // Why is the LocalTransactionalContext always a DTX one? +// _txnContext = +// new DistributedTransactionalContext(_transactionManager, _messageStore, _storeContext, _returnMessages); } public boolean isTransactional() @@ -210,7 +207,7 @@ public class AMQChannel } public void publishContentHeader(ContentHeaderBody contentHeaderBody, AMQProtocolSession protocolSession) - throws AMQException + throws AMQException { if (_currentMessage == null) { @@ -256,8 +253,8 @@ public class AMQChannel // returns true iff the message was delivered (i.e. if all data was // received if (_currentMessage.addContentBodyFrame(_storeContext, - protocolSession.getRegistry().getProtocolVersionMethodConverter().convertToContentChunk( - contentBody))) + protocolSession.getRegistry().getProtocolVersionMethodConverter().convertToContentChunk( + contentBody))) { // callback to allow the context to do any post message processing // primary use is to allow message return processing in the non-tx case @@ -307,12 +304,14 @@ public class AMQChannel * @param exclusive Flag requesting exclusive access to the queue * @param acks Are acks enabled for this subscriber * @param filters Filters to apply to this subscriber + * * @return the consumer tag. This is returned to the subscriber and used in subsequent unsubscribe requests + * * @throws ConsumerTagNotUniqueException if the tag is not unique * @throws AMQException if something goes wrong */ public AMQShortString subscribeToQueue(AMQShortString tag, AMQQueue queue, AMQProtocolSession session, boolean acks, - FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException, ConsumerTagNotUniqueException + FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException, ConsumerTagNotUniqueException { if (tag == null) { @@ -343,6 +342,7 @@ public class AMQChannel * Called from the protocol session to close this channel and clean up. T * * @param session The session to close + * * @throws AMQException if there is an error during closure */ public void close(AMQProtocolSession session) throws AMQException @@ -408,7 +408,7 @@ public class AMQChannel if (_log.isDebugEnabled()) { _log.debug(debugIdentity() + " Adding unacked message(" + message.toString() + " DT:" + deliveryTag - + ") with a queue(" + queue + ") for " + consumerTag); + + ") with a queue(" + queue + ") for " + consumerTag); } } } @@ -454,7 +454,7 @@ public class AMQChannel // if (_nonTransactedContext == null) { _nonTransactedContext = - new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); + new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); } deliveryContext = _nonTransactedContext; @@ -490,6 +490,7 @@ public class AMQChannel * Requeue a single message * * @param deliveryTag The message to requeue + * * @throws AMQException If something goes wrong. */ public void requeue(long deliveryTag) throws AMQException @@ -516,7 +517,7 @@ public class AMQChannel // if (_nonTransactedContext == null) { _nonTransactedContext = - new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); + new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); } deliveryContext = _nonTransactedContext; @@ -536,7 +537,7 @@ public class AMQChannel else { _log.warn(System.identityHashCode(this) + " Requested requeue of message(" + unacked.message.debugIdentity() - + "):" + deliveryTag + " but no queue defined and no DeadLetter queue so DROPPING message."); + + "):" + deliveryTag + " but no queue defined and no DeadLetter queue so DROPPING message."); // _log.error("Requested requeue of message:" + deliveryTag + // " but no queue defined using DeadLetter queue:" + getDeadLetterQueue()); // @@ -547,25 +548,26 @@ public class AMQChannel else { _log.warn("Requested requeue of message:" + deliveryTag + " but no such delivery tag exists." - + _unacknowledgedMessageMap.size()); + + _unacknowledgedMessageMap.size()); if (_log.isDebugEnabled()) { _unacknowledgedMessageMap.visit(new UnacknowledgedMessageMap.Visitor() - { - int count = 0; + { + int count = 0; - public boolean callback(UnacknowledgedMessage message) throws AMQException - { - _log.debug( + public boolean callback(UnacknowledgedMessage message) throws AMQException + { + _log.debug( (count++) + ": (" + message.message.debugIdentity() + ")" + "[" + message.deliveryTag + "]"); - return false; // Continue - } + return false; // Continue + } - public void visitComplete() - { } - }); + public void visitComplete() + { + } + }); } } @@ -575,6 +577,7 @@ public class AMQChannel * Called to resend all outstanding unacknowledged messages to this same channel. * * @param requeue Are the messages to be requeued or dropped. + * * @throws AMQException When something goes wrong. */ public void resend(final boolean requeue) throws AMQException @@ -582,73 +585,74 @@ public class AMQChannel final List<UnacknowledgedMessage> msgToRequeue = new LinkedList<UnacknowledgedMessage>(); final List<UnacknowledgedMessage> msgToResend = new LinkedList<UnacknowledgedMessage>(); - if (_log.isInfoEnabled()) + if (_log.isDebugEnabled()) { - _log.info("unacked map Size:" + _unacknowledgedMessageMap.size()); + _log.debug("unacked map Size:" + _unacknowledgedMessageMap.size()); } // Process the Unacked-Map. // Marking messages who still have a consumer for to be resent // and those that don't to be requeued. _unacknowledgedMessageMap.visit(new UnacknowledgedMessageMap.Visitor() + { + public boolean callback(UnacknowledgedMessage message) throws AMQException { - public boolean callback(UnacknowledgedMessage message) throws AMQException + AMQShortString consumerTag = message.consumerTag; + AMQMessage msg = message.message; + msg.setRedelivered(true); + if (consumerTag != null) { - AMQShortString consumerTag = message.consumerTag; - AMQMessage msg = message.message; - msg.setRedelivered(true); - if (consumerTag != null) + // Consumer exists + if (_consumerTag2QueueMap.containsKey(consumerTag)) { - // Consumer exists - if (_consumerTag2QueueMap.containsKey(consumerTag)) - { - msgToResend.add(message); - } - else // consumer has gone - { - msgToRequeue.add(message); - } + msgToResend.add(message); } - else + else // consumer has gone { - // Message has no consumer tag, so was "delivered" to a GET - // or consumer no longer registered - // cannot resend, so re-queue. - if (message.queue != null) + msgToRequeue.add(message); + } + } + else + { + // Message has no consumer tag, so was "delivered" to a GET + // or consumer no longer registered + // cannot resend, so re-queue. + if (message.queue != null) + { + if (requeue) { - if (requeue) - { - msgToRequeue.add(message); - } - else - { - _log.info("No DeadLetter Queue and requeue not requested so dropping message:" + message); - } + msgToRequeue.add(message); } else { - _log.info("Message.queue is null and no DeadLetter Queue so dropping message:" + message); + _log.info("No DeadLetter Queue and requeue not requested so dropping message:" + message); } } - - // false means continue processing - return false; + else + { + _log.info("Message.queue is null and no DeadLetter Queue so dropping message:" + message); + } } - public void visitComplete() - { } - }); + // false means continue processing + return false; + } + + public void visitComplete() + { + } + }); // Process Messages to Resend - if (_log.isInfoEnabled()) + if (_log.isDebugEnabled()) { if (!msgToResend.isEmpty()) { - _log.info("Preparing (" + msgToResend.size() + ") message to resend."); + _log.debug("Preparing (" + msgToResend.size() + ") message to resend."); } else { - _log.info("No message to resend."); + _log.debug("No message to resend."); } } @@ -692,7 +696,7 @@ public class AMQChannel if (_log.isDebugEnabled()) { _log.debug("Subscription(" + System.identityHashCode(sub) - + ") closed during resend so requeuing message"); + + ") closed during resend so requeuing message"); } // move this message to requeue msgToRequeue.add(message); @@ -702,7 +706,7 @@ public class AMQChannel if (_log.isDebugEnabled()) { _log.debug("Requeuing " + msg.debugIdentity() + " for resend via sub:" - + System.identityHashCode(sub)); + + System.identityHashCode(sub)); } sub.addToResendQueue(msg); @@ -716,7 +720,7 @@ public class AMQChannel if (_log.isInfoEnabled()) { _log.info("DeliveredSubscription not recorded so just requeueing(" + message.toString() - + ")to prevent loss"); + + ")to prevent loss"); } // move this message to requeue msgToRequeue.add(message); @@ -740,7 +744,7 @@ public class AMQChannel if (_nonTransactedContext == null) { _nonTransactedContext = - new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); + new NonTransactionalContext(_messageStore, _storeContext, this, _returnMessages, _browsedAcks); } deliveryContext = _nonTransactedContext; @@ -768,34 +772,36 @@ public class AMQChannel * since we may get an ack for a delivery tag that was generated from the deleted queue. * * @param queue the queue that has been deleted + * * @throws org.apache.qpid.AMQException if there is an error processing the unacked messages */ public void queueDeleted(final AMQQueue queue) throws AMQException { _unacknowledgedMessageMap.visit(new UnacknowledgedMessageMap.Visitor() + { + public boolean callback(UnacknowledgedMessage message) throws AMQException { - public boolean callback(UnacknowledgedMessage message) throws AMQException + if (message.queue == queue) { - if (message.queue == queue) + try { - try - { - message.discard(_storeContext); - message.queue = null; - } - catch (AMQException e) - { - _log.error( + message.discard(_storeContext); + message.queue = null; + } + catch (AMQException e) + { + _log.error( "Error decrementing ref count on message " + message.message.getMessageId() + ": " + e, e); - } } - - return false; } - public void visitComplete() - { } - }); + return false; + } + + public void visitComplete() + { + } + }); } /** @@ -804,6 +810,7 @@ public class AMQChannel * @param deliveryTag the last delivery tag * @param multiple if true will acknowledge all messages up to an including the delivery tag. if false only * acknowledges the single message specified by the delivery tag + * * @throws AMQException if the delivery tag is unknown (e.g. not outstanding) on this channel */ public void acknowledgeMessage(long deliveryTag, boolean multiple) throws AMQException @@ -842,8 +849,8 @@ public class AMQChannel boolean suspend; suspend = - ((_prefetch_HighWaterMark != 0) && (_unacknowledgedMessageMap.size() >= _prefetch_HighWaterMark)) - || ((_prefetchSize != 0) && (_prefetchSize < _unacknowledgedMessageMap.getUnacknowledgeBytes())); + ((_prefetch_HighWaterMark != 0) && (_unacknowledgedMessageMap.size() >= _prefetch_HighWaterMark)) + || ((_prefetchSize != 0) && (_prefetchSize < _unacknowledgedMessageMap.getUnacknowledgeBytes())); setSuspended(suspend); } @@ -928,7 +935,7 @@ public class AMQChannel { AMQMessage message = bouncedMessage.getAMQMessage(); session.getProtocolOutputConverter().writeReturn(message, _channelId, bouncedMessage.getReplyCode().getCode(), - new AMQShortString(bouncedMessage.getMessage())); + new AMQShortString(bouncedMessage.getMessage())); } _returnMessages.clear(); @@ -943,7 +950,7 @@ public class AMQChannel else { boolean willSuspend = - ((_prefetch_HighWaterMark != 0) && ((_unacknowledgedMessageMap.size() + 1) > _prefetch_HighWaterMark)); + ((_prefetch_HighWaterMark != 0) && ((_unacknowledgedMessageMap.size() + 1) > _prefetch_HighWaterMark)); if (!willSuspend) { final long unackedSize = _unacknowledgedMessageMap.getUnacknowledgeBytes(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/ConsumerTagNotUniqueException.java b/java/broker/src/main/java/org/apache/qpid/server/ConsumerTagNotUniqueException.java index 3253650d14..3dc2654bd5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/ConsumerTagNotUniqueException.java +++ b/java/broker/src/main/java/org/apache/qpid/server/ConsumerTagNotUniqueException.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 @@ -32,4 +32,5 @@ package org.apache.qpid.server; * @todo Consider replacing with an AMQNotAllowedException, as this is the status code returned when this happens. */ public class ConsumerTagNotUniqueException extends Exception -{ } +{ +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java index 29ea69caf7..8932dd25f0 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -20,13 +20,6 @@ */ package org.apache.qpid.server; -import java.io.File; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.BindException; -import java.util.Collection; -import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; @@ -34,6 +27,7 @@ import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; +import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; @@ -48,6 +42,7 @@ import org.apache.qpid.common.QpidProperties; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.management.JMXManagedObjectRegistry; import org.apache.qpid.server.protocol.AMQPFastProtocolHandler; import org.apache.qpid.server.protocol.AMQPProtocolProvider; import org.apache.qpid.server.registry.ApplicationRegistry; @@ -55,11 +50,19 @@ import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; import org.apache.qpid.server.transport.ConnectorConfiguration; import org.apache.qpid.url.URLSyntaxException; +import java.io.File; +import java.io.IOException; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.List; + /** * Main entry point for AMQPD. * */ -@SuppressWarnings({ "AccessStaticViaInstance" }) +@SuppressWarnings({"AccessStaticViaInstance"}) public class Main { /** Used for debugging. */ @@ -133,6 +136,12 @@ public class Main OptionBuilder.withArgName("port").hasArg() .withDescription("listen on the specified port. Overrides any value in the config file") .withLongOpt("port").create("p"); + Option mport = + OptionBuilder.withArgName("mport").hasArg() + .withDescription("listen on the specified management port. Overrides any value in the config file") + .withLongOpt("mport").create("m"); + + Option bind = OptionBuilder.withArgName("bind").hasArg() .withDescription("bind to the specified address. Overrides any value in the config file") @@ -153,6 +162,7 @@ public class Main options.addOption(logconfig); options.addOption(logwatchconfig); options.addOption(port); + options.addOption(mport); options.addOption(bind); } @@ -203,15 +213,19 @@ public class Main catch (InitException e) { System.out.println(e.getMessage()); + _brokerLogger.error("Initialisation Error : " + e.getMessage()); + } catch (ConfigurationException e) { System.out.println("Error configuring message broker: " + e); + _brokerLogger.error("Error configuring message broker: " + e); e.printStackTrace(); } catch (Exception e) { System.out.println("Error intialising message broker: " + e); + _brokerLogger.error("Error intialising message broker: " + e); e.printStackTrace(); } } @@ -260,13 +274,21 @@ public class Main configureLogging(logConfigFile, logWatchConfig); } - ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile)); + ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile); + - // fixme .. use QpidProperties.getVersionString when we have fixed the classpath issues + updateManagementPort(config.getConfiguration(), commandLine.getOptionValue("m")); + + + + ApplicationRegistry.initialise(config); + + + //fixme .. use QpidProperties.getVersionString when we have fixed the classpath issues // that are causing the broker build to pick up the wrong properties file and hence say // Starting Qpid Client - _brokerLogger.info("Starting Qpid Broker " + QpidProperties.getReleaseVersion() + " build: " - + QpidProperties.getBuildVersion()); + _brokerLogger.info("Starting Qpid Broker " + QpidProperties.getReleaseVersion() + + " build: " + QpidProperties.getBuildVersion()); ConnectorConfiguration connectorConfig = ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class); @@ -316,6 +338,30 @@ public class Main } bind(port, connectorConfig); + + } + + /** + * Update the configuration data with the management port. + * @param configuration + * @param managementPort The string from the command line + */ + private void updateManagementPort(Configuration configuration, String managementPort) + { + if (managementPort != null) + { + int mport; + int defaultMPort = configuration.getInt(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH); + try + { + mport = Integer.parseInt(managementPort); + configuration.setProperty(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH, mport); + } + catch (NumberFormatException e) + { + _logger.warn("Invalid management port: " + managementPort + " will use default:" + defaultMPort, e); + } + } } protected void setupVirtualHosts(String configFileParent, String configFilePath) @@ -421,8 +467,8 @@ public class Main } // fixme qpid.AMQP should be using qpidproperties to get value - _brokerLogger.info("Qpid Broker Ready :" + QpidProperties.getReleaseVersion() + " build: " - + QpidProperties.getBuildVersion()); + _brokerLogger.info("Qpid Broker Ready :" + QpidProperties.getReleaseVersion() + + " build: " + QpidProperties.getBuildVersion()); } catch (Exception e) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java index e337b26b33..d1589092e9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java @@ -36,7 +36,7 @@ import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.exception.InternalErrorException; import org.apache.qpid.server.exception.QueueAlreadyExistsException; @@ -193,19 +193,22 @@ public class VirtualHostConfiguration if (queue.isDurable()) { - try - { - messageStore.createQueue(queue); - } catch (InternalErrorException e) - { - _logger.error("Problem when creating Queue '" + queueNameString - + "' on virtual host " + virtualHost.getName() + ", not creating."); - - } catch (QueueAlreadyExistsException e) - { - _logger.error("Queue '" + queueNameString - + "' already exists on virtual host " + virtualHost.getName() + ", not creating."); - } + + messageStore.createQueue(queue); + //DTX MessageStore +// try +// { +// messageStore.createQueue(queue); +// } catch (InternalErrorException e) +// { +// _logger.error("Problem when creating Queue '" + queueNameString +// + "' on virtual host " + virtualHost.getName() + ", not creating."); +// +// } catch (QueueAlreadyExistsException e) +// { +// _logger.error("Queue '" + queueNameString +// + "' already exists on virtual host " + virtualHost.getName() + ", not creating."); +// } } queueRegistry.registerQueue(queue); @@ -260,10 +263,7 @@ public class VirtualHostConfiguration } - public void performBindings() - throws - AMQException, - ConfigurationException + public void performBindings() throws AMQException, ConfigurationException { List virtualHostNames = _config.getList(VIRTUALHOST_PROPERTY_BASE + "name"); String defaultVirtualHostName = _config.getString("default"); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java index 246de230ec..0558906fb6 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java @@ -38,19 +38,20 @@ import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.management.ManagedObjectRegistry; import org.apache.qpid.server.queue.QueueRegistry; +import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.List; +import java.util.Map; + public abstract class AbstractExchange implements Exchange, Managable { private AMQShortString _name; - - protected boolean _durable; protected String _exchangeType; - private VirtualHost _virtualHost; protected ExchangeMBean _exchangeMbean; @@ -178,6 +179,8 @@ public abstract class AbstractExchange implements Exchange, Managable } } + abstract public Map<AMQShortString, List<AMQQueue>> getBindings(); + public String toString() { return getClass().getName() + "[" + getName() +"]"; diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java index f3bdecc32e..23a4bec6bd 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java @@ -20,17 +20,18 @@ */ package org.apache.qpid.server.exchange; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exception.InternalErrorException; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.protocol.ExchangeInitialiser; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.messageStore.MessageStore; -import org.apache.qpid.server.exception.InternalErrorException; + +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; public class DefaultExchangeRegistry implements ExchangeRegistry { @@ -66,13 +67,15 @@ public class DefaultExchangeRegistry implements ExchangeRegistry _exchangeMap.put(exchange.getName(), exchange); if(exchange.isDurable()) { - try - { getMessageStore().createExchange(exchange); - } catch (InternalErrorException e) - { - throw new AMQException(null, "problem registering excahgne " + exchange, e); - } + //DTX MessageStore +// try +// { +// getMessageStore().createExchange(exchange); +// } catch (InternalErrorException e) +// { +// throw new AMQException(null, "problem registering excahgne " + exchange, e); +// } } } @@ -86,21 +89,28 @@ public class DefaultExchangeRegistry implements ExchangeRegistry return _defaultExchange; } + public Collection<AMQShortString> getExchangeNames() + { + return _exchangeMap.keySet(); + } + public void unregisterExchange(AMQShortString name, boolean inUse) throws AMQException { // TODO: check inUse argument Exchange e = _exchangeMap.remove(name); if (e != null) { - if(e.isDurable()) + if (e.isDurable()) { - try - { - getMessageStore().removeExchange(e); - } catch (InternalErrorException e1) - { - throw new AMQException(null, "Problem unregistering Exchange " + name, e1); - } + getMessageStore().removeExchange(e); + //DTX MessageStore +// try +// { +// getMessageStore().removeExchange(e); +// } catch (InternalErrorException e1) +// { +// throw new AMQException(null, "Problem unregistering Exchange " + name, e1); +// } } e.close(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java index 6177980b92..d1cc9b892f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java @@ -20,28 +20,10 @@ */ package org.apache.qpid.server.exchange; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.management.JMException; -import javax.management.MBeanException; -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.management.MBeanConstructor; @@ -50,6 +32,17 @@ import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.virtualhost.VirtualHost; +import javax.management.JMException; +import javax.management.MBeanException; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + public class DestNameExchange extends AbstractExchange { private static final Logger _logger = Logger.getLogger(DestNameExchange.class); @@ -78,7 +71,7 @@ public class DestNameExchange extends AbstractExchange boolean autoDelete) throws AMQException { DestNameExchange exch = new DestNameExchange(); - exch.initialise(host,name,durable,autoDelete); + exch.initialise(host, name, durable, autoDelete); return exch; } }; @@ -90,7 +83,7 @@ public class DestNameExchange extends AbstractExchange private final class DestNameExchangeMBean extends ExchangeMBean { @MBeanConstructor("Creates an MBean for AMQ direct exchange") - public DestNameExchangeMBean() throws JMException + public DestNameExchangeMBean() throws JMException { super(); _exchangeType = "direct"; @@ -200,7 +193,7 @@ public class DestNameExchange extends AbstractExchange } else { - _logger.error("MESSAGE LOSS: Message should be sent on a Dead Letter Queue"); + _logger.error("MESSAGE LOSS: Message should be sent on a Dead Letter Queue"); _logger.warn(msg); } } @@ -218,19 +211,24 @@ public class DestNameExchange extends AbstractExchange } } - public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException + public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) + { + return isBound(routingKey, queue); + } + + public boolean isBound(AMQShortString routingKey, AMQQueue queue) { final List<AMQQueue> queues = _index.get(routingKey); return queues != null && queues.contains(queue); } - public boolean isBound(AMQShortString routingKey) throws AMQException + public boolean isBound(AMQShortString routingKey) { final List<AMQQueue> queues = _index.get(routingKey); return queues != null && !queues.isEmpty(); } - public boolean isBound(AMQQueue queue) throws AMQException + public boolean isBound(AMQQueue queue) { Map<AMQShortString, List<AMQQueue>> bindings = _index.getBindingsMap(); for (List<AMQQueue> queues : bindings.values()) @@ -243,8 +241,13 @@ public class DestNameExchange extends AbstractExchange return false; } - public boolean hasBindings() throws AMQException + public boolean hasBindings() { return !_index.getBindingsMap().isEmpty(); } + + public Map<AMQShortString, List<AMQQueue>> getBindings() + { + return _index.getBindingsMap(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java index 20f0517789..25dc32fd41 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java @@ -21,11 +21,9 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; - import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.management.MBeanConstructor; @@ -36,17 +34,11 @@ import org.apache.qpid.server.virtualhost.VirtualHost; import javax.management.JMException; import javax.management.MBeanException; -import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; - import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -77,7 +69,7 @@ public class DestWildExchange extends AbstractExchange boolean autoDelete) throws AMQException { DestWildExchange exch = new DestWildExchange(); - exch.initialise(host,name,durable,autoDelete); + exch.initialise(host, name, durable, autoDelete); return exch; } }; @@ -86,7 +78,7 @@ public class DestWildExchange extends AbstractExchange private static final Logger _logger = Logger.getLogger(DestWildExchange.class); private ConcurrentHashMap<AMQShortString, List<AMQQueue>> _routingKey2queues = - new ConcurrentHashMap<AMQShortString, List<AMQQueue>>(); + new ConcurrentHashMap<AMQShortString, List<AMQQueue>>(); // private ConcurrentHashMap<AMQShortString, AMQQueue> _routingKey2queue = new ConcurrentHashMap<AMQShortString, AMQQueue>(); private static final String TOPIC_SEPARATOR = "."; private static final String AMQP_STAR = "*"; @@ -119,7 +111,7 @@ public class DestWildExchange extends AbstractExchange queueList.add(q.getName().toString()); } - Object[] bindingItemValues = { key.toString(), queueList.toArray(new String[0]) }; + Object[] bindingItemValues = {key.toString(), queueList.toArray(new String[0])}; CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues); _bindingList.put(bindingData); } @@ -265,21 +257,26 @@ public class DestWildExchange extends AbstractExchange } } - public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException + public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) + { + return isBound(routingKey, queue); + } + + public boolean isBound(AMQShortString routingKey, AMQQueue queue) { List<AMQQueue> queues = _routingKey2queues.get(normalize(routingKey)); return (queues != null) && queues.contains(queue); } - public boolean isBound(AMQShortString routingKey) throws AMQException + public boolean isBound(AMQShortString routingKey) { List<AMQQueue> queues = _routingKey2queues.get(normalize(routingKey)); return (queues != null) && !queues.isEmpty(); } - public boolean isBound(AMQQueue queue) throws AMQException + public boolean isBound(AMQQueue queue) { for (List<AMQQueue> queues : _routingKey2queues.values()) { @@ -292,7 +289,7 @@ public class DestWildExchange extends AbstractExchange return false; } - public boolean hasBindings() throws AMQException + public boolean hasBindings() { return !_routingKey2queues.isEmpty(); } @@ -338,6 +335,11 @@ public class DestWildExchange extends AbstractExchange } } + public Map<AMQShortString, List<AMQQueue>> getBindings() + { + return _routingKey2queues; + } + private List<AMQQueue> getMatchedQueues(AMQShortString routingKey) { List<AMQQueue> list = new LinkedList<AMQQueue>(); @@ -385,8 +387,8 @@ public class DestWildExchange extends AbstractExchange if (queueList.size() > (depth + queueskip)) { // a hash and it is the last entry matching = - queueList.get(depth + queueskip).equals(AMQP_HASH) - && (queueList.size() == (depth + queueskip + 1)); + queueList.get(depth + queueskip).equals(AMQP_HASH) + && (queueList.size() == (depth + queueskip + 1)); } } else if (routingkeyList.size() > (depth + routingskip)) diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java index 03b264f8fa..78749de612 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java @@ -27,12 +27,15 @@ import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.List; +import java.util.Map; + public interface Exchange { AMQShortString getName(); AMQShortString getType(); - + void initialise(VirtualHost host, AMQShortString name, boolean durable, boolean autoDelete) throws AMQException; boolean isDurable(); @@ -49,6 +52,17 @@ public interface Exchange void route(AMQMessage message) throws AMQException; + + /** + * Determines whether a message would be isBound to a particular queue using a specific routing key and arguments + * @param routingKey + * @param arguments + * @param queue + * @return + * @throws AMQException + */ + boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue); + /** * Determines whether a message would be isBound to a particular queue using a specific routing key * @param routingKey @@ -56,7 +70,7 @@ public interface Exchange * @return * @throws AMQException */ - boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException; + boolean isBound(AMQShortString routingKey, AMQQueue queue); /** * Determines whether a message is routing to any queue using a specific routing key @@ -64,14 +78,17 @@ public interface Exchange * @return * @throws AMQException */ - boolean isBound(AMQShortString routingKey) throws AMQException; + boolean isBound(AMQShortString routingKey); - boolean isBound(AMQQueue queue) throws AMQException; + boolean isBound(AMQQueue queue); /** * Returns true if this exchange has at least one binding associated with it. * @return * @throws AMQException */ - boolean hasBindings() throws AMQException; + boolean hasBindings(); + + Map<AMQShortString, List<AMQQueue>> getBindings(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java index 0003b8302f..2e101beb84 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java @@ -20,11 +20,10 @@ */ package org.apache.qpid.server.exchange; -import org.apache.commons.configuration.Configuration; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import java.util.Collection; public interface ExchangeRegistry extends MessageRouter { @@ -45,5 +44,7 @@ public interface ExchangeRegistry extends MessageRouter Exchange getDefaultExchange(); + Collection<AMQShortString> getExchangeNames(); + void initialise() throws AMQException; } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java index 8895539538..77590ea54d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java @@ -21,7 +21,6 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -35,17 +34,13 @@ import org.apache.qpid.server.virtualhost.VirtualHost; import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
public class FanoutExchange extends AbstractExchange
@@ -56,28 +51,28 @@ public class FanoutExchange extends AbstractExchange public static final ExchangeType<FanoutExchange> TYPE = new ExchangeType<FanoutExchange>()
- {
+ {
- public AMQShortString getName()
- {
- return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
- }
+ public AMQShortString getName()
+ {
+ return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
+ }
- public Class<FanoutExchange> getExchangeClass()
- {
- return FanoutExchange.class;
- }
+ public Class<FanoutExchange> getExchangeClass()
+ {
+ return FanoutExchange.class;
+ }
- public FanoutExchange newInstance(VirtualHost host,
- AMQShortString name,
- boolean durable,
- boolean autoDelete) throws AMQException
- {
- FanoutExchange exch = new FanoutExchange();
- exch.initialise(host,name,durable,autoDelete);
- return exch;
- }
- };
+ public FanoutExchange newInstance(VirtualHost host,
+ AMQShortString name,
+ boolean durable,
+ boolean autoDelete) throws AMQException
+ {
+ FanoutExchange exch = new FanoutExchange();
+ exch.initialise(host, name, durable, autoDelete);
+ return exch;
+ }
+ };
/**
@@ -108,7 +103,7 @@ public class FanoutExchange extends AbstractExchange {
String queueName = queue.getName().toString();
- Object[] bindingItemValues = { queueName, new String[] { queueName } };
+ Object[] bindingItemValues = {queueName, new String[]{queueName}};
CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
_bindingList.put(bindingData);
}
@@ -149,6 +144,11 @@ public class FanoutExchange extends AbstractExchange }
}
+ public Map<AMQShortString, List<AMQQueue>> getBindings()
+ {
+ return null;
+ }
+
public AMQShortString getType()
{
return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
@@ -210,24 +210,29 @@ public class FanoutExchange extends AbstractExchange }
}
- public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException
+ public boolean isBound(AMQShortString routingKey, FieldTable fieldtable, AMQQueue queue)
+ {
+ return isBound(routingKey, queue);
+ }
+
+ public boolean isBound(AMQShortString routingKey, AMQQueue queue)
{
return _queues.contains(queue);
}
- public boolean isBound(AMQShortString routingKey) throws AMQException
+ public boolean isBound(AMQShortString routingKey)
{
return (_queues != null) && !_queues.isEmpty();
}
- public boolean isBound(AMQQueue queue) throws AMQException
+ public boolean isBound(AMQQueue queue)
{
return _queues.contains(queue);
}
- public boolean hasBindings() throws AMQException
+ public boolean hasBindings()
{
return !_queues.isEmpty();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java index bed08daeaf..426cd090c1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java @@ -20,23 +20,6 @@ */ package org.apache.qpid.server.exchange; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.management.JMException; -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; -import javax.management.openmbean.TabularType; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; @@ -51,6 +34,23 @@ import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.virtualhost.VirtualHost; +import javax.management.JMException; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + /** * An exchange that binds queues based on a set of required headers and header values * and routes messages to these queues by matching the headers of the message against @@ -83,30 +83,29 @@ public class HeadersExchange extends AbstractExchange private static final Logger _logger = Logger.getLogger(HeadersExchange.class); - public static final ExchangeType<HeadersExchange> TYPE = new ExchangeType<HeadersExchange>() - { + { - public AMQShortString getName() - { - return ExchangeDefaults.HEADERS_EXCHANGE_CLASS; - } + public AMQShortString getName() + { + return ExchangeDefaults.HEADERS_EXCHANGE_CLASS; + } - public Class<HeadersExchange> getExchangeClass() - { - return HeadersExchange.class; - } + public Class<HeadersExchange> getExchangeClass() + { + return HeadersExchange.class; + } - public HeadersExchange newInstance(VirtualHost host, - AMQShortString name, - boolean durable, - boolean autoDelete) throws AMQException - { - HeadersExchange exch = new HeadersExchange(); - exch.initialise(host,name,durable,autoDelete); - return exch; - } - }; + public HeadersExchange newInstance(VirtualHost host, + AMQShortString name, + boolean durable, + boolean autoDelete) throws AMQException + { + HeadersExchange exch = new HeadersExchange(); + exch.initialise(host, name, durable, autoDelete); + return exch; + } + }; private final List<Registration> _bindings = new CopyOnWriteArrayList<Registration>(); @@ -119,13 +118,13 @@ public class HeadersExchange extends AbstractExchange private final class HeadersExchangeMBean extends ExchangeMBean { @MBeanConstructor("Creates an MBean for AMQ Headers exchange") - public HeadersExchangeMBean() throws JMException + public HeadersExchangeMBean() throws JMException { super(); _exchangeType = "headers"; init(); } - + /** * initialises the OpenType objects. */ @@ -141,7 +140,7 @@ public class HeadersExchange extends AbstractExchange _bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings", _bindingItemNames, _bindingItemNames, _bindingItemTypes); _bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(), - _bindingDataType, _bindingItemIndexNames); + _bindingDataType, _bindingItemIndexNames); } public TabularData bindings() throws OpenDataException @@ -197,7 +196,7 @@ public class HeadersExchange extends AbstractExchange throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange."); } - String[] bindings = binding.split(","); + String[] bindings = binding.split(","); FieldTable bindingMap = new FieldTable(); for (int i = 0; i < bindings.length; i++) { @@ -269,17 +268,23 @@ public class HeadersExchange extends AbstractExchange } } - public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException + public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) + { + //fixme isBound here should take the arguements in to consideration. + return isBound(routingKey, queue); + } + + public boolean isBound(AMQShortString routingKey, AMQQueue queue) { return isBound(queue); } - public boolean isBound(AMQShortString routingKey) throws AMQException + public boolean isBound(AMQShortString routingKey) { return hasBindings(); } - public boolean isBound(AMQQueue queue) throws AMQException + public boolean isBound(AMQQueue queue) { for (Registration r : _bindings) { @@ -291,7 +296,7 @@ public class HeadersExchange extends AbstractExchange return false; } - public boolean hasBindings() throws AMQException + public boolean hasBindings() { return !_bindings.isEmpty(); } @@ -316,6 +321,11 @@ public class HeadersExchange extends AbstractExchange } } + public Map<AMQShortString, List<AMQQueue>> getBindings() + { + return null; + } + private static class Registration { private final HeadersBinding binding; diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java index 9346eecbb2..ab4f2c4e64 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java @@ -100,6 +100,12 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic } else { + + if (body.consumerTag != null) + { + body.consumerTag = body.consumerTag.intern(); + } + try { AMQShortString consumerTag = channel.subscribeToQueue(body.consumerTag, queue, session, !body.noAck, @@ -138,15 +144,15 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic // If the above doesn't work then perhaps this is wrong too. // throw body.getConnectionException(AMQConstant.NOT_ALLOWED, // "Non-unique consumer tag, '" + body.consumerTag + "'"); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) + // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. session.writeFrame(ConnectionCloseBody.createAMQFrame(channelId, - (byte)8, (byte)0, // AMQP version (major, minor) - BasicConsumeBody.getClazz((byte)8, (byte)0), // classId - BasicConsumeBody.getMethod((byte)8, (byte)0), // methodId - AMQConstant.NOT_ALLOWED.getCode(), // replyCode - msg)); // replyText + (byte) 8, (byte) 0, // AMQP version (major, minor) + BasicConsumeBody.getClazz((byte) 8, (byte) 0), // classId + BasicConsumeBody.getMethod((byte) 8, (byte) 0), // methodId + AMQConstant.NOT_ALLOWED.getCode(), // replyCode + msg)); // replyText } catch (ExistingExclusiveSubscriptionException e) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java index 67ade0a744..541d2afaf4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java @@ -67,6 +67,10 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi body.exchange = ExchangeDefaults.DEFAULT_EXCHANGE_NAME; } + else + { + body.exchange = body.exchange.intern(); + } VirtualHost vHost = session.getVirtualHost(); Exchange e = vHost.getExchangeRegistry().getExchange(body.exchange); // if the exchange does not exist we raise a channel exception @@ -86,6 +90,11 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi throw body.getChannelNotFoundException(evt.getChannelId()); } + if(body.routingKey != null) + { + body.routingKey = body.routingKey.intern(); + } + MessagePublishInfo info = session.getRegistry().getProtocolVersionMethodConverter().convertToInfo(body); channel.setPublishFrame(info, session); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java index 9052b2e81f..32c840106f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java @@ -20,16 +20,15 @@ */ package org.apache.qpid.server.handler; +import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicRejectBody; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.ack.UnacknowledgedMessage; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.log4j.Logger; public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicRejectBody> { @@ -71,7 +70,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR { _logger.debug("Rejecting:" + evt.getMethod().deliveryTag + ": Requeue:" + evt.getMethod().requeue + -// ": Resend:" + evt.getMethod().resend + + //": Resend:" + evt.getMethod().resend + " on channel:" + channel.debugIdentity()); } @@ -91,7 +90,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR { _logger.trace("Rejecting: DT:" + deliveryTag + "-" + message.message.debugIdentity() + ": Requeue:" + evt.getMethod().requeue + -// ": Resend:" + evt.getMethod().resend + + //": Resend:" + evt.getMethod().resend + " on channel:" + channel.debugIdentity()); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java index f24c96f87f..0ff19bdf9e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.handler; diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java index 855d1a2add..f0f6fde08c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java @@ -83,7 +83,9 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange try { - exchange = exchangeFactory.createExchange(body.exchange, body.type, body.durable, + exchange = exchangeFactory.createExchange(body.exchange == null ? null : body.exchange.intern(), + body.type == null ? null : body.type.intern(), + body.durable, body.passive, body.ticket); exchangeRegistry.registerExchange(exchange); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java index 4dc67b1970..3e68069838 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java @@ -28,6 +28,7 @@ import org.apache.qpid.framing.QueueBindBody; import org.apache.qpid.framing.QueueBindOkBody; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -36,7 +37,6 @@ import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.AMQChannel; public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody> { @@ -77,7 +77,7 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody> { throw body.getChannelException(AMQConstant.NOT_FOUND, "No default queue defined on channel and queue was null"); } - + if (body.routingKey == null) { body.routingKey = queue.getName(); @@ -97,9 +97,18 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody> { throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.exchange + " does not exist."); } + + if (body.routingKey != null) + { + body.routingKey = body.routingKey.intern(); + } + try - { - queue.bind(body.routingKey, body.arguments, exch); + { + if (!exch.isBound(body.routingKey, body.arguments, queue)) + { + queue.bind(body.routingKey, body.arguments, exch); + } } catch (AMQInvalidRoutingKeyException rke) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index f9e94af697..9be0dabb68 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -42,11 +42,9 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.exception.InternalErrorException; -import org.apache.qpid.server.exception.QueueAlreadyExistsException; import org.apache.commons.configuration.Configuration; public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclareBody> @@ -95,6 +93,11 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar if (((queue = queueRegistry.getQueue(body.queue)) == null)) { + if(body.queue != null) + { + body.queue = body.queue.intern(); + } + if (body.passive) { String msg = "Queue: " + body.queue + " not found on VirtualHost(" + virtualHost + ")."; @@ -105,13 +108,14 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar queue = createQueue(body, virtualHost, session); if (queue.isDurable() && !queue.isAutoDelete()) { - try - { + //DTX MessageStore +// try +// { store.createQueue(queue); - } catch (Exception e) - { - throw new AMQException(null, "Problem when creating queue " + queue, e); - } +// } catch (Exception e) +// { +// throw new AMQException(null, "Problem when creating queue " + queue, e); +// } } queueRegistry.registerQueue(queue); if (autoRegister) diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java index eb89bf78e5..edeb6f1f48 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java @@ -30,7 +30,7 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.exception.InternalErrorException; @@ -111,7 +111,9 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB { try { - store.destroyQueue(queue); + //DTX MessageStore +// store.destroyQueue(queue); + store.removeQueue(queue.getName()); } catch (Exception e) { throw new AMQException(null, "problem when destroying queue " + queue, e); diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java index f277398b50..9dce752021 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java @@ -20,14 +20,14 @@ */ package org.apache.qpid.server.management; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.UnicastRemoteObject; -import java.util.HashMap; -import java.util.Map; +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; +import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser; import javax.management.JMException; import javax.management.MBeanServer; @@ -43,17 +43,14 @@ import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.AccountNotFoundException; import javax.security.sasl.AuthorizeCallback; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; -import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; -import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; +import java.util.HashMap; +import java.util.Map; /** * This class starts up an MBeanserver. If out of the box agent is being used then there are no security features @@ -69,6 +66,9 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry private Registry _rmiRegistry; private JMXServiceURL _jmxURL; + public static final String MANAGEMENT_PORT_CONFIG_PATH = "management.jmxport"; + public static final int MANAGEMENT_PORT_DEFAULT = 8999; + public JMXManagedObjectRegistry() throws AMQException { _log.info("Initialising managed object registry using platform MBean server"); @@ -95,7 +95,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry IApplicationRegistry appRegistry = ApplicationRegistry.getInstance(); boolean security = appRegistry.getConfiguration().getBoolean("management.security-enabled", false); - int port = appRegistry.getConfiguration().getInt("management.jmxport", 8999); + int port = appRegistry.getConfiguration().getInt(MANAGEMENT_PORT_CONFIG_PATH, MANAGEMENT_PORT_DEFAULT); if (security) { @@ -144,13 +144,13 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance(); cs.setMBeanServerForwarder(mbsf); cs.start(); - _log.warn("JMX: Started JMXConnector server with SASL"); + _log.warn("JMX: Started JMXConnector server on port '" + port + "' with SASL"); } else { startJMXConnectorServer(port); - _log.warn("JMX: Started JMXConnector server with security disabled"); + _log.warn("JMX: Started JMXConnector server on port '" + port + "' with security disabled"); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java index 3ab23e8b46..4fb260472d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.management; diff --git a/java/broker/src/main/java/org/apache/qpid/server/messageStore/JDBCStore.java b/java/broker/src/main/java/org/apache/qpid/server/messageStore/JDBCStore.java index e2d07c1c10..8c13473488 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/messageStore/JDBCStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/messageStore/JDBCStore.java @@ -17,29 +17,50 @@ */ package org.apache.qpid.server.messageStore; +import org.apache.commons.configuration.Configuration; +import org.apache.log4j.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.server.exception.InternalErrorException; +import org.apache.qpid.server.exception.InvalidXidException; +import org.apache.qpid.server.exception.MessageAlreadyStagedException; +import org.apache.qpid.server.exception.MessageDoesntExistException; +import org.apache.qpid.server.exception.QueueAlreadyExistsException; +import org.apache.qpid.server.exception.QueueDoesntExistException; +import org.apache.qpid.server.exception.UnknownXidException; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exception.*; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.txn.*; -import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MessageHandleFactory; import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.AMQException; -import org.apache.commons.configuration.Configuration; -import org.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.server.txn.JDBCAbstractRecord; +import org.apache.qpid.server.txn.JDBCDequeueRecord; +import org.apache.qpid.server.txn.JDBCEnqueueRecord; +import org.apache.qpid.server.txn.JDBCTransaction; +import org.apache.qpid.server.txn.JDBCTransactionManager; +import org.apache.qpid.server.txn.Transaction; +import org.apache.qpid.server.txn.TransactionManager; +import org.apache.qpid.server.txn.TransactionRecord; +import org.apache.qpid.server.txn.TransactionalContext; +import org.apache.qpid.server.txn.XidImpl; +import org.apache.qpid.server.virtualhost.VirtualHost; import javax.transaction.xa.Xid; -import java.util.Collection; -import java.util.List; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; -import java.sql.*; +import java.util.List; /** * Created by Arnaud Simon @@ -173,16 +194,18 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameExchange + - " (Name,Type) VALUES (?,?)"); + " (Name,Type) VALUES (?,?)"); connection.getStatements()[CREATE_EXCHANGE] = pstmt; } pstmt.setString(1, exchange.getName().asString()); pstmt.setString(2, exchange.getType().asString()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot create Exchange: " + exchange, e); - } finally + } + finally { if (connection != null) { @@ -190,7 +213,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -216,15 +240,17 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameExchange + - " WHERE Name = ?"); + " WHERE Name = ?"); connection.getStatements()[DELETE_EXCHANGE] = pstmt; } pstmt.setString(1, exchange.getName().asString()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot remove Exchange: " + exchange, e); - } finally + } + finally { if (connection != null) { @@ -232,7 +258,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -258,7 +285,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameExchangeQueueRelation + - " (QueueID,Name,RoutingKey,fieldTable) VALUES (?,?,?,?)"); + " (QueueID,Name,RoutingKey,fieldTable) VALUES (?,?,?,?)"); connection.getStatements()[BIND_QUEUE] = pstmt; } pstmt.setInt(1, queue.getQueueID()); @@ -267,15 +294,18 @@ public class JDBCStore implements MessageStore if (args != null) { pstmt.setBytes(4, args.getDataAsBytes()); - } else + } + else { pstmt.setBytes(4, null); } pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot create Exchange: " + exchange, e); - } finally + } + finally { if (connection != null) { @@ -283,7 +313,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -307,17 +338,19 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameExchangeQueueRelation + - " WHERE QueueID = ? AND NAME = ? AND RoutingKey = ?"); + " WHERE QueueID = ? AND NAME = ? AND RoutingKey = ?"); connection.getStatements()[UNBIND_QUEUE] = pstmt; } pstmt.setInt(1, queue.getQueueID()); pstmt.setString(2, exchange.getName().asString()); pstmt.setString(3, routingKey.asString()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot remove Exchange: " + exchange, e); - } finally + } + finally { if (connection != null) { @@ -325,7 +358,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -349,7 +383,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameQueue + - " (QueueID,Name,Owner) VALUES (?,?,?)"); + " (QueueID,Name,Owner) VALUES (?,?,?)"); connection.getStatements()[CREATE_QUEUE] = pstmt; } pstmt.setInt(1, queue.getQueueID()); @@ -357,15 +391,18 @@ public class JDBCStore implements MessageStore if (queue.getOwner() != null) { pstmt.setString(3, queue.getOwner().asString()); - } else + } + else { pstmt.setString(3, null); } pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot create Queue: " + queue, e); - } finally + } + finally { if (connection != null) { @@ -373,7 +410,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -397,15 +435,17 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameQueue + - " WHERE QueueID = ?"); + " WHERE QueueID = ?"); connection.getStatements()[DELETE_QUEUE] = pstmt; } pstmt.setInt(1, queue.getQueueID()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot remove Queue: " + queue, e); - } finally + } + finally { if (connection != null) { @@ -413,7 +453,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -439,10 +480,12 @@ public class JDBCStore implements MessageStore { connection = (MyConnection) _connectionPool.acquireInstance(); stage(connection, m); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot stage Message: " + m, e); - } finally + } + finally { if (connection != null) { @@ -450,7 +493,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -470,19 +514,21 @@ public class JDBCStore implements MessageStore if (!m.isStaged()) { _log.error("Cannot append content of message Id " - + m.getMessageId() + " as it has not been staged"); + + m.getMessageId() + " as it has not been staged"); throw new MessageDoesntExistException("Cannot append content of message Id " - + m.getMessageId() + " as it has not been staged"); + + m.getMessageId() + " as it has not been staged"); } MyConnection connection = null; try { connection = (MyConnection) _connectionPool.acquireInstance(); appendContent(connection, m, data, offset, size); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot stage Message: " + m, e); - } finally + } + finally { if (connection != null) { @@ -490,7 +536,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -515,7 +562,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("SELECT Payload FROM " + _tableNameMessage + - " WHERE MessageID = ? "); + " WHERE MessageID = ? "); connection.getStatements()[SELECT_MESSAGE_PAYLOAD] = pstmt; } pstmt.setLong(1, m.getMessageId()); @@ -523,7 +570,7 @@ public class JDBCStore implements MessageStore if (!rs.next()) { throw new MessageDoesntExistException("Cannot load content of message Id " - + m.getMessageId() + " as it has not been found"); + + m.getMessageId() + " as it has not been found"); } Blob myBlob = rs.getBlob(1); @@ -532,21 +579,25 @@ public class JDBCStore implements MessageStore if (size == 0) { result = myBlob.getBytes(offset, (int) myBlob.length()); - } else + } + else { result = myBlob.getBytes(offset, size); } - } else + } + else { throw new MessageDoesntExistException("Cannot load content of message Id " - + m.getMessageId() + " as it has not been found"); + + m.getMessageId() + " as it has not been found"); } rs.close(); return result; - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot load Message: " + m, e); - } finally + } + finally { if (connection != null) { @@ -554,7 +605,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -575,10 +627,12 @@ public class JDBCStore implements MessageStore { connection = (MyConnection) _connectionPool.acquireInstance(); destroy(connection, m); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot destroy message: " + m, e); - } finally + } + finally { if (connection != null) { @@ -586,7 +640,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -613,14 +668,16 @@ public class JDBCStore implements MessageStore { // add an enqueue record tx.addRecord(new JDBCEnqueueRecord(m, queue)); - } else + } + else { try { if (tx != null) { connection = tx.getConnection(); - } else + } + else { connection = (MyConnection) _connectionPool.acquireInstance(); } @@ -634,7 +691,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameQueueMessageRelation + - " (QueueID,MessageID,Prepared) VALUES (?,?,0)"); + " (QueueID,MessageID,Prepared) VALUES (?,?,0)"); connection.getStatements()[ENQUEUE] = pstmt; } pstmt.setInt(1, queue.getQueueID()); @@ -642,10 +699,12 @@ public class JDBCStore implements MessageStore pstmt.executeUpdate(); m.enqueue(queue); queue.enqueue(m); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot enqueue message : " + m + " in queue: " + queue, e); - } finally + } + finally { if (tx == null && connection != null) { @@ -653,7 +712,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -680,14 +740,16 @@ public class JDBCStore implements MessageStore { // add an dequeue record tx.addRecord(new JDBCDequeueRecord(m, queue)); - } else + } + else { try { if (tx != null) { connection = tx.getConnection(); - } else + } + else { connection = (MyConnection) _connectionPool.acquireInstance(); } @@ -695,7 +757,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameQueueMessageRelation + - " WHERE QueueID = ? AND MessageID = ?"); + " WHERE QueueID = ? AND MessageID = ?"); connection.getStatements()[DEQUEUE] = pstmt; } pstmt.setInt(1, queue.getQueueID()); @@ -708,10 +770,12 @@ public class JDBCStore implements MessageStore destroy(connection, m); } queue.dequeue(m); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot enqueue message : " + m + " in queue: " + queue, e); - } finally + } + finally { if (tx == null && connection != null) { @@ -719,7 +783,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -756,14 +821,16 @@ public class JDBCStore implements MessageStore queueOwner = new AMQShortString(rs.getString(3)); } result.add(new AMQQueue(new AMQShortString(rs.getString(2)), true, queueOwner, - false, _virtualHost)); + false, _virtualHost)); } rs.close(); return result; - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot get all queues", e); - } finally + } + finally { if (connection != null) { @@ -771,7 +838,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -791,10 +859,12 @@ public class JDBCStore implements MessageStore { connection = (MyConnection) _connectionPool.acquireInstance(); return getAllMessages(connection, queue); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot get all queues", e); - } finally + } + finally { if (connection != null) { @@ -802,7 +872,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -821,7 +892,7 @@ public class JDBCStore implements MessageStore HashMap<Xid, Transaction> result = new HashMap<Xid, Transaction>(); try { - TransactionalContext txnContext = new NonTransactionalContext(this, new StoreContext(), null, null, null); + //TransactionalContext txnContext = new NonTransactionalContext(this, new StoreContext(), null, null, null); MessageHandleFactory messageHandleFactory = new MessageHandleFactory(); // re-create all the tx connection = (MyConnection) _connectionPool.acquireInstance(); @@ -840,11 +911,11 @@ public class JDBCStore implements MessageStore } foundTx = new JDBCTransaction(); foundXid = new XidImpl(rs.getBlob(3).getBytes(1, (int) rs.getBlob(3).length()), - rs.getInt(2), rs.getBlob(4).getBytes(1, (int) rs.getBlob(4).length())); + rs.getInt(2), rs.getBlob(4).getBytes(1, (int) rs.getBlob(4).length())); // get all the records Statement stmtr = connection.getConnection().createStatement(); ResultSet rsr = stmtr.executeQuery("SELECT * FROM " + _tableNameRecord + - " WHERE XID_ID = " + rs.getLong(1)); + " WHERE XID_ID = " + rs.getLong(1)); int foundType; AMQQueue foundQueue; StorableMessage foundMessage; @@ -854,11 +925,14 @@ public class JDBCStore implements MessageStore // those messages were not recovered before so they need to be recreated foundType = rsr.getInt(2); foundQueue = _queueMap.get(new Integer(rsr.getInt(4))); - foundMessage = new AMQMessage(rs.getLong(3), this, messageHandleFactory, txnContext); + + //DTX MessageStore - this -> null , txContext -> null + foundMessage = new AMQMessage(rs.getLong(3), null, messageHandleFactory, null); if (foundType == JDBCAbstractRecord.TYPE_DEQUEUE) { foundRecord = new JDBCDequeueRecord(foundMessage, foundQueue); - } else + } + else { foundRecord = new JDBCEnqueueRecord(foundMessage, foundQueue); } @@ -870,10 +944,12 @@ public class JDBCStore implements MessageStore } rs.close(); return result; - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot recover: ", e); - } finally + } + finally { if (connection != null) { @@ -881,7 +957,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -917,7 +994,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -934,7 +1012,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().rollback(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to rollback this connection // it is better to release it @@ -952,7 +1031,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("SELECT Payload FROM " + _tableNameMessage + - " WHERE MessageID = ? "); + " WHERE MessageID = ? "); connection.getStatements()[SELECT_MESSAGE_PAYLOAD] = pstmt; } pstmt.setLong(1, m.getMessageId()); @@ -960,14 +1039,15 @@ public class JDBCStore implements MessageStore if (!rs.next()) { throw new MessageDoesntExistException("Cannot append content of message Id " - + m.getMessageId() + " as it has not been found"); + + m.getMessageId() + " as it has not been found"); } Blob myBlob = rs.getBlob(1); byte[] oldPayload; if (myBlob != null && myBlob.length() > 0) { oldPayload = myBlob.getBytes(1, (int) myBlob.length()); - } else + } + else { oldPayload = new byte[0]; } @@ -980,7 +1060,7 @@ public class JDBCStore implements MessageStore if (pstmtUpdate == null) { pstmtUpdate = connection.getConnection().prepareStatement("UPDATE " + _tableNameMessage + - " SET Payload = ? WHERE MessageID = ?"); + " SET Payload = ? WHERE MessageID = ?"); connection.getStatements()[UPDATE_MESSAGE_PAYLOAD] = pstmtUpdate; } pstmtUpdate.setBytes(1, newPayload); @@ -996,7 +1076,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameMessage + - " (MessageID,Header,ExchangeName,RoutingKey,Mandatory,Is_Immediate) VALUES (?,?,?,?,?,?)"); + " (MessageID,Header,ExchangeName,RoutingKey,Mandatory,Is_Immediate) VALUES (?,?,?,?,?,?)"); connection.getStatements()[STAGE_MESSAGE] = pstmt; } pstmt.setLong(1, m.getMessageId()); @@ -1019,7 +1099,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameRecord + - " (XID_ID,Type,MessageID,QueueID) VALUES (?,?,?,?)"); + " (XID_ID,Type,MessageID,QueueID) VALUES (?,?,?,?)"); connection.getStatements()[SAVE_RECORD] = pstmt; } pstmt.setLong(1, tx.getXidID()); @@ -1027,7 +1107,8 @@ public class JDBCStore implements MessageStore pstmt.setLong(3, record.getMessageID()); pstmt.setLong(4, record.getQueueID()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot save record: " + record, e); } @@ -1043,7 +1124,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("INSERT INTO " + _tableNameTransaction + - " (XID_ID,FormatId, BranchQualifier,GlobalTransactionId) VALUES (?,?,?,?)"); + " (XID_ID,FormatId, BranchQualifier,GlobalTransactionId) VALUES (?,?,?,?)"); connection.getStatements()[SAVE_XID] = pstmt; } pstmt.setLong(1, tx.getXidID()); @@ -1051,7 +1132,8 @@ public class JDBCStore implements MessageStore pstmt.setBytes(3, xid.getBranchQualifier()); pstmt.setBytes(4, xid.getGlobalTransactionId()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot save xid: " + xid, e); } @@ -1067,12 +1149,13 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameRecord + - " WHERE XID_ID = ?"); + " WHERE XID_ID = ?"); connection.getStatements()[DELETE_RECORD] = pstmt; } pstmt.setLong(1, tx.getXidID()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot delete record: " + tx.getXidID(), e); } @@ -1088,12 +1171,13 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameTransaction + - " WHERE XID_ID = ?"); + " WHERE XID_ID = ?"); connection.getStatements()[DELETE_XID] = pstmt; } pstmt.setLong(1, tx.getXidID()); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot delete xid: " + tx.getXidID(), e); } @@ -1142,14 +1226,15 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("UPDATE " + _tableNameQueueMessageRelation + - " SET Prepared = ? WHERE MessageID = ? AND QueueID = ?"); + " SET Prepared = ? WHERE MessageID = ? AND QueueID = ?"); connection.getStatements()[UPDATE_QMR] = pstmt; } pstmt.setInt(1, prepared); pstmt.setLong(2, messageId); pstmt.setInt(3, queueID); pstmt.executeUpdate(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot update QMR", e); } @@ -1169,8 +1254,8 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("SELECT ExchangeName, RoutingKey," + - " Mandatory, Is_Immediate from " + _tableNameMessage + - " WHERE MessageID = ?"); + " Mandatory, Is_Immediate from " + _tableNameMessage + + " WHERE MessageID = ?"); connection.getStatements()[GET_MESSAGE_INFO] = pstmt; } pstmt.setLong(1, m.getMessageId()); @@ -1204,16 +1289,19 @@ public class JDBCStore implements MessageStore return routingKey; } }; - } else + } + else { throw new InternalErrorException("Cannot get MessagePublishInfo of message: " + m); } rs.close(); return result; - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot get MessagePublishInfo of message: " + m, e); - } finally + } + finally { if (connection != null) { @@ -1221,7 +1309,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -1245,7 +1334,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("SELECT Header from " + _tableNameMessage + - " WHERE MessageID = ?"); + " WHERE MessageID = ?"); connection.getStatements()[GET_CONTENT_HEADER] = pstmt; } pstmt.setLong(1, m.getMessageId()); @@ -1253,16 +1342,19 @@ public class JDBCStore implements MessageStore if (rs.next()) { result = new ContentHeaderBody(ByteBuffer.wrap(rs.getBlob(1).getBytes(1, (int) rs.getBlob(1).length())), 0); - } else + } + else { throw new InternalErrorException("Cannot get Content Header of message: " + m); } rs.close(); return result; - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot get Content Header of message: " + m, e); - } finally + } + finally { if (connection != null) { @@ -1270,7 +1362,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -1287,21 +1380,21 @@ public class JDBCStore implements MessageStore AMQException { List<StorableMessage> result = new ArrayList<StorableMessage>(); - TransactionalContext txnContext = new NonTransactionalContext(this, new StoreContext(), null, null, null); +// TransactionalContext txnContext = new NonTransactionalContext(this, new StoreContext(), null, null, null); MessageHandleFactory messageHandleFactory = new MessageHandleFactory(); PreparedStatement pstmt = connection.getStatements()[GET_ALL_MESSAGES]; if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("SELECT " + _tableNameMessage + ".MessageID, Header FROM " + - _tableNameMessage + - " INNER JOIN " + - _tableNameQueueMessageRelation + - " ON " + - _tableNameMessage + ".MessageID = " + _tableNameQueueMessageRelation + ".MessageID" + - " WHERE " + - _tableNameQueueMessageRelation + ".QueueID = ?" + - " AND " + - _tableNameQueueMessageRelation + ".Prepared = 0"); + _tableNameMessage + + " INNER JOIN " + + _tableNameQueueMessageRelation + + " ON " + + _tableNameMessage + ".MessageID = " + _tableNameQueueMessageRelation + ".MessageID" + + " WHERE " + + _tableNameQueueMessageRelation + ".QueueID = ?" + + " AND " + + _tableNameQueueMessageRelation + ".Prepared = 0"); connection.getStatements()[GET_ALL_MESSAGES] = pstmt; } pstmt.setInt(1, queue.getQueueID()); @@ -1310,7 +1403,10 @@ public class JDBCStore implements MessageStore // ContentHeaderBody hb; while (rs.next()) { - foundMessage = new AMQMessage(rs.getLong(1), this, messageHandleFactory, txnContext); + + //DTX MessageStore - this -> null , txContext -> null + foundMessage = new AMQMessage(rs.getLong(1), null, messageHandleFactory, null); + result.add(foundMessage); } rs.close(); @@ -1340,7 +1436,7 @@ public class JDBCStore implements MessageStore owner = new AMQShortString(rs.getString(3)); } foundQueue = new AMQQueue(new AMQShortString(rs.getString(2)), - true, owner, false, _virtualHost); + true, owner, false, _virtualHost); // get all the Messages of that queue foundMessages = getAllMessages(connection, foundQueue); // enqueue those messages @@ -1350,7 +1446,7 @@ public class JDBCStore implements MessageStore } for (StorableMessage foundMessage : foundMessages) { - foundMessage.staged(); + foundMessage.staged(); foundMessage.enqueue(foundQueue); foundQueue.enqueue(foundMessage); foundQueue.process(context, (AMQMessage) foundMessage, false); @@ -1362,10 +1458,12 @@ public class JDBCStore implements MessageStore } rs.close(); return result; - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot recover: ", e); - } finally + } + finally { if (connection != null) { @@ -1373,7 +1471,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -1404,7 +1503,7 @@ public class JDBCStore implements MessageStore // get all the bindings Statement stmtb = connection.getConnection().createStatement(); ResultSet rsb = stmtb.executeQuery("SELECT * FROM " + _tableNameExchangeQueueRelation + - " WHERE Name = '" + rs.getString(1) + "'"); + " WHERE Name = '" + rs.getString(1) + "'"); while (rsb.next()) { foundQueue = queueMap.get(new Integer(rsb.getInt(1))); @@ -1426,10 +1525,12 @@ public class JDBCStore implements MessageStore _virtualHost.getExchangeRegistry().registerExchange(foundExchange); } rs.close(); - } catch (Exception e) + } + catch (Exception e) { throw new InternalErrorException("Cannot recover: ", e); - } finally + } + finally { if (connection != null) { @@ -1437,7 +1538,8 @@ public class JDBCStore implements MessageStore { connection.getConnection().commit(); _connectionPool.releaseInstance(connection); - } catch (SQLException e) + } + catch (SQLException e) { // we did not manage to commit this connection // it is better to release it @@ -1456,7 +1558,7 @@ public class JDBCStore implements MessageStore if (pstmt == null) { pstmt = connection.getConnection().prepareStatement("DELETE FROM " + _tableNameMessage + - " WHERE MessageID = ?"); + " WHERE MessageID = ?"); connection.getStatements()[DELETE_MESSAGE] = pstmt; } pstmt.setLong(1, m.getMessageId()); @@ -1589,8 +1691,8 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameMessage + " (MessageID FLOAT NOT NULL, Header BLOB," + - " Payload BLOB, ExchangeName VARCHAR(1024), RoutingKey VARCHAR(1024)," + - " Mandatory INTEGER, Is_Immediate INTEGER, PRIMARY KEY(MessageID))"); + " Payload BLOB, ExchangeName VARCHAR(1024), RoutingKey VARCHAR(1024)," + + " Mandatory INTEGER, Is_Immediate INTEGER, PRIMARY KEY(MessageID))"); myconnection._connection.commit(); } catch (SQLException ex) @@ -1602,7 +1704,7 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameQueue + " (QueueID INTEGER NOT NULL, " + - "Name VARCHAR(1024) NOT NULL, Owner VARCHAR(1024), PRIMARY KEY(QueueID))"); + "Name VARCHAR(1024) NOT NULL, Owner VARCHAR(1024), PRIMARY KEY(QueueID))"); myconnection._connection.commit(); } catch (SQLException ex) @@ -1614,7 +1716,7 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameQueueMessageRelation + " (QueueID INTEGER NOT NULL, " + - "MessageID FLOAT NOT NULL, Prepared INTEGER)"); + "MessageID FLOAT NOT NULL, Prepared INTEGER)"); myconnection._connection.commit(); } catch (SQLException ex) @@ -1625,7 +1727,7 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameExchange + " (Name VARCHAR(1024) NOT NULL, " + - "Type VARCHAR(1024) NOT NULL, PRIMARY KEY(Name))"); + "Type VARCHAR(1024) NOT NULL, PRIMARY KEY(Name))"); myconnection._connection.commit(); } catch (SQLException ex) @@ -1636,7 +1738,7 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameExchangeQueueRelation + " (QueueID INTEGER NOT NULL, " + - "Name VARCHAR(1024) NOT NULL, RoutingKey VARCHAR(1024), FieldTable BLOB )"); + "Name VARCHAR(1024) NOT NULL, RoutingKey VARCHAR(1024), FieldTable BLOB )"); myconnection._connection.commit(); } catch (SQLException ex) @@ -1647,7 +1749,7 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameRecord + " (XID_ID FLOAT, Type INTEGER, MessageID FLOAT, " + - "QueueID INTEGER, PRIMARY KEY(Type, MessageID, QueueID))"); + "QueueID INTEGER, PRIMARY KEY(Type, MessageID, QueueID))"); // we could alter the table with QueueID as foreign key myconnection._connection.commit(); } @@ -1659,7 +1761,7 @@ public class JDBCStore implements MessageStore try { stmt.executeUpdate("CREATE TABLE " + _tableNameTransaction + " (XID_ID FLOAT, FormatId INTEGER, " + - "BranchQualifier BLOB, GlobalTransactionId BLOB, PRIMARY KEY(XID_ID))"); + "BranchQualifier BLOB, GlobalTransactionId BLOB, PRIMARY KEY(XID_ID))"); myconnection._connection.commit(); } catch (SQLException ex) diff --git a/java/broker/src/main/java/org/apache/qpid/server/messageStore/MessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/messageStore/MessageStore.java index 913f3ed9c6..f5dc160fc6 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/messageStore/MessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/messageStore/MessageStore.java @@ -18,15 +18,23 @@ */ package org.apache.qpid.server.messageStore; -import org.apache.qpid.server.exception.*; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.txn.TransactionManager; -import org.apache.qpid.server.exchange.Exchange; +import org.apache.commons.configuration.Configuration; +import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.commons.configuration.Configuration; +import org.apache.qpid.server.exception.InternalErrorException; +import org.apache.qpid.server.exception.InvalidXidException; +import org.apache.qpid.server.exception.MessageAlreadyStagedException; +import org.apache.qpid.server.exception.MessageDoesntExistException; +import org.apache.qpid.server.exception.QueueAlreadyExistsException; +import org.apache.qpid.server.exception.QueueDoesntExistException; +import org.apache.qpid.server.exception.UnknownXidException; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.txn.TransactionManager; +import org.apache.qpid.server.virtualhost.VirtualHost; import javax.transaction.xa.Xid; import java.util.Collection; @@ -203,7 +211,7 @@ public interface MessageStore * @throws InternalErrorException In case of internal message store problem * @throws MessageDoesntExistException If the message does not exist */ - public MessagePublishInfo getMessagePublishInfo(StorableMessage m) + public MessagePublishInfo getMessagePublishInfo(StorableMessage m) throws InternalErrorException, MessageDoesntExistException; diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java index 84ec91d569..0c80414a3e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.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 @@ -44,6 +44,9 @@ import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.transport.ConnectorConfiguration; import org.apache.qpid.ssl.SSLContextFactory; +import java.io.IOException; +import java.net.InetSocketAddress; + /** * The protocol handler handles "protocol events" for all connections. The state * associated with an individual connection is accessed through the protocol session. @@ -80,12 +83,12 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter final AMQCodecFactory codecFactory = new AMQCodecFactory(true); createSession(protocolSession, _applicationRegistry, codecFactory); - _logger.info("Protocol session created"); + _logger.info("Protocol session created for:" + protocolSession.getRemoteAddress()); final ProtocolCodecFilter pcf = new ProtocolCodecFilter(codecFactory); - ConnectorConfiguration connectorConfig = - ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class); + ConnectorConfiguration connectorConfig = ApplicationRegistry.getInstance(). + getConfiguredObject(ConnectorConfiguration.class); if (connectorConfig.enableExecutorPool) { if (connectorConfig.enableSSL && isSSLClient(connectorConfig, protocolSession)) @@ -95,7 +98,7 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter String certType = connectorConfig.certType; SSLContextFactory sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType); protocolSession.getFilterChain().addAfter("AsynchronousReadFilter", "sslFilter", - new SSLFilter(sslContextFactory.buildServerContext())); + new SSLFilter(sslContextFactory.buildServerContext())); } protocolSession.getFilterChain().addBefore("AsynchronousWriteFilter", "protocolFilter", pcf); @@ -119,22 +122,21 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter /** * Separated into its own, protected, method to allow easier reuse */ - protected void createSession(IoSession session, IApplicationRegistry applicationRegistry, AMQCodecFactory codec) - throws AMQException + protected void createSession(IoSession session, IApplicationRegistry applicationRegistry, AMQCodecFactory codec) throws AMQException { new AMQMinaProtocolSession(session, applicationRegistry.getVirtualHostRegistry(), codec); } public void sessionOpened(IoSession protocolSession) throws Exception { - _logger.info("Session opened"); + _logger.info("Session opened for:" + protocolSession.getRemoteAddress()); } public void sessionClosed(IoSession protocolSession) throws Exception { - _logger.info("Protocol Session closed"); + _logger.info("Protocol Session closed for:" + protocolSession.getRemoteAddress()); final AMQProtocolSession amqProtocolSession = AMQMinaProtocolSession.getAMQProtocolSession(protocolSession); - // fixme -- this can be null + //fixme -- this can be null if (amqProtocolSession != null) { amqProtocolSession.closeSession(); @@ -143,15 +145,15 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter public void sessionIdle(IoSession session, IdleStatus status) throws Exception { - _logger.debug("Protocol Session [" + this + "] idle: " + status); + _logger.debug("Protocol Session [" + this + "] idle: " + status + " :for:" + session.getRemoteAddress()); if (IdleStatus.WRITER_IDLE.equals(status)) { - // write heartbeat frame: + //write heartbeat frame: session.write(HeartbeatBody.FRAME); } else if (IdleStatus.READER_IDLE.equals(status)) { - // failover: + //failover: throw new IOException("Timed out while waiting for heartbeat from peer."); } @@ -167,7 +169,7 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter protocolSession.close(); - _logger.error("Error in protocol initiation " + session + ": " + throwable.getMessage(), throwable); + _logger.error("Error in protocol initiation " + session + ":" + protocolSession.getRemoteAddress() + " :" + throwable.getMessage(), throwable); } else if (throwable instanceof IOException) { @@ -178,13 +180,14 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter _logger.error("Exception caught in" + session + ", closing session explictly: " + throwable, throwable); // Be aware of possible changes to parameter order as versions change. - protocolSession.write(ConnectionCloseBody.createAMQFrame(0, session.getProtocolMajorVersion(), - session.getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - 200, // replyCode - new AMQShortString(throwable.getMessage()) // replyText - )); + protocolSession.write(ConnectionCloseBody.createAMQFrame(0, + session.getProtocolMajorVersion(), + session.getProtocolMinorVersion(), // AMQP version (major, minor) + 0, // classId + 0, // methodId + 200, // replyCode + new AMQShortString(throwable.getMessage()) // replyText + )); protocolSession.close(); } } @@ -203,6 +206,7 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter if (message instanceof AMQDataBlock) { amqProtocolSession.dataBlockReceived((AMQDataBlock) message); + } else if (message instanceof ByteBuffer) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java index 95f75fdb36..d5100dc8e5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java @@ -20,17 +20,8 @@ */ package org.apache.qpid.server.queue; -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - - -/** Combines the information that make up a deliverable message into a more manageable form. */ - import org.apache.log4j.Logger; - import org.apache.mina.common.ByteBuffer; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQBody; import org.apache.qpid.framing.AMQDataBlock; @@ -40,22 +31,33 @@ import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; -import org.apache.qpid.server.messageStore.MessageStore; import org.apache.qpid.server.messageStore.StorableMessage; import org.apache.qpid.server.messageStore.StorableQueue; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.txn.TransactionalContext; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + /** * Combines the information that make up a deliverable message into a more manageable form. */ public class AMQMessage implements StorableMessage { + /** Used for debugging purposes. */ private static final Logger _log = Logger.getLogger(AMQMessage.class); - // The ordered list of queues into which this message is enqueued. + // The ordered list of queues into which this message is enqueued. private List<StorableQueue> _queues = new LinkedList<StorableQueue>(); // Indicates whether this message is staged private boolean _isStaged = false; @@ -66,7 +68,7 @@ public class AMQMessage implements StorableMessage private Set<Object> _tokens; /** - * Only use in clustering - should ideally be removed? + * Only use in clustering - //todo: should ideally be removed? */ private AMQProtocolSession _publisher; @@ -76,12 +78,13 @@ public class AMQMessage implements StorableMessage private AMQMessageHandle _messageHandle; + /** Holds the transactional context in which this message is being processed. */ // TODO: ideally this should be able to go into the transient message date - check this! (RG) private TransactionalContext _txnContext; /** - * Flag to indicate whether message has been delivered to a consumer. Used in implementing return functionality for - * messages published with the 'immediate' flag. + * Flag to indicate whether this message has been delivered to a consumer. Used in implementing return functionality + * for messages published with the 'immediate' flag. */ private boolean _deliveredToConsumer; /** @@ -89,18 +92,25 @@ public class AMQMessage implements StorableMessage * checkDelieveredToConsumer is called, the message may already have been received and acknowledged, and the body * removed from the store. */ + + /** Flag to indicate that this message requires 'immediate' delivery. */ private boolean _immediate; // private Subscription _takenBySubcription; // private AtomicBoolean _taken = new AtomicBoolean(false); private TransientMessageData _transientMessageData = new TransientMessageData(); + //todo: this should be part of a messageOnQueue object private Set<Subscription> _rejectedBy = null; + //todo: this should be part of a messageOnQueue object private Map<AMQQueue, AtomicBoolean> _takenMap = new HashMap<AMQQueue, AtomicBoolean>(); + //todo: this should be part of a messageOnQueue object private Map<AMQQueue, Subscription> _takenBySubcriptionMap = new HashMap<AMQQueue, Subscription>(); private final int hashcode = System.identityHashCode(this); + + //todo: this should be part of a messageOnQueue object private long _expiration; public String debugIdentity() @@ -111,9 +121,9 @@ public class AMQMessage implements StorableMessage public void setExpiration() { long expiration = - ((BasicContentHeaderProperties) _transientMessageData.getContentHeaderBody().properties).getExpiration(); + ((BasicContentHeaderProperties) _transientMessageData.getContentHeaderBody().properties).getExpiration(); long timestamp = - ((BasicContentHeaderProperties) _transientMessageData.getContentHeaderBody().properties).getTimestamp(); + ((BasicContentHeaderProperties) _transientMessageData.getContentHeaderBody().properties).getTimestamp(); if (ApplicationRegistry.getInstance().getConfiguration().getBoolean("advanced.synced-clocks", false)) { @@ -176,8 +186,8 @@ public class AMQMessage implements StorableMessage { AMQBody cb = - getProtocolVersionMethodConverter().convertToBody(_messageHandle.getContentChunk(getStoreContext(), - _messageId, ++_index)); + getProtocolVersionMethodConverter().convertToBody(_messageHandle.getContentChunk(getStoreContext(), + _messageId, ++_index)); return new AMQFrame(_channel, cb); } @@ -259,10 +269,11 @@ public class AMQMessage implements StorableMessage * @param messageId * @param store * @param factory + * * @throws AMQException */ public AMQMessage(Long messageId, MessageStore store, MessageHandleFactory factory, TransactionalContext txnConext) - throws AMQException + throws AMQException { _messageId = messageId; _messageHandle = factory.createMessageHandle(store, this, true); @@ -279,7 +290,7 @@ public class AMQMessage implements StorableMessage * @param contentHeader */ public AMQMessage(Long messageId, MessagePublishInfo info, TransactionalContext txnContext, - ContentHeaderBody contentHeader) throws AMQException + ContentHeaderBody contentHeader) throws AMQException { this(messageId, info, txnContext); setContentHeaderBody(contentHeader); @@ -294,11 +305,12 @@ public class AMQMessage implements StorableMessage * @param contentHeader * @param destinationQueues * @param contentBodies + * * @throws AMQException */ public AMQMessage(Long messageId, MessagePublishInfo info, TransactionalContext txnContext, - ContentHeaderBody contentHeader, List<AMQQueue> destinationQueues, List<ContentChunk> contentBodies, - MessageStore messageStore, StoreContext storeContext, MessageHandleFactory messageHandleFactory) throws AMQException + ContentHeaderBody contentHeader, List<AMQQueue> destinationQueues, List<ContentChunk> contentBodies, + MessageStore messageStore, StoreContext storeContext, MessageHandleFactory messageHandleFactory) throws AMQException { this(messageId, info, txnContext, contentHeader); _transientMessageData.setDestinationQueues(destinationQueues); @@ -443,22 +455,23 @@ public class AMQMessage implements StorableMessage } public void routingComplete(MessageStore store, StoreContext storeContext, MessageHandleFactory factory) - throws AMQException + throws AMQException { final boolean persistent = isPersistent(); _messageHandle = factory.createMessageHandle(store, this, persistent); - // if (persistent) - // { - _txnContext.beginTranIfNecessary(); - // } + if (persistent) //DTX was removed + { + _txnContext.beginTranIfNecessary(); + } // enqueuing the messages ensure that if required the destinations are recorded to a // persistent store - // for (AMQQueue q : _transientMessageData.getDestinationQueues()) - // { - // _messageHandle.enqueue(storeContext, _messageId, q); - // } + //DTX was removed + for (AMQQueue q : _transientMessageData.getDestinationQueues()) + { + _messageHandle.enqueue(storeContext, _messageId, q); + } if (_transientMessageData.getContentHeaderBody().bodySize == 0) { @@ -494,11 +507,12 @@ public class AMQMessage implements StorableMessage */ public AMQMessage takeReference() { - _referenceCount.incrementAndGet(); + incrementReference(); // _referenceCount.incrementAndGet(); return this; } + /** * Threadsafe. Increment the reference count on the message. */ @@ -516,6 +530,7 @@ public class AMQMessage implements StorableMessage * message store. * * @param storeContext + * * @throws MessageCleanupException when an attempt was made to remove the message from the message store and that * failed */ @@ -555,7 +570,7 @@ public class AMQMessage implements StorableMessage if (count < 0) { throw new MessageCleanupException("Reference count for message id " + debugIdentity() + " has gone below 0.", - null); + null); } } } @@ -684,6 +699,7 @@ public class AMQMessage implements StorableMessage * AMQMessageHandle implementation can be picked based on various criteria. * * @param queue the queue + * * @throws org.apache.qpid.AMQException if there is an error enqueuing the message */ public void enqueue(AMQQueue queue) throws AMQException @@ -756,14 +772,13 @@ public class AMQMessage implements StorableMessage /** * Checks to see if the message has expired. If it has the message is dequeued. * - * @param storecontext - * @param queue + * @param queue The queue to check the expiration against. (Currently not used) * * @return true if the message has expire * * @throws AMQException */ - public boolean expired(StoreContext storecontext, AMQQueue queue) throws AMQException + public boolean expired(AMQQueue queue) throws AMQException { // note: If the storecontext isn't need then we can remove the getChannel() from Subscription. @@ -771,12 +786,7 @@ public class AMQMessage implements StorableMessage { long now = System.currentTimeMillis(); - if (now > _expiration) - { - dequeue(storecontext, queue); - - return true; - } + return (now > _expiration); } return false; @@ -803,7 +813,7 @@ public class AMQMessage implements StorableMessage // first we allow the handle to know that the message has been fully received. This is useful if it is // maintaining any calculated values based on content chunks _messageHandle.setPublishAndContentHeaderBody(storeContext, _messageId, - _transientMessageData.getMessagePublishInfo(), _transientMessageData.getContentHeaderBody()); + _transientMessageData.getMessagePublishInfo(), _transientMessageData.getContentHeaderBody()); // we then allow the transactional context to do something with the message content // now that it has all been received, before we attempt delivery @@ -1039,7 +1049,7 @@ public class AMQMessage implements StorableMessage // _taken + " by :" + _takenBySubcription; return "Message[" + debugIdentity() + "]: " + _messageId + "; ref count: " + _referenceCount + "; taken for queues: " - + _takenMap.toString() + " by Subs:" + _takenBySubcriptionMap.toString(); + + _takenMap.toString() + " by Subs:" + _takenBySubcriptionMap.toString(); } public Subscription getDeliveredSubscription(AMQQueue queue) @@ -1053,6 +1063,7 @@ public class AMQMessage implements StorableMessage public void reject(Subscription subscription) { + if (subscription != null) { if (_rejectedBy == null) diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java index 6273ac997b..b4a92b3483 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java @@ -20,38 +20,26 @@ */ package org.apache.qpid.server.queue; -import java.text.MessageFormat; -import java.util.Collection; -import java.util.Hashtable; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import javax.management.JMException; - import org.apache.log4j.Logger; - import org.apache.qpid.AMQException; import org.apache.qpid.configuration.Configured; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.exception.InternalErrorException; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.messageStore.StorableMessage; import org.apache.qpid.server.messageStore.StorableQueue; import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.virtualhost.VirtualHost; import javax.management.JMException; - import java.text.MessageFormat; +import java.util.Collection; +import java.util.Hashtable; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; @@ -65,6 +53,49 @@ import java.util.concurrent.atomic.AtomicLong; */ public class AMQQueue implements Managable, Comparable, StorableQueue { + //FROM M2 - think these have been replaced by *Exception in the broker exception package +// /** +// * ExistingExclusiveSubscription signals a failure to create a subscription, because an exclusive subscription +// * already exists. +// * +// * <p/><table id="crc"><caption>CRC Card</caption> +// * <tr><th> Responsibilities <th> Collaborations +// * <tr><td> Represent failure to create a subscription, because an exclusive subscription already exists. +// * </table> +// * +// * @todo Not an AMQP exception as no status code. +// * +// * @todo Move to top level, used outside this class. +// */ +// public static final class ExistingExclusiveSubscription extends AMQException +// { +// +// public ExistingExclusiveSubscription() +// { +// super(""); +// } +// } +// +// /** +// * ExistingSubscriptionPreventsExclusive signals a failure to create an exclusize subscription, as a subscription +// * already exists. +// * +// * <p/><table id="crc"><caption>CRC Card</caption> +// * <tr><th> Responsibilities <th> Collaborations +// * <tr><td> Represent failure to create an exclusize subscription, as a subscription already exists. +// * </table> +// * +// * @todo Not an AMQP exception as no status code. +// * +// * @todo Move to top level, used outside this class. +// */ +// public static final class ExistingSubscriptionPreventsExclusive extends AMQException +// { +// public ExistingSubscriptionPreventsExclusive() +// { +// super(""); + // } + // } public static int s_queueID = 0; private static final Logger _logger = Logger.getLogger(AMQQueue.class); @@ -163,22 +194,22 @@ public class AMQQueue implements Managable, Comparable, StorableQueue } public AMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, VirtualHost virtualHost) - throws AMQException + throws AMQException { this(name, durable, owner, autoDelete, virtualHost, AsyncDeliveryConfig.getAsyncDeliveryExecutor(), - new SubscriptionSet(), new SubscriptionImpl.Factory()); + new SubscriptionSet(), new SubscriptionImpl.Factory()); } protected AMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, - VirtualHost virtualHost, SubscriptionSet subscribers) throws AMQException + VirtualHost virtualHost, SubscriptionSet subscribers) throws AMQException { this(name, durable, owner, autoDelete, virtualHost, AsyncDeliveryConfig.getAsyncDeliveryExecutor(), subscribers, - new SubscriptionImpl.Factory()); + new SubscriptionImpl.Factory()); } protected AMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, - VirtualHost virtualHost, Executor asyncDelivery, SubscriptionSet subscribers, - SubscriptionFactory subscriptionFactory) throws AMQException + VirtualHost virtualHost, Executor asyncDelivery, SubscriptionSet subscribers, + SubscriptionFactory subscriptionFactory) throws AMQException { if (name == null) { @@ -298,32 +329,217 @@ public class AMQQueue implements Managable, Comparable, StorableQueue * (enqueue in other queue) - Once sending to other Queue is successful, remove messages from this queue - remove * locks from both queues and start async delivery * - * @param fromMessageId - * @param toMessageId - * @param queueName - * @param storeContext + * @param fromMessageId The first message id to move. + * @param toMessageId The last message id to move. + * @param queueName The queue to move the messages to. + * @param storeContext The context of the message store under which to perform the move. This is associated with + * the stores transactional context. */ public synchronized void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, - StoreContext storeContext) + StoreContext storeContext) { - // prepare the delivery manager for moving messages by stopping the async delivery and creating a lock - AMQQueue anotherQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + + MessageStore fromStore = getVirtualHost().getMessageStore(); + MessageStore toStore = toQueue.getVirtualHost().getMessageStore(); + + if (toStore != fromStore) + { + throw new RuntimeException("Can only move messages between queues on the same message store."); + } + try { + // Obtain locks to prevent activity on the queues being moved between. startMovingMessages(); + toQueue.startMovingMessages(); + + // Get the list of messages to move. List<AMQMessage> foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId); - // move messages to another queue - anotherQueue.startMovingMessages(); - anotherQueue.enqueueMovedMessages(storeContext, foundMessagesList); + try + { + fromStore.beginTran(storeContext); + + // Move the messages in on the message store. + for (AMQMessage message : foundMessagesList) + { + fromStore.dequeueMessage(storeContext, _name, message.getMessageId()); + toStore.enqueueMessage(storeContext, toQueue._name, message.getMessageId()); + } + + // Commit and flush the move transcations. + try + { + fromStore.commitTran(storeContext); + } + catch (AMQException e) + { + throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e); + } + + // Move the messages on the in-memory queues. + toQueue.enqueueMovedMessages(storeContext, foundMessagesList); + _deliveryMgr.removeMovedMessages(foundMessagesList); + } + // Abort the move transactions on move failures. + catch (AMQException e) + { + try + { + fromStore.abortTran(storeContext); + } + catch (AMQException ae) + { + throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae); + } + } + } + // Release locks to allow activity on the queues being moved between to continue. + finally + { + toQueue.stopMovingMessages(); + stopMovingMessages(); + } + } + + /** + * Copies messages on this queue to another queue, and also commits the move on the message store. Delivery activity + * on the queues being moved between is suspended during the move. + * + * @param fromMessageId The first message id to move. + * @param toMessageId The last message id to move. + * @param queueName The queue to move the messages to. + * @param storeContext The context of the message store under which to perform the move. This is associated with + * the stores transactional context. + */ + public synchronized void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, + StoreContext storeContext) + { + AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); - // moving is successful, now remove from original queue - _deliveryMgr.removeMovedMessages(foundMessagesList); + MessageStore fromStore = getVirtualHost().getMessageStore(); + MessageStore toStore = toQueue.getVirtualHost().getMessageStore(); + + if (toStore != fromStore) + { + throw new RuntimeException("Can only move messages between queues on the same message store."); } + + try + { + // Obtain locks to prevent activity on the queues being moved between. + startMovingMessages(); + toQueue.startMovingMessages(); + + // Get the list of messages to move. + List<AMQMessage> foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId); + + try + { + fromStore.beginTran(storeContext); + + // Move the messages in on the message store. + for (AMQMessage message : foundMessagesList) + { + toStore.enqueueMessage(storeContext, toQueue._name, message.getMessageId()); + message.takeReference(); + } + + // Commit and flush the move transcations. + try + { + fromStore.commitTran(storeContext); + } + catch (AMQException e) + { + throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e); + } + + // Move the messages on the in-memory queues. + toQueue.enqueueMovedMessages(storeContext, foundMessagesList); + } + // Abort the move transactions on move failures. + catch (AMQException e) + { + try + { + fromStore.abortTran(storeContext); + } + catch (AMQException ae) + { + throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae); + } + } + } + // Release locks to allow activity on the queues being moved between to continue. + finally + { + toQueue.stopMovingMessages(); + stopMovingMessages(); + } + } + + /** + * Removes messages from this queue, and also commits the remove on the message store. Delivery activity + * on the queues being moved between is suspended during the remove. + * + * @param fromMessageId The first message id to move. + * @param toMessageId The last message id to move. + * @param storeContext The context of the message store under which to perform the move. This is associated with + * the stores transactional context. + */ + public synchronized void removeMessagesFromQueue(long fromMessageId, long toMessageId, StoreContext storeContext) + { + MessageStore fromStore = getVirtualHost().getMessageStore(); + + try + { + // Obtain locks to prevent activity on the queues being moved between. + startMovingMessages(); + + // Get the list of messages to move. + List<AMQMessage> foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId); + + try + { + fromStore.beginTran(storeContext); + + // remove the messages in on the message store. + for (AMQMessage message : foundMessagesList) + { + fromStore.dequeueMessage(storeContext, _name, message.getMessageId()); + } + + // Commit and flush the move transcations. + try + { + fromStore.commitTran(storeContext); + } + catch (AMQException e) + { + throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e); + } + + // remove the messages on the in-memory queues. + _deliveryMgr.removeMovedMessages(foundMessagesList); + } + // Abort the move transactions on move failures. + catch (AMQException e) + { + try + { + fromStore.abortTran(storeContext); + } + catch (AMQException ae) + { + throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae); + } + } + } + // Release locks to allow activity on the queues being moved between to continue. finally { - // remove the lock and start the async delivery - anotherQueue.stopMovingMessages(); stopMovingMessages(); } } @@ -426,14 +642,16 @@ public class AMQQueue implements Managable, Comparable, StorableQueue exchange.registerQueue(routingKey, this, arguments); if (isDurable() && exchange.isDurable()) { - try - { - _virtualHost.getMessageStore().bindQueue(exchange, routingKey, this, arguments); - } - catch (InternalErrorException e) - { - throw new AMQException(null, "Problem binding queue ", e); - } + _virtualHost.getMessageStore().bindQueue(exchange, routingKey, this, arguments); + //DTX MessageStore +// try +// { +// _virtualHost.getMessageStore().bindQueue(exchange, routingKey, this, arguments); +// } +// catch (InternalErrorException e) +// { +// throw new AMQException(null, "Problem binding queue ", e); +// } } _bindings.addBinding(routingKey, arguments, exchange); @@ -444,21 +662,24 @@ public class AMQQueue implements Managable, Comparable, StorableQueue exchange.deregisterQueue(routingKey, this, arguments); if (isDurable() && exchange.isDurable()) { - try - { - _virtualHost.getMessageStore().unbindQueue(exchange, routingKey, this, arguments); - } - catch (InternalErrorException e) - { - throw new AMQException(null, "problem unbinding queue", e); - } + + _virtualHost.getMessageStore().unbindQueue(exchange, routingKey, this, arguments); + //DTX MessageStore +// try +// { +// _virtualHost.getMessageStore().unbindQueue(exchange, routingKey, this, arguments); +// } +// catch (InternalErrorException e) +// { +// throw new AMQException(null, "problem unbinding queue", e); +// } } _bindings.remove(routingKey, arguments, exchange); } public void registerProtocolSession(AMQProtocolSession ps, int channel, AMQShortString consumerTag, boolean acks, - FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException + FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException { if (incrementSubscriberCount() > 1) { @@ -487,7 +708,7 @@ public class AMQQueue implements Managable, Comparable, StorableQueue } Subscription subscription = - _subscriptionFactory.createSubscription(channel, ps, consumerTag, acks, filters, noLocal, this); + _subscriptionFactory.createSubscription(channel, ps, consumerTag, acks, filters, noLocal, this); if (subscription.filtersMessages()) { @@ -532,11 +753,11 @@ public class AMQQueue implements Managable, Comparable, StorableQueue Subscription removedSubscription; if ((removedSubscription = - _subscribers.removeSubscriber(_subscriptionFactory.createSubscription(channel, ps, consumerTag))) - == null) + _subscribers.removeSubscriber(_subscriptionFactory.createSubscription(channel, ps, consumerTag))) + == null) { throw new AMQException(null, "Protocol session with channel " + channel + " and consumer tag " + consumerTag - + " and protocol session key " + ps.getKey() + " not registered with queue " + this, null); + + " and protocol session key " + ps.getKey() + " not registered with queue " + this, null); } removedSubscription.close(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java index bbaa7379f6..4331d8d870 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java @@ -18,30 +18,23 @@ * under the License. * */ -/* - * - * Copyright (c) 2006 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ package org.apache.qpid.server.queue; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; +import org.apache.log4j.Logger; + +import org.apache.mina.common.ByteBuffer; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.CommonContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.management.MBeanConstructor; +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.store.StoreContext; import javax.management.JMException; import javax.management.MBeanException; @@ -60,30 +53,25 @@ import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; -import org.apache.log4j.Logger; - -import org.apache.mina.common.ByteBuffer; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.CommonContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.abstraction.ContentChunk; -import org.apache.qpid.server.management.AMQManagedObject; -import org.apache.qpid.server.management.MBeanConstructor; -import org.apache.qpid.server.management.MBeanDescription; -import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.store.StoreContext; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; /** * MBean class for AMQQueue. It implements all the management features exposed * for an AMQQueue. + * <p/><tablse id="crc"><caption>CRC Caption</caption> + * <tr><th> Responsibilities <th> Collaborations + * </table> */ @MBeanDescription("Management Interface for AMQQueue") public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, QueueNotificationListener { + /** Used for debugging purposes. */ private static final Logger _logger = Logger.getLogger(AMQQueueMBean.class); + private static final SimpleDateFormat _dateFormat = new SimpleDateFormat("MM-dd-yy HH:mm:ss.SSS z"); /** diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java index 2aa759b35d..0639243e02 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java @@ -87,6 +87,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager private final Object _queueHeadLock = new Object(); private String _processingThreadName = ""; + + /** Used by any reaping thread to purge messages */ + private StoreContext _reapingStoreContext = new StoreContext(); + ConcurrentSelectorDeliveryManager(SubscriptionManager subscriptions, AMQQueue queue) { @@ -453,12 +457,31 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager //while (we have a message) && ((The subscriber is not a browser or message is taken ) or we are clearing) && (Check message is taken.) while (purgeMessage(message, sub)) { + // if we are purging then ensure we mark this message taken for the current subscriber + // the current subscriber may be null in the case of a get or a purge but this is ok. +// boolean alreadyTaken = message.taken(_queue, sub); + //remove the already taken message or expired AMQMessage removed = messages.poll(); assert removed == message; - _totalMessageSize.addAndGet(-message.getSize()); + // if the message expired then the _totalMessageSize needs adjusting + if (message.expired(_queue)) + { + _totalMessageSize.addAndGet(-message.getSize()); + + // Use the reapingStoreContext as any sub(if we have one) may be in a tx. + message.dequeue(_reapingStoreContext, _queue); + + if (_log.isInfoEnabled()) + { + _log.info(debugIdentity() + " Doing clean up of the main _message queue."); + } + } + + //else the clean up is not required as the message has already been taken for this queue therefore + // it was the responsibility of the code that took the message to ensure the _totalMessageSize was updated. if (_log.isTraceEnabled()) { @@ -473,7 +496,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager } /** - * + * This method will return true if the message is to be purged from the queue. + * + * + * SIDE-EFFECT: The message will be taken by the Subscription(sub) for the current Queue(_queue) * @param message * @param sub * @return @@ -493,15 +519,15 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager // if the message is null then don't purge as we have no messagse. if (message != null) { + // Check that the message hasn't expired. + if (message.expired(_queue)) + { + return true; + } + // if we have a subscriber perform message checks if (sub != null) { - // Check that the message hasn't expired. - if (message.expired(sub.getChannel().getStoreContext(), _queue)) - { - return true; - } - // if we have a queue browser(we don't purge) so check mark the message as taken purge = ((!sub.isBrowser() || message.isTaken(_queue))); } @@ -606,7 +632,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager { if (_log.isInfoEnabled()) { - _log.info(debugIdentity() + "We could do clean up of the main _message queue here"); + //fixme - we should do the clean up as the message remains on the _message queue + // this is resulting in the next consumer receiving the message and then attempting to purge it + // + _log.info(debugIdentity() + "We should do clean up of the main _message queue here"); } } @@ -617,7 +646,14 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager } catch (AMQException e) { - message.release(_queue); + if (message != null) + { + message.release(_queue); + } + else + { + _log.error(debugIdentity() + "Unable to release message as it is null. " + e, e); + } _log.error(debugIdentity() + "Unable to deliver message as dequeue failed: " + e, e); } } @@ -696,25 +732,6 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager } -// private void sendNextMessage(Subscription sub) -// { -// if (sub.filtersMessages()) -// { -// sendNextMessage(sub, sub.getPreDeliveryQueue()); -// if (sub.isAutoClose()) -// { -// if (sub.getPreDeliveryQueue().isEmpty()) -// { -// sub.close(); -// } -// } -// } -// else -// { -// sendNextMessage(sub, _messages); -// } -// } - public void deliver(StoreContext context, AMQShortString name, AMQMessage msg, boolean deliverFirst) throws AMQException { @@ -723,8 +740,6 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager { _log.debug(debugIdentity() + "deliver :first(" + deliverFirst + ") :" + msg); } - // This shouldn't be done here. -// msg.release(); //Check if we have someone to deliver the message to. _lock.lock(); @@ -800,7 +815,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager if (debugEnabled) { _log.debug(debugIdentity() + " Subscription(" + System.identityHashCode(s) + ") became " + - "suspended between nextSubscriber and send for message:" + msg.debugIdentity()); + "suspended between nextSubscriber and send for message:" + msg.debugIdentity()); } } } @@ -810,7 +825,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager if (debugEnabled) { _log.debug(debugIdentity() + " Message(" + msg.debugIdentity() + ") has not been taken so recursing!:" + - " Subscriber:" + System.identityHashCode(s)); + " Subscriber:" + System.identityHashCode(s)); } deliver(context, name, msg, deliverFirst); diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java index c0f1e7f40c..cbe9246f09 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java @@ -20,13 +20,14 @@ */ package org.apache.qpid.server.queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + public class DefaultQueueRegistry implements QueueRegistry { private ConcurrentMap<AMQShortString, AMQQueue> _queueMap = new ConcurrentHashMap<AMQShortString, AMQQueue>(); @@ -57,4 +58,14 @@ public class DefaultQueueRegistry implements QueueRegistry { return _queueMap.get(name); } + + public Collection<AMQShortString> getQueueNames() + { + return _queueMap.keySet(); + } + + public Collection<AMQQueue> getQueues() + { + return _queueMap.values(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java index a8247aa2db..a950678487 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java @@ -80,7 +80,10 @@ class ExchangeBindings public boolean equals(Object o) { - if (!(o instanceof ExchangeBinding)) return false; + if (!(o instanceof ExchangeBinding)) + { + return false; + } ExchangeBinding eb = (ExchangeBinding) o; return _exchange.equals(eb._exchange) && _routingKey.equals(eb._routingKey) @@ -104,16 +107,16 @@ class ExchangeBindings */ void addBinding(AMQShortString routingKey, FieldTable arguments, Exchange exchange) { - _bindings.add(new ExchangeBinding(routingKey, exchange, arguments )); + _bindings.add(new ExchangeBinding(routingKey, exchange, arguments)); } public void remove(AMQShortString routingKey, FieldTable arguments, Exchange exchange) { - _bindings.remove(new ExchangeBinding(routingKey, exchange, arguments )); + _bindings.remove(new ExchangeBinding(routingKey, exchange, arguments)); } - + /** * Deregisters this queue from any exchange it has been bound to */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/InMemoryMessageHandle.java b/java/broker/src/main/java/org/apache/qpid/server/queue/InMemoryMessageHandle.java index 1d9f56669e..c81360e7d4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/InMemoryMessageHandle.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/InMemoryMessageHandle.java @@ -56,9 +56,7 @@ public class InMemoryMessageHandle implements AMQMessageHandle { } - public ContentHeaderBody getContentHeaderBody(StoreContext context, Long messageId) - throws - AMQException + public ContentHeaderBody getContentHeaderBody(StoreContext context, Long messageId) throws AMQException { return _contentHeaderBody; } @@ -68,36 +66,28 @@ public class InMemoryMessageHandle implements AMQMessageHandle return _contentBodies.size(); } - public long getBodySize(StoreContext context, Long messageId) - throws - AMQException + public long getBodySize(StoreContext context, Long messageId) throws AMQException { return getContentHeaderBody(context, messageId).bodySize; } - public ContentChunk getContentChunk(StoreContext context, Long messageId, int index) - throws - AMQException, - IllegalArgumentException + public ContentChunk getContentChunk(StoreContext context, Long messageId, int index) throws AMQException, IllegalArgumentException { if (index > _contentBodies.size() - 1) { throw new IllegalArgumentException("Index " + index + " out of valid range 0 to " + - (_contentBodies.size() - 1)); + (_contentBodies.size() - 1)); } return _contentBodies.get(index); } public void addContentBodyFrame(StoreContext storeContext, Long messageId, ContentChunk contentBody, boolean isLastContentBody) - throws - AMQException + throws AMQException { _contentBodies.add(contentBody); } - public MessagePublishInfo getMessagePublishInfo(StoreContext context, Long messageId) - throws - AMQException + public MessagePublishInfo getMessagePublishInfo(StoreContext context, Long messageId) throws AMQException { return _messagePublishInfo; } @@ -113,50 +103,40 @@ public class InMemoryMessageHandle implements AMQMessageHandle _redelivered = redelivered; } - public boolean isPersistent(StoreContext context, Long messageId) - throws - AMQException + public boolean isPersistent(StoreContext context, Long messageId) throws AMQException { //todo remove literal values to a constant file such as AMQConstants in common ContentHeaderBody chb = getContentHeaderBody(context, messageId); return chb.properties instanceof BasicContentHeaderProperties && - ((BasicContentHeaderProperties) chb.properties).getDeliveryMode() == 2; + ((BasicContentHeaderProperties) chb.properties).getDeliveryMode() == 2; } /** * This is called when all the content has been received. - * * @param messagePublishInfo * @param contentHeaderBody * @throws AMQException */ public void setPublishAndContentHeaderBody(StoreContext storeContext, Long messageId, MessagePublishInfo messagePublishInfo, ContentHeaderBody contentHeaderBody) - throws - AMQException + throws AMQException { _messagePublishInfo = messagePublishInfo; _contentHeaderBody = contentHeaderBody; _arrivalTime = System.currentTimeMillis(); } - public void removeMessage(StoreContext storeContext, Long messageId) - throws - AMQException + public void removeMessage(StoreContext storeContext, Long messageId) throws AMQException { // NO OP } - public void enqueue(StoreContext storeContext, Long messageId, AMQQueue queue) - throws - AMQException + public void enqueue(StoreContext storeContext, Long messageId, AMQQueue queue) throws AMQException { // NO OP } - public void dequeue(StoreContext storeContext, Long messageId, AMQQueue queue) - throws - AMQException + public void dequeue(StoreContext storeContext, Long messageId, AMQQueue queue) throws AMQException { // NO OP } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageHandleFactory.java b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageHandleFactory.java index 69aaffa907..35e43aa412 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageHandleFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageHandleFactory.java @@ -20,14 +20,13 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.messageStore.StorableMessage; /** * Constructs a message handle based on the publish body, the content header and the queue to which the message * has been routed. * - * @author Robert Greig (robert.j.greig@jpmorgan.com) */ public class MessageHandleFactory { @@ -37,8 +36,9 @@ public class MessageHandleFactory // just hardcoded for now if (persistent) { - // return new WeakReferenceMessageHandle(store); - return new StorableMessageHandle(store, m); + return new WeakReferenceMessageHandle(store); + //DTX MessageStore +// return new StorableMessageHandle(store, m); } else { diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java index 285f05fb20..6118a4c11f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java @@ -1,18 +1,22 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ package org.apache.qpid.server.queue; diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java index 00ccffdea1..6b3d65661f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java @@ -1,18 +1,21 @@ /*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * 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
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
package org.apache.qpid.server.queue;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java index 9554d34f00..d2680ffcc8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java @@ -1,18 +1,21 @@ /*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * 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
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
package org.apache.qpid.server.queue;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java index ed2101fd75..1210f0e97c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java @@ -23,8 +23,8 @@ package org.apache.qpid.server.queue; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.messageStore.StorableQueue; +import java.util.Collection; public interface QueueRegistry { @@ -35,4 +35,9 @@ public interface QueueRegistry void unregisterQueue(AMQShortString name) throws AMQException; AMQQueue getQueue(AMQShortString name); + + Collection<AMQShortString> getQueueNames(); + + Collection<AMQQueue> getQueues(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/StorableMessageHandle.java b/java/broker/src/main/java/org/apache/qpid/server/queue/StorableMessageHandle.java index 47126f4b68..8c20050027 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/StorableMessageHandle.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/StorableMessageHandle.java @@ -17,24 +17,21 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.messageStore.MessageStore; import org.apache.qpid.server.messageStore.StorableMessage; -import org.apache.qpid.server.messageStore.JDBCStore; -import org.apache.qpid.server.exception.InternalErrorException; -import org.apache.qpid.server.exception.MessageDoesntExistException; -import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.log4j.Logger; +import org.apache.qpid.server.store.StoreContext; import javax.transaction.xa.Xid; -import java.util.List; -import java.util.LinkedList; import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.List; /** * Created by Arnaud Simon @@ -94,7 +91,8 @@ public class StorableMessageHandle implements AMQMessageHandle try { _contentHeaderBody = _messageStore.getContentHeaderBody(_message); - } catch (Exception e) + } + catch (Exception e) { throw new AMQException(AMQConstant.INTERNAL_ERROR, e.getMessage(), e); } @@ -106,17 +104,17 @@ public class StorableMessageHandle implements AMQMessageHandle throws AMQException { - if (_chunks == null ) - { - if(_message.isStaged() ) - { - loadChunks(); - } - else - { - return 0; - } - } + if (_chunks == null) + { + if (_message.isStaged()) + { + loadChunks(); + } + else + { + return 0; + } + } return _chunks.size(); } @@ -144,8 +142,8 @@ public class StorableMessageHandle implements AMQMessageHandle AMQException { try - { - _chunks = new LinkedList<ContentChunk>(); + { + _chunks = new LinkedList<ContentChunk>(); byte[] underlying = _messageStore.loadContent(_message, 1, 0); final int size = underlying.length; final org.apache.mina.common.ByteBuffer data = @@ -169,7 +167,8 @@ public class StorableMessageHandle implements AMQMessageHandle } }; _chunks.add(cb); - } catch (Exception e) + } + catch (Exception e) { throw new AMQException(AMQConstant.INTERNAL_ERROR, e.getMessage(), e); } @@ -198,8 +197,10 @@ public class StorableMessageHandle implements AMQMessageHandle // read it from the store try { + _messagePublishInfo = _messageStore.getMessagePublishInfo(_message); - } catch (Exception e) + } + catch (Exception e) { throw new AMQException(AMQConstant.INTERNAL_ERROR, e.getMessage(), e); } @@ -222,7 +223,7 @@ public class StorableMessageHandle implements AMQMessageHandle AMQException { return _contentHeaderBody.properties instanceof BasicContentHeaderProperties && - ((BasicContentHeaderProperties) _contentHeaderBody.properties).getDeliveryMode() == 2; + ((BasicContentHeaderProperties) _contentHeaderBody.properties).getDeliveryMode() == 2; } public void setPublishAndContentHeaderBody(StoreContext storeContext, Long messageId, @@ -254,7 +255,8 @@ public class StorableMessageHandle implements AMQMessageHandle { _messageStore.enqueue((Xid) storeContext.getPayload(), _message, queue); } - } catch (Exception e) + } + catch (Exception e) { throw new AMQException(null, "PRoblem during message enqueue", e); } @@ -270,7 +272,8 @@ public class StorableMessageHandle implements AMQMessageHandle { _messageStore.dequeue((Xid) storeContext.getPayload(), _message, queue); } - } catch (Exception e) + } + catch (Exception e) { throw new AMQException(null, "PRoblem during message dequeue", e); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java b/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java index 7c8064789e..79ee6b93a3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/WeakReferenceMessageHandle.java b/java/broker/src/main/java/org/apache/qpid/server/queue/WeakReferenceMessageHandle.java index 64fb6c15d5..88eb891a20 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/WeakReferenceMessageHandle.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/WeakReferenceMessageHandle.java @@ -34,7 +34,6 @@ import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; /** - * @author Robert Greig (robert.j.greig@jpmorgan.com) */ public class WeakReferenceMessageHandle implements AMQMessageHandle { diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java index 2e506b9751..06eb9329a6 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java @@ -107,7 +107,7 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab } private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, Configuration config, int index) - throws FileNotFoundException, ConfigurationException + throws FileNotFoundException, ConfigurationException { String baseName = _base + "(" + index + ").attributes.attribute."; List<String> argumentNames = config.getList(baseName + "name"); @@ -139,9 +139,9 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab if (method == null) { throw new ConfigurationException("No method " + methodName + " found in class " - + principalDatabase.getClass() - + " hence unable to configure principal database. The method must be public and " - + "have a single String argument with a void return type"); + + principalDatabase.getClass() + + " hence unable to configure principal database. The method must be public and " + + "have a single String argument with a void return type"); } try @@ -152,7 +152,7 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab { if (ite instanceof ConfigurationException) { - throw (ConfigurationException) ite; + throw(ConfigurationException) ite; } else { diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransactionalContext.java index 6c001485b9..13f66fac5b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransactionalContext.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransactionalContext.java @@ -26,8 +26,6 @@ import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.messageStore.MessageStore; import org.apache.qpid.server.RequiredDeliveryException; -import org.apache.qpid.server.exception.InternalErrorException; -import org.apache.qpid.server.exception.InvalidXidException; import org.apache.log4j.Logger; import javax.transaction.xa.Xid; diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java index 8becaf52b9..47c94114a3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.txn; @@ -31,7 +34,7 @@ import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.NoConsumersException; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; /** @author Apache Software Foundation */ @@ -74,7 +77,7 @@ public class NonTransactionalContext implements TransactionalContext { if (!_inTran) { - // _messageStore.beginTran(_storeContext); + _messageStore.beginTran(_storeContext); _inTran = true; } } @@ -93,10 +96,12 @@ public class NonTransactionalContext implements TransactionalContext { try { - if( ! deliverFirst ) - { - message.getMessageHandle().enqueue(_storeContext, message.getMessageId(), queue); - } + //DTX removed - deliverFirst is to do with the position on the Queue not enqueuing!! + // This should be done in routingComplete +// if( ! deliverFirst ) +// { +// message.getMessageHandle().enqueue(_storeContext, message.getMessageId(), queue); +// } queue.process(_storeContext, message, deliverFirst); //following check implements the functionality //required by the 'immediate' flag: @@ -216,7 +221,8 @@ public class NonTransactionalContext implements TransactionalContext { if (persistent) { - // _messageStore.commitTran(_storeContext); + //DTX removed this option. + _messageStore.commitTran(_storeContext); _inTran = false; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java index 88451e2fca..fee25c07df 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java @@ -28,24 +28,144 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.store.StoreContext; /** - * @author Robert Greig (robert.j.greig@jpmorgan.com) + * TransactionalContext provides a context in which transactional operations on {@link AMQMessage}s are performed. + * Different levels of transactional support for the delivery of messages may be provided by different implementations + * of this interface. + * + * <p/>The fundamental transactional operations that can be performed on a message queue are 'enqueue' and 'dequeue'. + * In this interface, these have been recast as the {@link #messageFullyReceived} and {@link #acknowledgeMessage} + * operations. This interface essentially provides a way to make enqueueing and dequeuing transactional. + * + * <p/><table id="crc"><caption>CRC Card</caption> + * <tr><th> Responsibilities + * <tr><td> Explicitly accept a transaction start notification. + * <tr><td> Commit all pending operations in a transaction. + * <tr><td> Rollback all pending operations in a transaction. + * <tr><td> Deliver a message to a queue as part of a transaction. + * <tr><td> Redeliver a message to a queue as part of a transaction. + * <tr><td> Mark a message as acknowledged as part of a transaction. + * <tr><td> Accept notification that a message has been completely received as part of a transaction. + * <tr><td> Accept notification that a message has been fully processed as part of a transaction. + * <tr><td> Associate a message store context with this transaction context. + * </table> + * + * @todo The 'fullyReceived' and 'messageProcessed' events sit uncomfortably in the responsibilities of a transactional + * context. They are non-transactional operations, used to trigger other side-effects. Consider moving them + * somewhere else, a seperate interface for example. + * + * @todo This transactional context could be written as a wrapper extension to a Queue implementation, that provides + * transactional management of the enqueue and dequeue operations, with added commit/rollback methods. Any + * queue implementation could be made transactional by wrapping it as a transactional queue. This would mean + * that the enqueue/dequeue operations do not need to be recast as deliver/acknowledge operations, which may be + * conceptually neater. + * + * For example: + * <pre> + * public interface Transactional + * { + * public void commit(); + * public void rollback(); + * } + * + * public interface TransactionalQueue<E> extends Transactional, SizeableQueue<E> + * {} + * + * public class Queues + * { + * ... + * // For transactional messaging, take a transactional view onto the queue. + * public static <E> TransactionalQueue<E> getTransactionalQueue(SizeableQueue<E> queue) { ... } + * + * // For non-transactional messaging, take a non-transactional view onto the queue. + * public static <E> TransactionalQueue<E> getNonTransactionalQueue(SizeableQueue<E> queue) { ... } + * } + * </pre> */ public interface TransactionalContext { + /** + * Explicitly begins the transaction, if it has not already been started. {@link #commit} or {@link #rollback} + * should automatically begin the next transaction in the chain. + * + * @throws AMQException If the transaction cannot be started for any reason. + */ void beginTranIfNecessary() throws AMQException; + /** + * Makes all pending operations on the transaction permanent and visible. + * + * @throws AMQException If the transaction cannot be committed for any reason. + */ void commit() throws AMQException; + /** + * Erases all pending operations on the transaction. + * + * @throws AMQException If the transaction cannot be committed for any reason. + */ void rollback() throws AMQException; + /** + * Delivers the specified message to the specified queue. A 'deliverFirst' flag may be set if the message is a + * redelivery, and should be placed on the front of the queue. + * + * <p/>This is an 'enqueue' operation. + * + * @param message The message to deliver. + * @param queue The queue to deliver the message to. + * @param deliverFirst <tt>true</tt> to place the message on the front of the queue for redelivery, <tt>false</tt> + * for normal FIFO message ordering. + * + * @throws AMQException If the message cannot be delivered for any reason. + */ void deliver(AMQMessage message, AMQQueue queue, boolean deliverFirst) throws AMQException; + /** + * Acknowledges a message or many messages as delivered. All messages up to a specified one, may be acknowledged by + * setting the 'multiple' flag. It is also possible for the acknowledged message id to be zero, when the 'multiple' + * flag is set, in which case an acknowledgement up to the latest delivered message should be done. + * + * <p/>This is a 'dequeue' operation. + * + * @param deliveryTag The id of the message to acknowledge, or zero, if using multiple acknowledgement + * up to the latest message. + * @param lastDeliveryTag The latest message delivered. + * @param multiple <tt>true</tt> if all message ids up the acknowledged one or latest delivered, are + * to be acknowledged, <tt>false</tt> otherwise. + * @param unacknowledgedMessageMap The unacknowledged messages in the transaction, to remove the acknowledged message + * from. + * + * @throws AMQException If the message cannot be acknowledged for any reason. + */ void acknowledgeMessage(long deliveryTag, long lastDeliveryTag, boolean multiple, - UnacknowledgedMessageMap unacknowledgedMessageMap) throws AMQException; + UnacknowledgedMessageMap unacknowledgedMessageMap) throws AMQException; + /** + * Notifies the transactional context that a message has been fully received. The actual message that was received + * is not specified. This event may be used to trigger a process related to the receipt of the message, for example, + * flushing its data to disk. + * + * @param persistent <tt>true</tt> if the received message is persistent, <tt>false</tt> otherwise. + * + * @throws AMQException If the fully received event cannot be processed for any reason. + */ void messageFullyReceived(boolean persistent) throws AMQException; + /** + * Notifies the transactional context that a message has been delivered, succesfully or otherwise. The actual + * message that was delivered is not specified. This event may be used to trigger a process related to the + * outcome of the delivery of the message, for example, cleaning up failed deliveries. + * + * @param protocolSession The protocol session of the deliverable message. + * + * @throws AMQException If the message processed event cannot be handled for any reason. + */ void messageProcessed(AMQProtocolSession protocolSession) throws AMQException; + /** + * Gets the message store context associated with this transactional context. + * + * @return The message store context associated with this transactional context. + */ StoreContext getStoreContext(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java index 12b2a4f7a8..4985c12dbb 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java @@ -57,11 +57,11 @@ public class NullApplicationRegistry extends ApplicationRegistry super(new MapConfiguration(new HashMap())); } - public void initialise() - throws - Exception + public void initialise() throws Exception { - _configuration.addProperty("store.class", "org.apache.qpid.server.messageStore.MemoryMessageStore"); + //DTX MessageStore +// _configuration.addProperty("store.class", "org.apache.qpid.server.messageStore.MemoryMessageStore"); + _configuration.addProperty("store.class", "org.apache.qpid.server.store.MemoryMessageStore"); _configuration.addProperty("txn.class", "org.apache.qpid.server.txn.MemoryTransactionManager"); // _configuration.addProperty("store.class", "org.apache.qpid.server.messageStore.JDBCStore"); // _configuration.addProperty("txn.class", "org.apache.qpid.server.txn.JDBCTransactionManager"); diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index 6518d8b765..53844ccc4b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -1,290 +1,289 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost; - -import javax.management.NotCompliantMBeanException; - -import org.apache.commons.configuration.Configuration; -import org.apache.log4j.Logger; -import org.apache.qpid.server.AMQBrokerManagerMBean; -import org.apache.qpid.server.txn.TransactionManager; -import org.apache.qpid.server.security.access.AccessManager; -import org.apache.qpid.server.security.access.AccessManagerImpl; -import org.apache.qpid.server.security.access.Accessable; -import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.configuration.Configurator; -import org.apache.qpid.server.exchange.DefaultExchangeFactory; -import org.apache.qpid.server.exchange.DefaultExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeFactory; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.management.AMQManagedObject; -import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.queue.DefaultQueueRegistry; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.messageStore.MessageStore; - -public class VirtualHost implements Accessable -{ - private static final Logger _logger = Logger.getLogger(VirtualHost.class); - - - private final String _name; - - private QueueRegistry _queueRegistry; - - private ExchangeRegistry _exchangeRegistry; - - private ExchangeFactory _exchangeFactory; - - private MessageStore _messageStore; - - private TransactionManager _transactionManager; - - protected VirtualHostMBean _virtualHostMBean; - - private AMQBrokerManagerMBean _brokerMBean; - - private AuthenticationManager _authenticationManager; - - private AccessManager _accessManager; - - - public void setAccessableName(String name) - { - _logger.warn("Setting Accessable Name for VirualHost is not allowed. (" - + name + ") ignored remains :" + getAccessableName()); - } - - public String getAccessableName() - { - return _name; - } - - - /** - * Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any - * implementaion of an Exchange MBean should extend this class. - */ - public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost - { - public VirtualHostMBean() throws NotCompliantMBeanException - { - super(ManagedVirtualHost.class, "VirtualHost"); - } - - public String getObjectInstanceName() - { - return _name.toString(); - } - - public String getName() - { - return _name.toString(); - } - - public VirtualHost getVirtualHost() - { - return VirtualHost.this; - } - - - } // End of MBean class - - /** - * Used for testing only - * - * @param name - * @param store - * - * @throws Exception - */ - public VirtualHost(String name, MessageStore store) throws Exception - { - this(name, null, store); - } - - /** - * Normal Constructor - * - * @param name - * @param hostConfig - * - * @throws Exception - */ - public VirtualHost(String name, Configuration hostConfig) throws Exception - { - this(name, hostConfig, null); - } - - private VirtualHost(String name, Configuration hostConfig, MessageStore store) throws Exception - { - _name = name; - - _virtualHostMBean = new VirtualHostMBean(); - // This isn't needed to be registered - //_virtualHostMBean.register(); - - _queueRegistry = new DefaultQueueRegistry(this); - _exchangeFactory = new DefaultExchangeFactory(this); - _exchangeFactory.initialise(hostConfig); - _exchangeRegistry = new DefaultExchangeRegistry(this); - - if (store != null) - { - _messageStore = store; - } - else - { - if (hostConfig == null) - { - throw new IllegalAccessException("HostConfig and MessageStore cannot be null"); - } - initialiseTransactionManager(hostConfig); - initialiseMessageStore(hostConfig); - } - - _exchangeRegistry.initialise(); - - - _logger.warn("VirtualHost authentication Managers require spec change to be operational."); - _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig); - - _accessManager = new AccessManagerImpl(name, hostConfig); - - _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean); - _brokerMBean.register(); - } - - private void initialiseMessageStore(Configuration config) throws Exception - { - String messageStoreClass = config.getString("store.class"); - - Class clazz = Class.forName(messageStoreClass); - Object o = clazz.newInstance(); - - if (!(o instanceof MessageStore)) - { - throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz + - " does not."); - } - _messageStore = (MessageStore) o; - _messageStore.configure(this, _transactionManager, "store", config); - } - - private void initialiseTransactionManager(Configuration config) throws Exception - { - String transactionManagerClass = config.getString("txn.class"); - Class clazz = Class.forName(transactionManagerClass); - Object o = clazz.newInstance(); - - if (!(o instanceof TransactionManager)) - { - throw new ClassCastException("Transaction Manager class must implement " + TransactionManager.class + ". Class " + clazz + - " does not."); - } - _transactionManager = (TransactionManager) o; - } - - - public <T> T getConfiguredObject(Class<T> instanceType, Configuration config) - { - T instance; - try - { - instance = instanceType.newInstance(); - } - catch (Exception e) - { - _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor"); - throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e); - } - Configurator.configure(instance); - - return instance; - } - - - public String getName() - { - return _name; - } - - public QueueRegistry getQueueRegistry() - { - return _queueRegistry; - } - - public ExchangeRegistry getExchangeRegistry() - { - return _exchangeRegistry; - } - - public ExchangeFactory getExchangeFactory() - { - return _exchangeFactory; - } - - public ApplicationRegistry getApplicationRegistry() - { - throw new UnsupportedOperationException(); - } - - public MessageStore getMessageStore() - { - return _messageStore; - } - - public TransactionManager getTransactionManager() - { - return _transactionManager; - } - - public AuthenticationManager getAuthenticationManager() - { - return _authenticationManager; - } - - public AccessManager getAccessManager() - { - return _accessManager; - } - - public void close() throws Exception - { - if (_messageStore != null) - { - _messageStore.close(); - } - } - - public ManagedObject getBrokerMBean() - { - return _brokerMBean; - } - - public ManagedObject getManagedObject() - { - return _virtualHostMBean; - } -} - +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.virtualhost;
+
+import javax.management.NotCompliantMBeanException;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.AMQBrokerManagerMBean;
+import org.apache.qpid.server.txn.TransactionManager;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AccessManagerImpl;
+import org.apache.qpid.server.security.access.Accessable;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.configuration.Configurator;
+import org.apache.qpid.server.exchange.DefaultExchangeFactory;
+import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
+import org.apache.qpid.server.exchange.ExchangeFactory;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.queue.DefaultQueueRegistry;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.store.MessageStore;
+
+public class VirtualHost implements Accessable
+{
+ private static final Logger _logger = Logger.getLogger(VirtualHost.class);
+
+
+ private final String _name;
+
+ private QueueRegistry _queueRegistry;
+
+ private ExchangeRegistry _exchangeRegistry;
+
+ private ExchangeFactory _exchangeFactory;
+
+ private MessageStore _messageStore;
+
+ private TransactionManager _transactionManager;
+
+ protected VirtualHostMBean _virtualHostMBean;
+
+ private AMQBrokerManagerMBean _brokerMBean;
+
+ private AuthenticationManager _authenticationManager;
+
+ private AccessManager _accessManager;
+
+
+ public void setAccessableName(String name)
+ {
+ _logger.warn("Setting Accessable Name for VirualHost is not allowed. ("
+ + name + ") ignored remains :" + getAccessableName());
+ }
+
+ public String getAccessableName()
+ {
+ return _name;
+ }
+
+
+ /**
+ * Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any
+ * implementaion of an Exchange MBean should extend this class.
+ */
+ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost
+ {
+ public VirtualHostMBean() throws NotCompliantMBeanException
+ {
+ super(ManagedVirtualHost.class, "VirtualHost");
+ }
+
+ public String getObjectInstanceName()
+ {
+ return _name.toString();
+ }
+
+ public String getName()
+ {
+ return _name.toString();
+ }
+
+ public VirtualHost getVirtualHost()
+ {
+ return VirtualHost.this;
+ }
+
+
+ } // End of MBean class
+
+ /**
+ * Used for testing only
+ * @param name
+ * @param store
+ *
+ * @throws Exception
+ */
+ public VirtualHost(String name, MessageStore store) throws Exception
+ {
+ this(name, null, store);
+ }
+
+ /**
+ * Normal Constructor
+ *
+ * @param name
+ * @param hostConfig
+ *
+ * @throws Exception
+ */
+ public VirtualHost(String name, Configuration hostConfig) throws Exception
+ {
+ this(name, hostConfig, null);
+ }
+
+ private VirtualHost(String name, Configuration hostConfig, MessageStore store) throws Exception
+ {
+ _name = name;
+
+ _virtualHostMBean = new VirtualHostMBean();
+ // This isn't needed to be registered
+ //_virtualHostMBean.register();
+
+ _queueRegistry = new DefaultQueueRegistry(this);
+ _exchangeFactory = new DefaultExchangeFactory(this);
+ _exchangeFactory.initialise(hostConfig);
+ _exchangeRegistry = new DefaultExchangeRegistry(this);
+
+ if (store != null)
+ {
+ _messageStore = store;
+ }
+ else
+ {
+ if (hostConfig == null)
+ {
+ throw new IllegalAccessException("HostConfig and MessageStore cannot be null");
+ }
+ initialiseTransactionManager(hostConfig);
+ initialiseMessageStore(hostConfig);
+ }
+
+ _exchangeRegistry.initialise();
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig);
+
+ _accessManager = new AccessManagerImpl(name, hostConfig);
+
+ _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
+ _brokerMBean.register();
+ }
+
+ private void initialiseMessageStore(Configuration config) throws Exception
+ {
+ String messageStoreClass = config.getString("store.class");
+
+ Class clazz = Class.forName(messageStoreClass);
+ Object o = clazz.newInstance();
+
+ if (!(o instanceof MessageStore))
+ {
+ throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz +
+ " does not.");
+ }
+ _messageStore = (MessageStore) o;
+ //DTX MessageStore
+// _messageStore.configure(this, _transactionManager, "store", config);
+ _messageStore.configure(this, "store", config);
+ }
+
+ private void initialiseTransactionManager(Configuration config) throws Exception
+ {
+ String transactionManagerClass = config.getString("txn.class");
+ Class clazz = Class.forName(transactionManagerClass);
+ Object o = clazz.newInstance();
+
+ if (!(o instanceof TransactionManager))
+ {
+ throw new ClassCastException("Transaction Manager class must implement " + TransactionManager.class + ". Class " + clazz +
+ " does not.");
+ }
+ _transactionManager = (TransactionManager) o;
+ }
+
+
+ public <T> T getConfiguredObject(Class<T> instanceType, Configuration config)
+ {
+ T instance;
+ try
+ {
+ instance = instanceType.newInstance();
+ }
+ catch (Exception e)
+ {
+ _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
+ throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
+ }
+ Configurator.configure(instance);
+
+ return instance;
+ }
+
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public QueueRegistry getQueueRegistry()
+ {
+ return _queueRegistry;
+ }
+
+ public ExchangeRegistry getExchangeRegistry()
+ {
+ return _exchangeRegistry;
+ }
+
+ public ExchangeFactory getExchangeFactory()
+ {
+ return _exchangeFactory;
+ }
+
+ public ApplicationRegistry getApplicationRegistry()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public MessageStore getMessageStore()
+ {
+ return _messageStore;
+ }
+
+ public TransactionManager getTransactionManager()
+ {
+ return _transactionManager;
+ }
+
+ public AuthenticationManager getAuthenticationManager()
+ {
+ return _authenticationManager;
+ }
+
+ public AccessManager getAccessManager()
+ {
+ return _accessManager;
+ }
+
+ public void close() throws Exception
+ {
+ if (_messageStore != null)
+ {
+ _messageStore.close();
+ }
+ }
+
+ public ManagedObject getBrokerMBean()
+ {
+ return _brokerMBean;
+ }
+
+ public ManagedObject getManagedObject()
+ {
+ return _virtualHostMBean;
+ }
+}
+
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java new file mode 100644 index 0000000000..edc900f401 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java @@ -0,0 +1,652 @@ +/* + * 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.tools.messagestore; + +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.configuration.Configuration; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; +import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.tools.messagestore.commands.Clear; +import org.apache.qpid.tools.messagestore.commands.Command; +import org.apache.qpid.tools.messagestore.commands.Copy; +import org.apache.qpid.tools.messagestore.commands.Dump; +import org.apache.qpid.tools.messagestore.commands.Help; +import org.apache.qpid.tools.messagestore.commands.List; +import org.apache.qpid.tools.messagestore.commands.Load; +import org.apache.qpid.tools.messagestore.commands.Quit; +import org.apache.qpid.tools.messagestore.commands.Select; +import org.apache.qpid.tools.messagestore.commands.Show; +import org.apache.qpid.tools.messagestore.commands.Move; +import org.apache.qpid.tools.messagestore.commands.Purge; +import org.apache.qpid.tools.utils.CommandParser; +import org.apache.qpid.tools.utils.Console; +import org.apache.qpid.tools.utils.SimpleCommandParser; +import org.apache.qpid.tools.utils.SimpleConsole; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * MessageStoreTool. + */ +public class MessageStoreTool +{ + /** Text outputted at the start of each console.*/ + private static final String BOILER_PLATE = "MessageStoreTool - for examining Persistent Qpid Broker MessageStore instances"; + + /** I/O Wrapper. */ + protected Console _console; + + /** Batch mode flag. */ + protected boolean _batchMode; + + /** Internal State object. */ + private State _state = new State(); + + private HashMap<String, Command> _commands = new HashMap<String, Command>(); + + /** SLF4J Logger. */ + private static Logger _devlog = LoggerFactory.getLogger(MessageStoreTool.class); + + /** Loaded configuration file. */ + private Configuration _config; + + /** Control used for main run loop. */ + private boolean _running = true; + private boolean _initialised = false; + + //---------------------------------------------------------------------------------------------------/ + + public static void main(String[] args) throws Configuration.InitException + { + + MessageStoreTool tool = new MessageStoreTool(args); + + tool.start(); + } + + + public MessageStoreTool(String[] args) throws Configuration.InitException + { + this(args, System.in, System.out); + } + + public MessageStoreTool(String[] args, InputStream in, OutputStream out) throws Configuration.InitException + { + BufferedReader consoleReader = new BufferedReader(new InputStreamReader(in)); + BufferedWriter consoleWriter = new BufferedWriter(new OutputStreamWriter(out)); + + Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook(this))); + _batchMode = false; + + _console = new SimpleConsole(consoleWriter, consoleReader); + + _config = new Configuration(); + + setOptions(); + _config.processCommandline(args); + } + + + private void setOptions() + { + Option help = new Option("h", "help", false, "print this message"); + Option version = new Option("v", "version", false, "print the version information and exit"); + Option configFile = + OptionBuilder.withArgName("file").hasArg() + .withDescription("use given configuration file By " + + "default looks for a file named " + + Configuration.DEFAULT_CONFIG_FILE + " in " + Configuration.QPID_HOME) + .withLongOpt("config") + .create("c"); + + _config.setOption(help); + _config.setOption(version); + _config.setOption(configFile); + } + + public State getState() + { + return _state; + } + + public Map<String, Command> getCommands() + { + return _commands; + } + + public void setConfigurationFile(String configfile) throws Configuration.InitException + { + _config.loadConfig(new File(configfile)); + setup(); + } + + public Console getConsole() + { + return _console; + } + + public void setConsole(Console console) + { + _console = console; + } + + /** + * Simple ShutdownHook to cleanly shutdown the databases + */ + class ShutdownHook implements Runnable + { + MessageStoreTool _tool; + + ShutdownHook(MessageStoreTool messageStoreTool) + { + _tool = messageStoreTool; + } + + public void run() + { + _tool.quit(); + } + } + + public void quit() + { + _running = false; + + if (_initialised) + { + ApplicationRegistry.remove(1); + } + + _console.println("...exiting"); + + _console.close(); + } + + public void setBatchMode(boolean batchmode) + { + _batchMode = batchmode; + } + + /** + * Main loop + */ + protected void start() + { + setup(); + + if (!_initialised) + { + System.exit(1); + } + + _console.println(""); + + _console.println(BOILER_PLATE); + + runCLI(); + } + + private void setup() + { + loadDefaultVirtualHosts(); + + loadCommands(); + + _state.clearAll(); + } + + private void loadCommands() + { + _commands.clear(); + //todo Dynamically load the classes that exis in com.redhat.etp.qpid.commands + _commands.put("close", new Clear(this)); + _commands.put("copy", new Copy(this)); + _commands.put("dump", new Dump(this)); + _commands.put("help", new Help(this)); + _commands.put("list", new List(this)); + _commands.put("load", new Load(this)); + _commands.put("move", new Move(this)); + _commands.put("purge", new Purge(this)); + _commands.put("quit", new Quit(this)); + _commands.put("select", new Select(this)); + _commands.put("show", new Show(this)); + } + + private void loadDefaultVirtualHosts() + { + final File configFile = _config.getConfigFile(); + + loadVirtualHosts(configFile); + } + + private void loadVirtualHosts(File configFile) + { + + if (!configFile.exists()) + { + _devlog.error("Config file not found:" + configFile.getAbsolutePath()); + return; + } + else + { + _devlog.debug("using config file :" + configFile.getAbsolutePath()); + } + + try + { + ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(configFile); + + ApplicationRegistry.remove(1); + + ApplicationRegistry.initialise(registry); + + checkMessageStores(); + _initialised = true; + } + catch (ConfigurationException e) + { + _console.println("Unable to load configuration due to configuration error: " + e.getMessage()); + e.printStackTrace(); + } + catch (Exception e) + { + _console.println("Unable to load configuration due to: " + e.getMessage()); + e.printStackTrace(); + } + + + } + + private void checkMessageStores() + { + Collection<VirtualHost> vhosts = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts(); + + boolean warning = false; + for (VirtualHost vhost : vhosts) + { + if (vhost.getMessageStore() instanceof MemoryMessageStore) + { + _console.println("WARNING: Virtualhost '" + vhost.getName() + "' is using a MemoryMessageStore. " + + "Changes will not persist."); + warning = true; + } + } + + if (warning) + { + _console.println(""); + _console.println("Please ensure you are using the correct config file currently using '" + + _config.getConfigFile().getAbsolutePath() + "'"); + _console.println("New config file can be specifed by 'load <config file>' or -c on the commandline."); + _console.println(""); + } + } + + private void runCLI() + { + while (_running) + { + if (!_batchMode) + { + printPrompt(); + } + + String[] args = _console.readCommand(); + + while (args != null) + { + exec(args); + + if (_running) + { + if (!_batchMode) + { + printPrompt(); + } + + args = _console.readCommand(); + } + } + } + } + + private void printPrompt() + { + _console.print(prompt()); + } + + + /** + * Execute a script (batch mode). + * + * @param script The file script + */ + protected void runScripts(String script) + { + //Store Current State + boolean oldBatch = _batchMode; + CommandParser oldParser = _console.getCommandParser(); + setBatchMode(true); + + try + { + _devlog.debug("Running script '" + script + "'"); + + _console.setCommandParser(new SimpleCommandParser(new BufferedReader(new FileReader(script)))); + + start(); + } + catch (java.io.FileNotFoundException e) + { + _devlog.error("Script not found: '" + script + "' due to:" + e.getMessage()); + } + + //Restore previous state + _console.setCommandParser(oldParser); + setBatchMode(oldBatch); + } + + public String prompt() + { + String state = _state.toString(); + if (state != null && state.length() != 0) + { + return state + ":bdb$ "; + } + else + { + return "bdb$ "; + } + } + + /** + * Execute the command. + * + * @param args [command, arg0, arg1...]. + */ + protected void exec(String[] args) + { + // Comment lines start with a # + if (args.length == 0 || args[0].startsWith("#")) + { + return; + } + + final String command = args[0]; + + Command cmd = _commands.get(command); + + if (cmd == null) + { + _console.println("Command not understood: " + command); + } + else + { + cmd.execute(args); + } + } + + + /** + * Displays usage info. + */ + protected static void help() + { + System.out.println(BOILER_PLATE); + System.out.println("Usage: java " + MessageStoreTool.class + " [Options]"); + System.out.println(" [-c <broker config file>] : Defaults to \"$QPID_HOME/etc/config.xml\""); + } + + + /** + * This class is used to store the current state of the tool. + * + * This is then interrogated by the various commands to augment their behaviour. + * + * + */ + public class State + { + private VirtualHost _vhost = null; + private AMQQueue _queue = null; + private Exchange _exchange = null; + private java.util.List<Long> _msgids = null; + + public State() + { + } + + public void setQueue(AMQQueue queue) + { + _queue = queue; + } + + public AMQQueue getQueue() + { + return _queue; + } + + public void setVhost(VirtualHost vhost) + { + _vhost = vhost; + } + + public VirtualHost getVhost() + { + return _vhost; + } + + public Exchange getExchange() + { + return _exchange; + } + + public void setExchange(Exchange exchange) + { + _exchange = exchange; + } + + public String toString() + { + StringBuilder status = new StringBuilder(); + + if (_vhost != null) + { + status.append(_vhost.getName()); + + if (_exchange != null) + { + status.append("["); + status.append(_exchange.getName()); + status.append("]"); + + if (_queue != null) + { + status.append("->'"); + status.append(_queue.getName()); + status.append("'"); + + if (_msgids != null) + { + status.append(printMessages()); + } + } + } + } + + return status.toString(); + } + + + public String printMessages() + { + StringBuilder sb = new StringBuilder(); + + Long previous = null; + + Long start = null; + for (Long id : _msgids) + { + if (previous != null) + { + if (id == previous + 1) + { + if (start == null) + { + start = previous; + } + } + else + { + if (start != null) + { + sb.append(","); + sb.append(start); + sb.append("-"); + sb.append(id); + start = null; + } + else + { + sb.append(","); + sb.append(previous); + } + } + } + + previous = id; + } + + if (start != null) + { + sb.append(","); + sb.append(start); + sb.append("-"); + sb.append(_msgids.get(_msgids.size() - 1)); + } + else + { + sb.append(","); + sb.append(previous); + } + + // surround list in () + sb.replace(0, 1, "("); + sb.append(")"); + return sb.toString(); + } + + public void clearAll() + { + _vhost = null; + clearExchange(); + } + + public void clearExchange() + { + _exchange = null; + clearQueue(); + } + + public void clearQueue() + { + _queue = null; + clearMessages(); + } + + public void clearMessages() + { + _msgids = null; + } + + /** + * A common location to provide parsing of the message id string + * utilised by a number of the commands. + * The String is comma separated list of ids that can be individual ids + * or a range (4-10) + * + * @param msgString string of msg ids to parse 1,2,4-10 + */ + public void setMessages(String msgString) + { + StringTokenizer tok = new StringTokenizer(msgString, ","); + + if (tok.hasMoreTokens()) + { + _msgids = new LinkedList<Long>(); + } + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + if (next.contains("-")) + { + Long start = Long.parseLong(next.substring(0, next.indexOf("-"))); + Long end = Long.parseLong(next.substring(next.indexOf("-") + 1)); + + if (end >= start) + { + for (long l = start; l <= end; l++) + { + _msgids.add(l); + } + } + } + else + { + _msgids.add(Long.parseLong(next)); + } + } + + } + + public void setMessages(java.util.List<Long> msgids) + { + _msgids = msgids; + } + + public java.util.List<Long> getMessages() + { + return _msgids; + } + }//Class State + +}//Class MessageStoreTool diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java new file mode 100644 index 0000000000..5444197cb4 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java @@ -0,0 +1,66 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +public abstract class AbstractCommand implements Command +{ + protected Console _console; + protected MessageStoreTool _tool; + + public AbstractCommand(MessageStoreTool tool) + { + _console = tool.getConsole(); + _tool = tool; + } + + public void setOutput(Console out) + { + _console = out; + } + + protected void commandError(String message, String[] args) + { + _console.print(getCommand() + " : " + message); + + if (args != null) + { + for (int i = 1; i < args.length; i++) + { + _console.print(args[i]); + } + } + _console.println(""); + _console.println(help()); + } + + + public abstract String help(); + + public abstract String usage(); + + public abstract String getCommand(); + + + public abstract void execute(String... args); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java new file mode 100644 index 0000000000..b0006b3fe6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java @@ -0,0 +1,85 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Clear extends AbstractCommand +{ + public Clear(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Clears any selection."; + } + + public String usage() + { + return "clear [ all | virtualhost | exchange | queue | msgs ]"; + } + + public String getCommand() + { + return "clear"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length < 1) + { + doClose("all"); + } + else + { + doClose(args[1]); + } + } + + private void doClose(String type) + { + if (type.equals("virtualhost") + || type.equals("all")) + { + _tool.getState().clearAll(); + } + + if (type.equals("exchange")) + { + _tool.getState().clearExchange(); + } + + if (type.equals("queue")) + { + _tool.getState().clearQueue(); + } + + if (type.equals("msgs")) + { + _tool.getState().clearMessages(); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java new file mode 100644 index 0000000000..bfa775a34a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.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.tools.messagestore.commands; + +import org.apache.qpid.tools.utils.Console; + +public interface Command +{ + public void setOutput(Console out); + + public String help(); + + public abstract String usage(); + + String getCommand(); + + public void execute(String... args); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java new file mode 100644 index 0000000000..a5b3a87616 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java @@ -0,0 +1,55 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Copy extends Move +{ + public Copy(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Copy messages between queues.";/*\n" + + "The currently selected message set will be copied to the specifed queue.\n" + + "Alternatively the values can be provided on the command line."; */ + } + + public String usage() + { + return "copy to=<queue> [from=<queue>] [msgids=<msgids eg, 1,2,4-10>]"; + } + + public String getCommand() + { + return "copy"; + } + + protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue) + { + fromQueue.copyMessagesToAnotherQueue(start, end, toQueue.getName().toString(), _storeContext); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java new file mode 100644 index 0000000000..a0fe54994b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java @@ -0,0 +1,299 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.commons.codec.binary.Hex; +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.io.UnsupportedEncodingException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +public class Dump extends Show +{ + private static final int LINE_SIZE = 8; + private static final String DEFAULT_ENCODING = "utf-8"; + private static final boolean SPACE_BYTES = true; + private static final String BYTE_SPACER = " "; + private static final String NON_PRINTING_ASCII_CHAR = "?"; + + protected boolean _content = true; + + public Dump(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Dump selected message content. Default: show=content"; + } + + public String usage() + { + return getCommand() + " [show=[all],[msgheaders],[_amqHeaders],[routing],[content]] [id=<msgid e.g. 1,2,4-10>]"; + } + + public String getCommand() + { + return "dump"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + + if (args.length >= 2) + { + for (String arg : args) + { + if (arg.startsWith("show=")) + { + _content = arg.contains("content") || arg.contains("all"); + } + } + + parseArgs(args); + } + + performShow(); + } + + + protected List<List> createMessageData(java.util.List<Long> msgids, List<AMQMessage> messages, boolean showHeaders, boolean showRouting, + boolean showMessageHeaders) + { + + List<List> display = new LinkedList<List>(); + + List<String> hex = new LinkedList<String>(); + List<String> ascii = new LinkedList<String>(); + display.add(hex); + display.add(ascii); + + for (AMQMessage msg : messages) + { + if (!includeMsg(msg, msgids)) + { + continue; + } + + //Add divider between messages + hex.add(Console.ROW_DIVIDER); + ascii.add(Console.ROW_DIVIDER); + + // Show general message information + hex.add(Show.Columns.ID.name()); + ascii.add("" +msg.getMessageId()); + + hex.add(Console.ROW_DIVIDER); + ascii.add(Console.ROW_DIVIDER); + + if (showRouting) + { + addShowInformation(hex, ascii, msg, "Routing Details", true, false, false); + } + if (showHeaders) + { + addShowInformation(hex, ascii, msg, "Headers", false, true, false); + } + if (showMessageHeaders) + { + addShowInformation(hex, ascii, msg, null, false, false, true); + } + + // Add Content Body seciont + hex.add("Content Body"); + ascii.add(""); + hex.add(Console.ROW_DIVIDER); + ascii.add(Console.ROW_DIVIDER); + + Iterator bodies = msg.getContentBodyIterator(); + if (bodies.hasNext()) + { + + hex.add("Hex"); + hex.add(Console.ROW_DIVIDER); + + + ascii.add("ASCII"); + ascii.add(Console.ROW_DIVIDER); + + while (bodies.hasNext()) + { + ContentChunk chunk = (ContentChunk) bodies.next(); + + //Duplicate so we don't destroy original data :) + ByteBuffer hexBuffer = chunk.getData().duplicate(); + + ByteBuffer charBuffer = hexBuffer.duplicate(); + + Hex hexencoder = new Hex(); + + while (hexBuffer.hasRemaining()) + { + byte[] line = new byte[LINE_SIZE]; + + int bufsize = hexBuffer.remaining(); + if (bufsize < LINE_SIZE) + { + hexBuffer.get(line, 0, bufsize); + } + else + { + bufsize = line.length; + hexBuffer.get(line); + } + + byte[] encoded = hexencoder.encode(line); + + try + { + String encStr = new String(encoded, 0, bufsize * 2, DEFAULT_ENCODING); + String hexLine = ""; + + int strKength = encStr.length(); + for (int c = 0; c < strKength; c++) + { + hexLine += encStr.charAt(c); + + if (c % 2 == 1 && SPACE_BYTES) + { + hexLine += BYTE_SPACER; + } + } + + hex.add(hexLine); + } + catch (UnsupportedEncodingException e) + { + _console.println(e.getMessage()); + return null; + } + } + + while (charBuffer.hasRemaining()) + { + String asciiLine = ""; + + for (int pos = 0; pos < LINE_SIZE; pos++) + { + if (charBuffer.hasRemaining()) + { + byte ch = charBuffer.get(); + + if (isPrintable(ch)) + { + asciiLine += (char) ch; + } + else + { + asciiLine += NON_PRINTING_ASCII_CHAR; + } + + if (SPACE_BYTES) + { + asciiLine += BYTE_SPACER; + } + } + else + { + break; + } + } + + ascii.add(asciiLine); + } + } + } + else + { + List<String> result = new LinkedList<String>(); + + display.add(result); + result.add("No ContentBodies"); + } + } + + // if hex is empty then we have no data to display + if (hex.size() == 0) + { + return null; + } + + return display; + } + + private void addShowInformation(List<String> column1, List<String> column2, AMQMessage msg, + String title, boolean routing, boolean headers, boolean messageHeaders) + { + List<AMQMessage> single = new LinkedList<AMQMessage>(); + single.add(msg); + + List<List> routingData = super.createMessageData(null, single, headers, routing, messageHeaders); + + //Reformat data + if (title != null) + { + column1.add(title); + column2.add(""); + column1.add(Console.ROW_DIVIDER); + column2.add(Console.ROW_DIVIDER); + } + + // look at all columns in the routing Data + for (List item : routingData) + { + // the item should be: + // Title + // *divider + // value + // otherwise we can't reason about the correct value + if (item.size() == 3) + { + //Filter out the columns we are not interested in. + + String columnName = item.get(0).toString(); + + if (!(columnName.equals(Show.Columns.ID.name()) + || columnName.equals(Show.Columns.Size.name()))) + { + column1.add(columnName); + column2.add(item.get(2).toString()); + } + } + } + column1.add(Console.ROW_DIVIDER); + column2.add(Console.ROW_DIVIDER); + } + + private boolean isPrintable(byte c) + { + return c > 31 && c < 127; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java new file mode 100644 index 0000000000..0f9546541b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java @@ -0,0 +1,98 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.util.LinkedList; +import java.util.Map; + +public class Help extends AbstractCommand +{ + public Help(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Provides detailed help on commands."; + } + + public String getCommand() + { + return "help"; + } + + public String usage() + { + return "help [<command>]"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length > 1) + { + Command command = _tool.getCommands().get(args[1]); + if (command != null) + { + _console.println(command.help()); + _console.println("Usage:" + command.usage()); + } + else + { + commandError("Command not found: ", args); + } + } + else + { + java.util.List<java.util.List> data = new LinkedList<java.util.List>(); + + java.util.List<String> commandName = new LinkedList<String>(); + java.util.List<String> commandDescription = new LinkedList<String>(); + + data.add(commandName); + data.add(commandDescription); + + //Set up Headers + commandName.add("Command"); + commandDescription.add("Description"); + + commandName.add(Console.ROW_DIVIDER); + commandDescription.add(Console.ROW_DIVIDER); + + //Add current Commands with descriptions + Map<String, Command> commands = _tool.getCommands(); + + for (Command command : commands.values()) + { + commandName.add(command.getCommand()); + commandDescription.add(command.help()); + } + + _console.printMap("Available Commands", data); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java new file mode 100644 index 0000000000..df8b59ec19 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java @@ -0,0 +1,314 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.util.Collection; +import java.util.LinkedList; + +public class List extends AbstractCommand +{ + + public List(MessageStoreTool tool) + { + super(tool); + } + + public void setOutput(Console out) + { + _console = out; + } + + public String help() + { + return "list available items."; + } + + public String usage() + { + return "list queues [<exchange>] | exchanges | bindings [<exchange>] | all"; + } + + public String getCommand() + { + return "list"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length > 1) + { + if ((args[1].equals("exchanges")) + || (args[1].equals("queues")) + || (args[1].equals("bindings")) + || (args[1].equals("all"))) + { + if (args.length == 2) + { + doList(args[1]); + } + else if (args.length == 3) + { + doList(args[1], args[2]); + } + } + else + { + commandError("Unknown options. ", args); + } + } + else if (args.length < 2) + { + doList("all"); + } + else + { + doList(args[1]); + } + } + + private void doList(String... listItem) + { + if (_tool.getState().getVhost() == null) + { + _console.println("No Virtualhost open. Open a Virtualhost first."); + listVirtualHosts(); + return; + } + + VirtualHost vhost = _tool.getState().getVhost(); + + java.util.List<String> data = null; + + if (listItem[0].equals("queues")) + { + if (listItem.length > 1) + { + data = listQueues(vhost, new AMQShortString(listItem[1])); + } + else + { + Exchange exchange = _tool.getState().getExchange(); + data = listQueues(vhost, exchange); + } + } + + if (listItem[0].equals("exchanges")) + { + data = listExchanges(vhost); + } + + if (listItem[0].equals("bindings")) + { + + if (listItem.length > 1) + { + data = listBindings(vhost, new AMQShortString(listItem[1])); + } + else + { + Exchange exchange = _tool.getState().getExchange(); + + data = listBindings(vhost, exchange); + } + } + + if (data != null) + { + if (data.size() == 1) + { + _console.println("No '" + listItem[0] + "' to display,"); + } + else + { + _console.displayList(true, data.toArray(new String[0])); + } + } + + + if (listItem[0].equals("all")) + { + + boolean displayed = false; + Exchange exchange = _tool.getState().getExchange(); + + //Do the display here for each one so that they are pretty printed + data = listQueues(vhost, exchange); + if (data != null) + { + displayed = true; + _console.displayList(true, data.toArray(new String[0])); + } + + if (exchange == null) + { + data = listExchanges(vhost); + if (data != null) + { + displayed = true; + _console.displayList(true, data.toArray(new String[0])); + } + } + + data = listBindings(vhost, exchange); + if (data != null) + { + displayed = true; + _console.displayList(true, data.toArray(new String[0])); + } + + if (!displayed) + { + _console.println("Nothing to list"); + } + } + } + + private void listVirtualHosts() + { + Collection<VirtualHost> vhosts = ApplicationRegistry.getInstance() + .getVirtualHostRegistry().getVirtualHosts(); + + String[] data = new String[vhosts.size() + 1]; + + data[0] = "Available VirtualHosts"; + + int index = 1; + for (VirtualHost vhost : vhosts) + { + data[index] = vhost.getName(); + index++; + } + + _console.displayList(true, data); + } + + private java.util.List<String> listBindings(VirtualHost vhost, AMQShortString exchangeName) + { + return listBindings(vhost, vhost.getExchangeRegistry().getExchange(exchangeName)); + } + + private java.util.List<String> listBindings(VirtualHost vhost, Exchange exchange) + { + Collection<AMQShortString> queues = vhost.getQueueRegistry().getQueueNames(); + + if (queues == null || queues.size() == 0) + { + return null; + } + + java.util.List<String> data = new LinkedList<String>(); + + data.add("Current Bindings"); + + for (AMQShortString queue : queues) + { + if (exchange != null) + { + if (exchange.isBound(queue)) + { + data.add(queue.toString()); + } + } + else + { + data.add(queue.toString()); + } + } + + return data; + } + + private java.util.List<String> listExchanges(VirtualHost vhost) + { + Collection<AMQShortString> queues = vhost.getExchangeRegistry().getExchangeNames(); + + if (queues == null || queues.size() == 0) + { + return null; + } + + java.util.List<String> data = new LinkedList<String>(); + + data.add("Available Exchanges"); + + for (AMQShortString queue : queues) + { + data.add(queue.toString()); + } + + return data; + } + + private java.util.List<String> listQueues(VirtualHost vhost, AMQShortString exchangeName) + { + return listQueues(vhost, vhost.getExchangeRegistry().getExchange(exchangeName)); + } + + private java.util.List<String> listQueues(VirtualHost vhost, Exchange exchange) + { + Collection<AMQQueue> queues = vhost.getQueueRegistry().getQueues(); + + if (queues == null || queues.size() == 0) + { + return null; + } + + java.util.List<String> data = new LinkedList<String>(); + + data.add("Available Queues"); + + for (AMQQueue queue : queues) + { + if (exchange != null) + { + if (exchange.isBound(queue)) + { + data.add(queue.getName().toString()); + } + } + else + { + data.add(queue.getName().toString()); + } + } + + if (exchange != null) + { + if (queues.size() == 1) + { + return null; + } + } + + return data; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java new file mode 100644 index 0000000000..244a311c30 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ +package org.apache.qpid.tools.messagestore.commands; + +import org.apache.qpid.configuration.Configuration; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Load extends AbstractCommand +{ + public Load(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Loads specified broker configuration file."; + } + + public String usage() + { + return "load <configuration file>"; + } + + public String getCommand() + { + return "load"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length > 2) + { + _console.print("load " + args[1] + ": additional options not understood:"); + for (int i = 2; i < args.length; i++) + { + _console.print(args[i] + " "); + } + _console.println(""); + } + else if (args.length < 2) + { + _console.println("Enter Configuration file."); + String input = _console.readln(); + if (input != null) + { + doLoad(input); + } + else + { + _console.println("Did not recognise config file."); + } + } + else + { + doLoad(args[1]); + } + } + + private void doLoad(String configfile) + { + _console.println("Loading Configuration:" + configfile); + + try + { + _tool.setConfigurationFile(configfile); + } + catch (Configuration.InitException e) + { + _console.println("Unable to open config file due to: '" + e.getMessage() + "'"); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java new file mode 100644 index 0000000000..25cff27445 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java @@ -0,0 +1,205 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +import java.util.LinkedList; +import java.util.List; + +public class Move extends AbstractCommand +{ + + /** + * Since the Coopy command is not associated with a real channel we can safely create our own store context + * for use in the few methods that require one. + */ + protected StoreContext _storeContext = new StoreContext(); + + public Move(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Move messages between queues.";/*\n" + + "The currently selected message set will be moved to the specifed queue.\n" + + "Alternatively the values can be provided on the command line.";*/ + } + + public String usage() + { + return "move to=<queue> [from=<queue>] [msgids=<msgids eg, 1,2,4-10>]"; + } + + public String getCommand() + { + return "move"; + } + + public void execute(String... args) + { + AMQQueue toQueue = null; + AMQQueue fromQueue = _tool.getState().getQueue(); + java.util.List<Long> msgids = _tool.getState().getMessages(); + + if (args.length >= 2) + { + for (String arg : args) + { + if (arg.startsWith("to=")) + { + String queueName = arg.substring(arg.indexOf("=") + 1); + toQueue = _tool.getState().getVhost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + } + + if (arg.startsWith("from=")) + { + String queueName = arg.substring(arg.indexOf("=") + 1); + fromQueue = _tool.getState().getVhost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + } + + if (arg.startsWith("msgids=")) + { + String msgidStr = arg.substring(arg.indexOf("=") + 1); + + // Record the current message selection + java.util.List<Long> currentIDs = _tool.getState().getMessages(); + + // Use the ToolState class to perform the messasge parsing + _tool.getState().setMessages(msgidStr); + msgids = _tool.getState().getMessages(); + + // Reset the original selection of messages + _tool.getState().setMessages(currentIDs); + } + } + } + + if (!checkRequirements(fromQueue, toQueue, msgids)) + { + return; + } + + processIDs(fromQueue, toQueue, msgids); + } + + private void processIDs(AMQQueue fromQueue, AMQQueue toQueue, java.util.List<Long> msgids) + { + Long previous = null; + Long start = null; + + if (msgids == null) + { + msgids = allMessageIDs(fromQueue); + } + + if (msgids == null || msgids.size() == 0) + { + _console.println("No Messages to move."); + return; + } + + for (long id : msgids) + { + if (previous != null) + { + if (id == previous + 1) + { + if (start == null) + { + start = previous; + } + } + else + { + if (start != null) + { + //move a range of ids + doCommand(fromQueue, start, id, toQueue); + start = null; + } + else + { + //move a single id + doCommand(fromQueue, id, id, toQueue); + } + } + } + + previous = id; + } + + if (start != null) + { + //move a range of ids + doCommand(fromQueue, start, previous, toQueue); + } + } + + private List<Long> allMessageIDs(AMQQueue fromQueue) + { + List<Long> ids = new LinkedList<Long>(); + + if (fromQueue != null) + { + List<AMQMessage> messages = fromQueue.getMessagesOnTheQueue(); + if (messages != null) + { + for (AMQMessage msg : messages) + { + ids.add(msg.getMessageId()); + } + } + } + + return ids; + } + + protected boolean checkRequirements(AMQQueue fromQueue, AMQQueue toQueue, List<Long> msgids) + { + if (toQueue == null) + { + _console.println("Destination queue not specifed."); + _console.println(usage()); + return false; + } + + if (fromQueue == null) + { + _console.println("Source queue not specifed."); + _console.println(usage()); + return false; + } + + return true; + } + + protected void doCommand(AMQQueue fromQueue, long start, long id, AMQQueue toQueue) + { + fromQueue.moveMessagesToAnotherQueue(start, id, toQueue.getName().toString(), _storeContext); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java new file mode 100644 index 0000000000..f187e26593 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java @@ -0,0 +1,68 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Purge extends Move +{ + public Purge(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Purge messages from a queue.\n" + + "The currently selected message set will be purged from the specifed queue.\n" + + "Alternatively the values can be provided on the command line."; + } + + public String usage() + { + return "purge from=<queue> [msgids=<msgids eg, 1,2,4-10>]"; + } + + public String getCommand() + { + return "purge"; + } + + + protected boolean checkRequirements(AMQQueue fromQueue, AMQQueue toQueue, java.util.List<Long> msgids) + { + if (fromQueue == null) + { + _console.println("Source queue not specifed."); + _console.println(usage()); + return false; + } + + return true; + } + + protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue) + { + fromQueue.removeMessagesFromQueue(start, end, _storeContext); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java new file mode 100644 index 0000000000..a81bc07c38 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java @@ -0,0 +1,54 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +public class Quit extends AbstractCommand +{ + public Quit(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Quit the tool."; + } + + public String usage() + { + return "quit"; + } + + public String getCommand() + { + return "quit"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals("quit"); + + _tool.quit(); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java new file mode 100644 index 0000000000..fd7d4c3f13 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java @@ -0,0 +1,233 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.tools.messagestore.MessageStoreTool; + +import java.util.LinkedList; +import java.util.StringTokenizer; + +public class Select extends AbstractCommand +{ + + public Select(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Perform a selection."; + } + + public String usage() + { + return "select virtualhost <name> |exchange <name> |queue <name> | msg id=<msgids eg. 1,2,4-10>"; + } + + public String getCommand() + { + return "select"; + } + + public void execute(String... args) + { + assert args.length > 2; + assert args[0].equals("select"); + + if (args.length < 3) + { + if (args[1].equals("show")) + { + doSelect(args[1], null); + } + else + { + _console.print("select : unknown command:"); + _console.println(help()); + } + } + else + { + if (args[1].equals("virtualhost") + || args[1].equals("vhost") + || args[1].equals("exchange") + || args[1].equals("queue") + || args[1].equals("msg") + ) + { + doSelect(args[1], args[2]); + } + else + { + _console.println(help()); + } + } + } + + private void doSelect(String type, String item) + { + if (type.equals("virtualhost")) + { + + VirtualHost vhost = ApplicationRegistry.getInstance() + .getVirtualHostRegistry().getVirtualHost(item); + + if (vhost == null) + { + _console.println("Virtualhost '" + item + "' not found."); + } + else + { + _tool.getState().setVhost(vhost); + } + } + + if (type.equals("exchange")) + { + + VirtualHost vhost = _tool.getState().getVhost(); + + if (vhost == null) + { + _console.println("No Virtualhost open. Open a Virtualhost first."); + return; + } + + + Exchange exchange = vhost.getExchangeRegistry().getExchange(new AMQShortString(item)); + + if (exchange == null) + { + _console.println("Exchange '" + item + "' not found."); + } + else + { + _tool.getState().setExchange(exchange); + } + + if (_tool.getState().getQueue() != null) + { + if (!exchange.isBound(_tool.getState().getQueue())) + { + _tool.getState().setQueue(null); + } + } + } + + if (type.equals("queue")) + { + VirtualHost vhost = _tool.getState().getVhost(); + + if (vhost == null) + { + _console.println("No Virtualhost open. Open a Virtualhost first."); + return; + } + + AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(item)); + + if (queue == null) + { + _console.println("Queue '" + item + "' not found."); + } + else + { + _tool.getState().setQueue(queue); + + if (_tool.getState().getExchange() == null) + { + for (AMQShortString exchangeName : vhost.getExchangeRegistry().getExchangeNames()) + { + Exchange exchange = vhost.getExchangeRegistry().getExchange(exchangeName); + if (exchange.isBound(queue)) + { + _tool.getState().setExchange(exchange); + break; + } + } + } + + //remove the message selection + _tool.getState().setMessages((java.util.List<Long>) null); + } + } + + if (type.equals("msg")) + { + if (item.startsWith("id=")) + { + StringTokenizer tok = new StringTokenizer(item.substring(item.indexOf("=") + 1), ","); + + java.util.List<Long> msgids = null; + + if (tok.hasMoreTokens()) + { + msgids = new LinkedList<Long>(); + } + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + if (next.contains("-")) + { + Long start = Long.parseLong(next.substring(0, next.indexOf("-"))); + Long end = Long.parseLong(next.substring(next.indexOf("-") + 1)); + + if (end >= start) + { + for (long l = start; l <= end; l++) + { + msgids.add(l); + } + } + } + else + { + msgids.add(Long.parseLong(next)); + } + } + + _tool.getState().setMessages(msgids); + } + + } + + if (type.equals("show")) + { + _console.println(_tool.getState().toString()); + if (_tool.getState().getMessages() != null) + { + _console.print("Msgs:"); + for (Long l : _tool.getState().getMessages()) + { + _console.print(" " + l); + } + _console.println(""); + } + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java new file mode 100644 index 0000000000..8487afba76 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java @@ -0,0 +1,512 @@ +/* + * 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.tools.messagestore.commands; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.apache.qpid.tools.utils.Console; + +import java.util.LinkedList; +import java.util.List; + +public class Show extends AbstractCommand +{ + protected boolean _amqHeaders = false; + protected boolean _routing = false; + protected boolean _msgHeaders = false; + + public Show(MessageStoreTool tool) + { + super(tool); + } + + public String help() + { + return "Shows the messages headers."; + } + + public String usage() + { + return getCommand() + " [show=[all],[msgheaders],[amqheaders],[routing]] [id=<msgid e.g. 1,2,4-10>]"; + } + + public String getCommand() + { + return "show"; + } + + public void execute(String... args) + { + assert args.length > 0; + assert args[0].equals(getCommand()); + + if (args.length < 2) + { + parseArgs("all"); + } + else + { + parseArgs(args); + } + + performShow(); + } + + protected void parseArgs(String... args) + { + List<Long> msgids = null; + + if (args.length >= 2) + { + for (String arg : args) + { + if (arg.startsWith("show=")) + { + _msgHeaders = arg.contains("msgheaders") || arg.contains("all"); + _amqHeaders = arg.contains("amqheaders") || arg.contains("all"); + _routing = arg.contains("routing") || arg.contains("all"); + } + + if (arg.startsWith("id=")) + { + _tool.getState().setMessages(msgids); + } + }//for args + }// if args > 2 + } + + protected void performShow() + { + if (_tool.getState().getVhost() == null) + { + _console.println("No Virtualhost selected. 'DuSelect' a Virtualhost first."); + return; + } + + AMQQueue _queue = _tool.getState().getQueue(); + + List<Long> msgids = _tool.getState().getMessages(); + + if (_queue != null) + { + List<AMQMessage> messages = _queue.getMessagesOnTheQueue(); + if (messages == null || messages.size() == 0) + { + _console.println("No messages on queue"); + return; + } + + List<List> data = createMessageData(msgids, messages, _amqHeaders, _routing, _msgHeaders); + if (data != null) + { + _console.printMap(null, data); + } + else + { + String message = "No data to display."; + if (msgids != null) + { + message += " Is message selection correct? " + _tool.getState().printMessages(); + } + _console.println(message); + } + + } + else + { + _console.println("No Queue specified to show."); + } + } + + /** + * Create the list data for display from the messages. + * + * @param msgids The list of message ids to display + * @param messages A list of messages to format and display. + * @param showHeaders should the header info be shown + * @param showRouting show the routing info be shown + * @param showMessageHeaders show the msg headers be shown + * @return the formated data lists for printing + */ + protected List<List> createMessageData(List<Long> msgids, List<AMQMessage> messages, boolean showHeaders, boolean showRouting, + boolean showMessageHeaders) + { + + // Currenly exposed message properties +// //Printing the content Body +// msg.getContentBodyIterator(); +// //Print the Headers +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getAppId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getAppIdAsString(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getClusterId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getContentType(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getCorrelationId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getDeliveryMode(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getEncoding(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getExpiration(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getHeaders(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getMessageId(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getPriority(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getPropertyFlags(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getReplyTo(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getTimestamp(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getType(); +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getUserId(); +// +// //Print out all the property names +// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getHeaders().getPropertyNames(); +// +// msg.getMessageId(); +// msg.getSize(); +// msg.getArrivalTime(); + +// msg.getDeliveredSubscription(); +// msg.getDeliveredToConsumer(); +// msg.getMessageHandle(); +// msg.getMessageId(); +// msg.getMessagePublishInfo(); +// msg.getPublisher(); + +// msg.getStoreContext(); +// msg.isAllContentReceived(); +// msg.isPersistent(); +// msg.isRedelivered(); +// msg.isRejectedBy(); +// msg.isTaken(); + + //Header setup + + List<List> data = new LinkedList<List>(); + + List<String> id = new LinkedList<String>(); + data.add(id); + id.add(Columns.ID.name()); + id.add(Console.ROW_DIVIDER); + + List<String> exchange = new LinkedList<String>(); + List<String> routingkey = new LinkedList<String>(); + List<String> immediate = new LinkedList<String>(); + List<String> mandatory = new LinkedList<String>(); + if (showRouting) + { + data.add(exchange); + exchange.add(Columns.Exchange.name()); + exchange.add(Console.ROW_DIVIDER); + + data.add(routingkey); + routingkey.add(Columns.RoutingKey.name()); + routingkey.add(Console.ROW_DIVIDER); + + data.add(immediate); + immediate.add(Columns.isImmediate.name()); + immediate.add(Console.ROW_DIVIDER); + + data.add(mandatory); + mandatory.add(Columns.isMandatory.name()); + mandatory.add(Console.ROW_DIVIDER); + } + + List<String> size = new LinkedList<String>(); + List<String> appid = new LinkedList<String>(); + List<String> clusterid = new LinkedList<String>(); + List<String> contenttype = new LinkedList<String>(); + List<String> correlationid = new LinkedList<String>(); + List<String> deliverymode = new LinkedList<String>(); + List<String> encoding = new LinkedList<String>(); + List<String> arrival = new LinkedList<String>(); + List<String> expiration = new LinkedList<String>(); + List<String> priority = new LinkedList<String>(); + List<String> propertyflag = new LinkedList<String>(); + List<String> replyto = new LinkedList<String>(); + List<String> timestamp = new LinkedList<String>(); + List<String> type = new LinkedList<String>(); + List<String> userid = new LinkedList<String>(); + List<String> ispersitent = new LinkedList<String>(); + List<String> isredelivered = new LinkedList<String>(); + List<String> isdelivered = new LinkedList<String>(); + + data.add(size); + size.add(Columns.Size.name()); + size.add(Console.ROW_DIVIDER); + + if (showHeaders) + { + data.add(ispersitent); + ispersitent.add(Columns.isPersistent.name()); + ispersitent.add(Console.ROW_DIVIDER); + + data.add(isredelivered); + isredelivered.add(Columns.isRedelivered.name()); + isredelivered.add(Console.ROW_DIVIDER); + + data.add(isdelivered); + isdelivered.add(Columns.isDelivered.name()); + isdelivered.add(Console.ROW_DIVIDER); + + data.add(appid); + appid.add(Columns.App_ID.name()); + appid.add(Console.ROW_DIVIDER); + + data.add(clusterid); + clusterid.add(Columns.Cluster_ID.name()); + clusterid.add(Console.ROW_DIVIDER); + + data.add(contenttype); + contenttype.add(Columns.Content_Type.name()); + contenttype.add(Console.ROW_DIVIDER); + + data.add(correlationid); + correlationid.add(Columns.Correlation_ID.name()); + correlationid.add(Console.ROW_DIVIDER); + + data.add(deliverymode); + deliverymode.add(Columns.Delivery_Mode.name()); + deliverymode.add(Console.ROW_DIVIDER); + + data.add(encoding); + encoding.add(Columns.Encoding.name()); + encoding.add(Console.ROW_DIVIDER); + + data.add(arrival); + expiration.add(Columns.Arrival.name()); + expiration.add(Console.ROW_DIVIDER); + + data.add(expiration); + expiration.add(Columns.Expiration.name()); + expiration.add(Console.ROW_DIVIDER); + + data.add(priority); + priority.add(Columns.Priority.name()); + priority.add(Console.ROW_DIVIDER); + + data.add(propertyflag); + propertyflag.add(Columns.Property_Flag.name()); + propertyflag.add(Console.ROW_DIVIDER); + + data.add(replyto); + replyto.add(Columns.ReplyTo.name()); + replyto.add(Console.ROW_DIVIDER); + + data.add(timestamp); + timestamp.add(Columns.Timestamp.name()); + timestamp.add(Console.ROW_DIVIDER); + + data.add(type); + type.add(Columns.Type.name()); + type.add(Console.ROW_DIVIDER); + + data.add(userid); + userid.add(Columns.UserID.name()); + userid.add(Console.ROW_DIVIDER); + } + + List<String> msgHeaders = new LinkedList<String>(); + if (showMessageHeaders) + { + data.add(msgHeaders); + msgHeaders.add(Columns.MsgHeaders.name()); + msgHeaders.add(Console.ROW_DIVIDER); + } + + //Add create the table of data + for (AMQMessage msg : messages) + { + if (!includeMsg(msg, msgids)) + { + continue; + } + + id.add("" + msg.getMessageId()); + + size.add("" + msg.getSize()); + + arrival.add("" + msg.getArrivalTime()); + + try + { + ispersitent.add(msg.isPersistent() ? "true" : "false"); + } + catch (AMQException e) + { + ispersitent.add("n/a"); + } + + isredelivered.add(msg.isRedelivered() ? "true" : "false"); + + isdelivered.add(msg.getDeliveredToConsumer() ? "true" : "false"); + +// msg.getMessageHandle(); + + BasicContentHeaderProperties headers = null; + + try + { + headers = ((BasicContentHeaderProperties) msg.getContentHeaderBody().properties); + } + catch (AMQException e) + { + //ignore +// commandError("Unable to read properties for message: " + e.getMessage(), null); + } + + if (headers != null) + { + String appidS = headers.getAppIdAsString(); + appid.add(appidS == null ? "null" : appidS); + + String clusterS = headers.getClusterIdAsString(); + clusterid.add(clusterS == null ? "null" : clusterS); + + String contentS = headers.getContentTypeAsString(); + contenttype.add(contentS == null ? "null" : contentS); + + String correlationS = headers.getCorrelationIdAsString(); + correlationid.add(correlationS == null ? "null" : correlationS); + + deliverymode.add("" + headers.getDeliveryMode()); + + AMQShortString encodeSS = headers.getEncoding(); + encoding.add(encodeSS == null ? "null" : encodeSS.toString()); + + expiration.add("" + headers.getExpiration()); + + FieldTable headerFT = headers.getHeaders(); + msgHeaders.add(headerFT == null ? "none" : "" + headerFT.toString()); + + priority.add("" + headers.getPriority()); + propertyflag.add("" + headers.getPropertyFlags()); + + AMQShortString replytoSS = headers.getReplyTo(); + replyto.add(replytoSS == null ? "null" : replytoSS.toString()); + + timestamp.add("" + headers.getTimestamp()); + + AMQShortString typeSS = headers.getType(); + type.add(typeSS == null ? "null" : typeSS.toString()); + + AMQShortString useridSS = headers.getUserId(); + userid.add(useridSS == null ? "null" : useridSS.toString()); + + MessagePublishInfo info = null; + try + { + info = msg.getMessagePublishInfo(); + } + catch (AMQException e) + { + //ignore + } + + if (info != null) + { + AMQShortString exchangeSS = info.getExchange(); + exchange.add(exchangeSS == null ? "null" : exchangeSS.toString()); + + AMQShortString routingkeySS = info.getRoutingKey(); + routingkey.add(routingkeySS == null ? "null" : routingkeySS.toString()); + + immediate.add(info.isImmediate() ? "true" : "false"); + mandatory.add(info.isMandatory() ? "true" : "false"); + } + +// msg.getPublisher(); -- only used in clustering +// msg.getStoreContext(); +// msg.isAllContentReceived(); + + }// if headers!=null + +// need to access internal map and do lookups. +// msg.isTaken(); +// msg.getDeliveredSubscription(); +// msg.isRejectedBy(); + + } + + // if id only had the header and the divider in it then we have no data to display + if (id.size() == 2) + { + return null; + } + return data; + } + + protected boolean includeMsg(AMQMessage msg, List<Long> msgids) + { + if (msgids == null) + { + return true; + } + + Long msgid = msg.getMessageId(); + + boolean found = false; + + if (msgids != null) + { + //check msgid is in msgids + for (Long l : msgids) + { + if (l.equals(msgid)) + { + found = true; + break; + } + } + } + return found; + } + + public enum Columns + { + ID, + Size, + Exchange, + RoutingKey, + isImmediate, + isMandatory, + isPersistent, + isRedelivered, + isDelivered, + App_ID, + Cluster_ID, + Content_Type, + Correlation_ID, + Delivery_Mode, + Encoding, + Arrival, + Expiration, + Priority, + Property_Flag, + ReplyTo, + Timestamp, + Type, + UserID, + MsgHeaders + } +} + + diff --git a/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java b/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java new file mode 100644 index 0000000000..c27c52eb8e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.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.tools.security; + +import org.apache.commons.codec.binary.Base64; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.DigestException; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; + +public class Passwd +{ + public static void main(String args[]) throws NoSuchAlgorithmException, DigestException, IOException + { + if (args.length != 2) + { + System.out.println("Passwd <username> <password>"); + System.exit(0); + } + + byte[] data = args[1].getBytes("utf-8"); + + MessageDigest md = MessageDigest.getInstance("MD5"); + + for (byte b : data) + { + md.update(b); + } + + byte[] digest = md.digest(); + + Base64 b64 = new Base64(); + + byte[] encoded = b64.encode(digest); + + output(args[0], encoded); + } + + private static void output(String user, byte[] encoded) throws IOException + { + +// File passwdFile = new File("qpid.passwd"); + + PrintStream ps = new PrintStream(System.out); + + user += ":"; + ps.write(user.getBytes("utf-8")); + + for (byte b : encoded) + { + ps.write(b); + } + + ps.println(); + + ps.flush(); + ps.close(); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java new file mode 100644 index 0000000000..986fea32cc --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java @@ -0,0 +1,51 @@ +/* + * 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.tools.utils; + +public interface CommandParser +{ + /** + * If there is more than one command received on the last parse request. + * + * Subsequent calls to parse will utilise this input rather than reading new data from the input source + * @return boolean + */ + boolean more(); + + /** + * True if the currently parsed command has been requested as a background operation + * + * @return boolean + */ + boolean isBackground(); + + /** + * Parses user commands, and groups tokens in the + * String[] format that all Java main's love. + * + * If more than one command is provided in one input line then the more() method will return true. + * A subsequent call to parse() will continue to parse that input line before reading new input. + * + * @return <code>input</code> split in args[] format; null if eof. + * @throws java.io.IOException if there is a problem reading from the input stream + */ + String[] parse() throws java.io.IOException; +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java new file mode 100644 index 0000000000..cf457d1ea5 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java @@ -0,0 +1,90 @@ +/* + * 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.tools.utils; + +import java.util.List; + +public interface Console +{ + public enum CellFormat + { + CENTRED, LEFT, RIGHT + } + + public static String ROW_DIVIDER = "*divider"; + + public void print(String... message); + + public void println(String... message); + + public String readln(); + + /** + * Reads and parses the command line. + * + * + * @return The next command or null + */ + public String[] readCommand(); + + public CommandParser getCommandParser(); + + public void setCommandParser(CommandParser parser); + + /** + * + * Prints the list of String nicely. + * + * +-------------+ + * | Heading | + * +-------------+ + * | Item 1 | + * | Item 2 | + * | Item 3 | + * +-------------+ + * + * @param hasTitle should list[0] be used as a heading + * @param list The list of Strings to display + */ + public void displayList(boolean hasTitle, String... list); + + /** + * + * Prints the list of String nicely. + * + * +----------------------------+ + * | Heading | + * +----------------------------+ + * | title | title | .. + * +----------------------------+ + * | Item 2 | value 2 | .. + * +----------------------------+ (*divider) + * | Item 3 | value 2 | .. + * +----------------------------+ + * + * @param title The title to display if any + * @param entries the entries to display in a map. + */ + void printMap(String title, List<List> entries); + + + public void close(); +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java new file mode 100644 index 0000000000..09444ccdd7 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java @@ -0,0 +1,121 @@ +/* + * 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.tools.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.StringTokenizer; + +public class SimpleCommandParser implements CommandParser +{ + private static final String COMMAND_SEPERATOR = ";"; + + /** Input source of commands */ + protected BufferedReader _reader; + + /** The next list of commands from the command line */ + private StringBuilder _nextCommand = null; + + public SimpleCommandParser(BufferedReader reader) + { + _reader = reader; + } + + public boolean more() + { + return _nextCommand != null; + } + + public boolean isBackground() + { + return false; + } + + public String[] parse() throws IOException + { + String[] commands = null; + + String input = null; + + if (_nextCommand == null) + { + input = _reader.readLine(); + } + else + { + input = _nextCommand.toString(); + _nextCommand = null; + } + + if (input == null) + { + return null; + } + + StringTokenizer tok = new StringTokenizer(input, " "); + + int tokenCount = tok.countTokens(); + int index = 0; + + if (tokenCount > 0) + { + commands = new String[tokenCount]; + boolean commandComplete = false; + + while (tok.hasMoreTokens()) + { + String next = tok.nextToken(); + + if (next.equals(COMMAND_SEPERATOR)) + { + commandComplete = true; + _nextCommand = new StringBuilder(); + continue; + } + + if (commandComplete) + { + _nextCommand.append(next); + _nextCommand.append(" "); + } + else + { + commands[index] = next; + index++; + } + } + + } + + //Reduce the String[] if not all the tokens were used in this command. + // i.e. there is more than one command on the line. + if (index != tokenCount) + { + String[] shortCommands = new String[index]; + System.arraycopy(commands, 0, shortCommands, 0, index); + return shortCommands; + } + else + { + return commands; + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java new file mode 100644 index 0000000000..ec080a4611 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java @@ -0,0 +1,363 @@ +/* + * 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.tools.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +public class SimpleConsole implements Console +{ + /** SLF4J Logger. */ + private static Logger _devlog = LoggerFactory.getLogger(SimpleConsole.class); + + /** Console Writer. */ + protected static BufferedWriter _consoleWriter; + + /** Console Reader. */ + protected static BufferedReader _consoleReader; + + /** Parser for command-line input. */ + protected CommandParser _parser; + + public SimpleConsole(BufferedWriter writer, BufferedReader reader) + { + _consoleWriter = writer; + _consoleReader = reader; + _parser = new SimpleCommandParser(_consoleReader); + } + + public void print(String... message) + { + try + { + for (String s : message) + { + _consoleWriter.write(s); + } + _consoleWriter.flush(); + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to write:" + message); + } + + } + + public void println(String... message) + { + print(message); + print(System.getProperty("line.separator")); + } + + + public String readln() + { + try + { + return _consoleReader.readLine(); + } + catch (IOException e) + { + _devlog.debug("Unable to read input due to:" + e.getMessage()); + return null; + } + } + + public String[] readCommand() + { + try + { + return _parser.parse(); + } + catch (IOException e) + { + _devlog.error("Error reading command:" + e.getMessage()); + return new String[0]; + } + } + + public CommandParser getCommandParser() + { + return _parser; + } + + public void setCommandParser(CommandParser parser) + { + _parser = parser; + } + + public void displayList(boolean hasTitle, String... list) + { + java.util.List<java.util.List> data = new LinkedList<List>(); + + java.util.List<String> values = new LinkedList<String>(); + + data.add(values); + + for (String value : list) + { + values.add(value); + } + + if (hasTitle) + { + values.add(1, "*divider"); + } + + printMap(null, data); + } + + /** + * + * Prints the list of String nicely. + * + * +----------------------------+ + * | Heading | + * +----------------------------+ + * | title | title | .. + * +----------------------------+ + * | Item 2 | value 2 | .. + * | Item 3 | value 2 | .. + * +----------------------------+ + * + * @param title The title to display if any + * @param entries the entries to display in a map. + */ + public void printMap(String title, java.util.List<java.util.List> entries) + { + try + { + int columns = entries.size(); + + int[] columnWidth = new int[columns]; + + // calculate row count + int rowMax = 0; + + //the longest item + int itemMax = 0; + + for (int i = 0; i < columns; i++) + { + int columnIRowMax = entries.get(i).size(); + + if (columnIRowMax > rowMax) + { + rowMax = columnIRowMax; + } + for (Object values : entries.get(i)) + { + if (values.toString().equals(Console.ROW_DIVIDER)) + { + continue; + } + + int itemLength = values.toString().length(); + + //note for single width + if (itemLength > itemMax) + { + itemMax = itemLength; + } + + //note for mulit width + if (itemLength > columnWidth[i]) + { + columnWidth[i] = itemLength; + } + + } + } + + int tableWidth = 0; + + + for (int i = 0; i < columns; i++) + { + // plus 2 for the space padding + columnWidth[i] += 2; + } + for (int size : columnWidth) + { + tableWidth += size; + } + tableWidth += (columns - 1); + + if (title != null) + { + if (title.length() > tableWidth) + { + tableWidth = title.length(); + } + + printCellRow("+", "-", tableWidth); + + printCell(CellFormat.CENTRED, "|", tableWidth, " " + title + " ", 0); + _consoleWriter.newLine(); + + } + + //put top line | or bottom of title + printCellRow("+", "-", tableWidth); + + //print the table data + int row = 0; + + for (; row < rowMax; row++) + { + for (int i = 0; i < columns; i++) + { + java.util.List columnData = entries.get(i); + + String value; + // does this column have a value for this row + if (columnData.size() > row) + { + value = " " + columnData.get(row).toString() + " "; + } + else + { + value = " "; + } + + if (i == 0 && value.equals(" " + Console.ROW_DIVIDER + " ")) + { + printCellRow("+", "-", tableWidth); + //move on to the next row + break; + } + else + { + printCell(CellFormat.LEFT, "|", columnWidth[i], value, i); + } + + // if it is the last row then do a new line. + if (i == columns - 1) + { + _consoleWriter.newLine(); + } + } + } + + printCellRow("+", "-", tableWidth); + + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to write."); + } + } + + public void close() + { + + try + { + _consoleReader.close(); + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to close reader."); + } + + try + { + + _consoleWriter.close(); + } + catch (IOException e) + { + _devlog.error(e.getMessage() + ": Occured whilst trying to close writer."); + } + + } + + private void printCell(CellFormat format, String edge, int cellWidth, String cell, int column) throws IOException + { + int pad = cellWidth - cell.length(); + + if (column == 0) + { + _consoleWriter.write(edge); + } + + switch (format) + { + case CENTRED: + printPad(" ", pad / 2); + break; + case RIGHT: + printPad(" ", pad); + break; + } + + _consoleWriter.write(cell); + + + switch (format) + { + case CENTRED: + // if pad isn't even put the extra one on the right + if (pad % 2 == 0) + { + printPad(" ", pad / 2); + } + else + { + printPad(" ", (pad / 2) + 1); + } + break; + case LEFT: + printPad(" ", pad); + break; + } + + + _consoleWriter.write(edge); + + } + + private void printCellRow(String edge, String mid, int cellWidth) throws IOException + { + _consoleWriter.write(edge); + + printPad(mid, cellWidth); + + _consoleWriter.write(edge); + _consoleWriter.newLine(); + } + + private void printPad(String padChar, int count) throws IOException + { + for (int i = 0; i < count; i++) + { + _consoleWriter.write(padChar); + } + } + + +} diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java index 8391481aeb..3dbcb1c14b 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java @@ -14,15 +14,14 @@ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations - * under the License. - * + * under the License. * + * */ package org.apache.qpid.server.exchange; import java.util.HashSet; import java.util.LinkedList; -import java.util.List; import junit.framework.Assert; import junit.framework.TestCase; @@ -32,13 +31,12 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.RequiredDeliveryException; -import org.apache.qpid.server.messageStore.MemoryMessageStore; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MessageHandleFactory; import org.apache.qpid.server.registry.ApplicationRegistry; -// import org.apache.qpid.server.store.MemoryMessageStore; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.txn.NonTransactionalContext; import org.apache.qpid.server.txn.TransactionalContext; @@ -57,7 +55,6 @@ public class DestWildExchangeTest extends TestCase { _exchange = new DestWildExchange(); _vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next(); - // _store = new MemoryMessageStore(); _store = new MemoryMessageStore(); _context = new StoreContext(); } @@ -117,7 +114,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has no route and should fail to be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); } @@ -175,6 +173,8 @@ public class DestWildExchangeTest extends TestCase } catch (AMQException nre) { } + { + } Assert.assertEquals(0, queue.getMessageCount()); } @@ -269,7 +269,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has no route and should fail to be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); } @@ -333,7 +334,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -365,7 +367,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -405,7 +408,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -444,7 +448,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -483,7 +488,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -503,7 +509,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -523,7 +530,8 @@ public class DestWildExchangeTest extends TestCase fail("Message has route and should not be routed"); } catch (AMQException nre) - { } + { + } Assert.assertEquals(0, queue.getMessageCount()); @@ -533,9 +541,9 @@ public class DestWildExchangeTest extends TestCase { MessagePublishInfo info = new PublishInfo(new AMQShortString(s)); - TransactionalContext trancontext = - new NonTransactionalContext(_store, _context, null, new LinkedList<RequiredDeliveryException>(), - new HashSet<Long>()); + TransactionalContext trancontext = new NonTransactionalContext(_store, _context, null, + new LinkedList<RequiredDeliveryException>(), + new HashSet<Long>()); AMQMessage message = new AMQMessage(0L, info, trancontext); message.setContentHeaderBody(new ContentHeaderBody()); diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java index 10450f880f..7b084dd268 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.exchange; diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java index 89b0e068d9..0c0d8f471e 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java +++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.protocol; diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java index a7e5c0d1d0..dd9f3e7723 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java @@ -1,26 +1,29 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; import junit.framework.TestCase; import org.apache.qpid.AMQException; -import org.apache.qpid.server.messageStore.MessageStore; -import org.apache.qpid.server.messageStore.MemoryMessageStore; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.MemoryMessageStore; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.registry.IApplicationRegistry; @@ -56,6 +59,7 @@ public class AMQQueueAlertTest extends TestCase private TransactionManager _txm = new MemoryTransactionManager(); private StoreContext _storeContext = new StoreContext(); + private TransactionalContext _transactionalContext = new NonTransactionalContext(_messageStore, _storeContext, null, new LinkedList<RequiredDeliveryException>(), diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java index acd5e0772f..32dba5e15d 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java @@ -1,18 +1,21 @@ /* * - * Copyright (c) 2006 The Apache Software Foundation + * 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 * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * 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. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. * */ package org.apache.qpid.server.queue; @@ -32,9 +35,9 @@ import org.apache.qpid.server.txn.TransactionalContext; import org.apache.qpid.server.txn.NonTransactionalContext; import org.apache.qpid.server.txn.TransactionManager; import org.apache.qpid.server.txn.MemoryTransactionManager; -import org.apache.qpid.server.messageStore.MessageStore; +import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.server.messageStore.MemoryMessageStore; +import org.apache.qpid.server.store.MemoryMessageStore; import javax.management.JMException; import java.util.LinkedList; @@ -135,7 +138,6 @@ public class AMQQueueMBeanTest extends TestCase public void testExceptions() throws Exception { - /* try { _queueMBean.viewMessages(0, 3); @@ -182,7 +184,7 @@ public class AMQQueueMBeanTest extends TestCase catch (JMException ex) { - }*/ + } } private AMQMessage message(final boolean immediate) throws AMQException |
