summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Anthony Giusti <kgiusti@apache.org>2011-06-21 19:58:01 +0000
committerKenneth Anthony Giusti <kgiusti@apache.org>2011-06-21 19:58:01 +0000
commit9e9da9a82c79f6f6e15ba7ba86c2554932654cda (patch)
tree543da99341f5f24cd72baa5f31f3594f86bd3308
parent15c6e1552997bc618b01faac3a2ceabbeeba7946 (diff)
downloadqpid-python-9e9da9a82c79f6f6e15ba7ba86c2554932654cda.tar.gz
QPID-3079: merge latest trunk
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/qpid-3079@1138153 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/bindings/qmf/python/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf/ruby/Makefile.am2
-rw-r--r--qpid/cpp/bindings/qmf2/python/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf2/ruby/Makefile.am2
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Session.cpp25
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Session.h2
-rw-r--r--qpid/cpp/bindings/qpid/python/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qpid/ruby/Makefile.am2
-rw-r--r--qpid/cpp/configure.ac4
-rw-r--r--qpid/cpp/examples/messaging/drain.cpp2
-rw-r--r--qpid/cpp/examples/messaging/spout.cpp2
-rw-r--r--qpid/cpp/include/qpid/framing/FieldTable.h2
-rw-r--r--qpid/cpp/include/qpid/messaging/Connection.h28
-rw-r--r--qpid/cpp/include/qpid/messaging/Message.h79
-rw-r--r--qpid/cpp/include/qpid/messaging/Session.h4
-rw-r--r--qpid/cpp/managementgen/Makefile.am11
-rw-r--r--qpid/cpp/src/CMakeLists.txt7
-rw-r--r--qpid/cpp/src/Makefile.am2
-rw-r--r--qpid/cpp/src/qmf/ConsoleSession.cpp2
-rw-r--r--qpid/cpp/src/qmf/engine/ResilientConnection.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.cpp7
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.h2
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.h2
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.cpp12
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionState.h8
-rw-r--r--qpid/cpp/src/qpid/broker/Daemon.cpp5
-rw-r--r--qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp10
-rw-r--r--qpid/cpp/src/qpid/broker/ExpiryPolicy.h12
-rw-r--r--qpid/cpp/src/qpid/broker/HeadersExchange.cpp9
-rw-r--r--qpid/cpp/src/qpid/broker/Link.cpp2
-rw-r--r--qpid/cpp/src/qpid/broker/Message.cpp55
-rw-r--r--qpid/cpp/src/qpid/broker/Message.h28
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.cpp135
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.h37
-rw-r--r--qpid/cpp/src/qpid/broker/QueueCleaner.cpp18
-rw-r--r--qpid/cpp/src/qpid/broker/QueueCleaner.h14
-rw-r--r--qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.cpp13
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.h3
-rw-r--r--qpid/cpp/src/qpid/broker/RateTracker.cpp51
-rw-r--r--qpid/cpp/src/qpid/broker/RateTracker.h57
-rw-r--r--qpid/cpp/src/qpid/broker/SemanticState.cpp3
-rw-r--r--qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp11
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionImpl.cpp10
-rw-r--r--qpid/cpp/src/qpid/client/Connector.h2
-rw-r--r--qpid/cpp/src/qpid/client/RdmaConnector.cpp6
-rw-r--r--qpid/cpp/src/qpid/client/SslConnector.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/TCPConnector.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/TCPConnector.h2
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp26
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h4
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp21
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp38
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h1
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h2
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp11
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h11
-rw-r--r--qpid/cpp/src/qpid/client/windows/SslConnector.cpp4
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.cpp66
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.h14
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp1
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterSettings.h3
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterTimer.cpp4
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.cpp19
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.h5
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp95
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.h42
-rw-r--r--qpid/cpp/src/qpid/cluster/FailoverExchange.cpp26
-rw-r--r--qpid/cpp/src/qpid/cluster/FailoverExchange.h10
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.cpp91
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.h13
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateExchange.cpp27
-rw-r--r--qpid/cpp/src/qpid/console/SessionManager.cpp3
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeaderBody.h12
-rw-r--r--qpid/cpp/src/qpid/messaging/Session.cpp3
-rw-r--r--qpid/cpp/src/qpid/messaging/SessionImpl.h2
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIO.h4
-rw-r--r--qpid/cpp/src/qpid/sys/AtomicValue_gcc.h11
-rw-r--r--qpid/cpp/src/qpid/sys/ProtocolFactory.h3
-rw-r--r--qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp24
-rw-r--r--qpid/cpp/src/qpid/sys/Socket.h23
-rw-r--r--qpid/cpp/src/qpid/sys/SocketAddress.h2
-rw-r--r--qpid/cpp/src/qpid/sys/SslPlugin.cpp9
-rw-r--r--qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp29
-rw-r--r--qpid/cpp/src/qpid/sys/Timer.cpp6
-rw-r--r--qpid/cpp/src/qpid/sys/Timer.h8
-rw-r--r--qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp14
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/LockFile.cpp3
-rw-r--r--qpid/cpp/src/qpid/sys/posix/Socket.cpp111
-rw-r--r--qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp32
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslIo.cpp2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslIo.h2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp4
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.h2
-rw-r--r--qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp14
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/Socket.cpp91
-rw-r--r--qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp2
-rw-r--r--qpid/cpp/src/tests/BrokerMgmtAgent.cpp3
-rw-r--r--qpid/cpp/src/tests/ClientSessionTest.cpp7
-rw-r--r--qpid/cpp/src/tests/ForkedBroker.cpp3
-rw-r--r--qpid/cpp/src/tests/MessagingSessionTests.cpp72
-rw-r--r--qpid/cpp/src/tests/QueueTest.cpp4
-rw-r--r--qpid/cpp/src/tests/SocketProxy.h4
-rw-r--r--qpid/cpp/src/tests/brokertest.py15
-rwxr-xr-xqpid/cpp/src/tests/cluster_test_logs.py2
-rwxr-xr-xqpid/cpp/src/tests/cluster_tests.py185
-rwxr-xr-xqpid/cpp/src/tests/federation.py13
-rw-r--r--qpid/cpp/xml/cluster.xml40
-rwxr-xr-xqpid/doc/book/build-book.sh12
-rw-r--r--qpid/doc/website/README.txt28
-rwxr-xr-xqpid/doc/website/build.sh53
-rw-r--r--qpid/doc/website/content/.htaccess20
-rw-r--r--qpid/doc/website/content/acknowledgements.html39
-rw-r--r--qpid/doc/website/content/amqp.html71
-rw-r--r--qpid/doc/website/content/compatibility.html386
-rw-r--r--qpid/doc/website/content/documentation.html92
-rw-r--r--qpid/doc/website/content/download.cgi26
-rw-r--r--qpid/doc/website/content/download.html304
-rw-r--r--qpid/doc/website/content/getting_involved.html69
-rw-r--r--qpid/doc/website/content/getting_started.html73
-rw-r--r--qpid/doc/website/content/images/README.txt1
-rw-r--r--qpid/doc/website/content/images/jprofiler.pngbin584 -> 0 bytes
-rw-r--r--qpid/doc/website/content/images/structure101.jpgbin3465 -> 0 bytes
-rw-r--r--qpid/doc/website/content/index.html91
-rw-r--r--qpid/doc/website/content/mailing_lists.html82
-rw-r--r--qpid/doc/website/content/people.html99
-rw-r--r--qpid/doc/website/content/qpid_integrated_with.html40
-rw-r--r--qpid/doc/website/content/qpid_project_etiquette_guide.html104
-rw-r--r--qpid/doc/website/content/release_notes_0.10.html379
-rw-r--r--qpid/doc/website/content/release_notes_0.8.html437
-rw-r--r--qpid/doc/website/content/source_repository.html74
-rw-r--r--qpid/doc/website/example/images/asf-logo.pngbin4735 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/asf_logo.gifbin7279 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/header.pngbin22354 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/main_body.pngbin211 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/main_bottom.pngbin1719 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/main_top.pngbin295 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/menu_body.pngbin198 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/menu_bottom.pngbin264 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/menu_top.pngbin258 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/qpid-logo-900x480.pngbin39038 -> 0 bytes
-rw-r--r--qpid/doc/website/example/images/qpid-logo.pngbin5775 -> 0 bytes
-rw-r--r--qpid/doc/website/example/index.html185
-rw-r--r--qpid/doc/website/example/style.css263
-rw-r--r--qpid/doc/website/template/images/asf-logo.pngbin4735 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/asf_logo.gifbin7279 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/header.pngbin22576 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/main_body.pngbin211 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/main_bottom.pngbin1719 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/main_top.pngbin295 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/menu_body.pngbin198 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/menu_bottom.pngbin264 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/menu_top.pngbin258 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/qpid-logo-900x480.pngbin39038 -> 0 bytes
-rw-r--r--qpid/doc/website/template/images/qpid-logo.pngbin6600 -> 0 bytes
-rw-r--r--qpid/doc/website/template/style.css276
-rw-r--r--qpid/doc/website/template/template.html126
-rwxr-xr-xqpid/doc/website/tools/generate56
-rwxr-xr-xqpid/doc/website/tools/wrap44
-rw-r--r--qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java2
-rw-r--r--qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java9
-rw-r--r--qpid/java/broker/etc/config.xml4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java61
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java25
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java14
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java77
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java14
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java34
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java35
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java54
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java58
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java56
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java213
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java532
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java53
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java47
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java264
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java124
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java56
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java112
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java30
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java13
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java5
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java99
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java78
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQException.java16
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java83
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java10
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java13
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java214
-rw-r--r--qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml4
-rw-r--r--qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml3
-rw-r--r--qpid/java/systests/etc/config-systests-firewall-2.xml4
-rw-r--r--qpid/java/systests/etc/config-systests-firewall-3.xml4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java34
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java2
-rw-r--r--qpid/python/qpid/messaging/driver.py3
-rw-r--r--qpid/specs/management-schema.xml1
-rwxr-xr-xqpid/tools/src/py/qpid-cluster9
-rwxr-xr-xqpid/tools/src/py/qpid-config4
219 files changed, 3192 insertions, 4878 deletions
diff --git a/qpid/cpp/bindings/qmf/python/Makefile.am b/qpid/cpp/bindings/qmf/python/Makefile.am
index 421590f189..8abad32959 100644
--- a/qpid/cpp/bindings/qmf/python/Makefile.am
+++ b/qpid/cpp/bindings/qmf/python/Makefile.am
@@ -30,11 +30,13 @@ BUILT_SOURCES = $(generated_file_list)
SWIG_FLAGS = -w362,401
$(generated_file_list): $(srcdir)/python.i $(srcdir)/../qmfengine.i
- swig -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o qmfengine.cpp $(srcdir)/python.i
+ $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o qmfengine.cpp $(srcdir)/python.i
pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _qmfengine.la
+qenginedir = $(pyexecdir)
+qengine_PYTHON = qmfengine.py qmf.py
#_qmfengine_la_LDFLAGS = -avoid-version -module -shrext "$(PYTHON_SO)"
#_qmfengine_la_LDFLAGS = -avoid-version -module -shrext ".so"
diff --git a/qpid/cpp/bindings/qmf/ruby/Makefile.am b/qpid/cpp/bindings/qmf/ruby/Makefile.am
index 395d64ff90..de8c4d10d5 100644
--- a/qpid/cpp/bindings/qmf/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qmf/ruby/Makefile.am
@@ -35,7 +35,7 @@ qmfengine.cpp: $(srcdir)/ruby.i $(srcdir)/../qmfengine.i
rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = qmfengine.la
-qmfengine_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
+qmfengine_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)"
qmfengine_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfengine.la
qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
nodist_qmfengine_la_SOURCES = qmfengine.cpp
diff --git a/qpid/cpp/bindings/qmf2/python/Makefile.am b/qpid/cpp/bindings/qmf2/python/Makefile.am
index 7adc62eddb..3dc04e832f 100644
--- a/qpid/cpp/bindings/qmf2/python/Makefile.am
+++ b/qpid/cpp/bindings/qmf2/python/Makefile.am
@@ -30,12 +30,12 @@ BUILT_SOURCES = $(generated_file_list)
SWIG_FLAGS = -w362,401
$(generated_file_list): $(srcdir)/python.i $(srcdir)/../qmf2.i $(srcdir)/../../swig_python_typemaps.i
- swig -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqmf2.cpp $(srcdir)/python.i
+ $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqmf2.cpp $(srcdir)/python.i
pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _cqmf2.la
-cqpiddir = $(pythondir)
+cqpiddir = $(pyexecdir)
cqpid_PYTHON = qmf2.py cqmf2.py
_cqmf2_la_LDFLAGS = -avoid-version -module -shared
diff --git a/qpid/cpp/bindings/qmf2/ruby/Makefile.am b/qpid/cpp/bindings/qmf2/ruby/Makefile.am
index 8e11a204b2..97bbc6f385 100644
--- a/qpid/cpp/bindings/qmf2/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qmf2/ruby/Makefile.am
@@ -34,7 +34,7 @@ rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = cqmf2.la
dist_rubylib_DATA = qmf2.rb
-cqmf2_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
+cqmf2_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)"
cqmf2_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqmf2 $(top_builddir)/src/libqmf2.la
cqmf2_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
nodist_cqmf2_la_SOURCES = cqmf2.cpp
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp
index 4a6199f108..0e918769a3 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp
@@ -248,6 +248,31 @@ namespace Messaging {
}
}
+ void Session::AcknowledgeUpTo(Message ^ message)
+ {
+ AcknowledgeUpTo(message, false);
+ }
+
+ void Session::AcknowledgeUpTo(Message ^ message, bool sync)
+ {
+ System::Exception ^ newException = nullptr;
+
+ try
+ {
+ sessionp->acknowledgeUpTo(*(message->NativeMessage), sync);
+ }
+ catch (const ::qpid::types::Exception & error)
+ {
+ String ^ errmsg = gcnew String(error.what());
+ newException = gcnew QpidException(errmsg);
+ }
+
+ if (newException != nullptr)
+ {
+ throw newException;
+ }
+ }
+
void Session::Reject(Message ^ message)
{
System::Exception ^ newException = nullptr;
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Session.h b/qpid/cpp/bindings/qpid/dotnet/src/Session.h
index 4d4cad75c4..4b98a37f18 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Session.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Session.h
@@ -104,6 +104,8 @@ namespace Messaging {
void Acknowledge(bool sync);
void Acknowledge(Message ^ message);
void Acknowledge(Message ^ message, bool sync);
+ void AcknowledgeUpTo(Message ^ message);
+ void AcknowledgeUpTo(Message ^ message, bool sync);
void Reject(Message ^);
void Release(Message ^);
void Sync();
diff --git a/qpid/cpp/bindings/qpid/python/Makefile.am b/qpid/cpp/bindings/qpid/python/Makefile.am
index 9aef179db7..dd25f34829 100644
--- a/qpid/cpp/bindings/qpid/python/Makefile.am
+++ b/qpid/cpp/bindings/qpid/python/Makefile.am
@@ -30,12 +30,12 @@ BUILT_SOURCES = $(generated_file_list)
SWIG_FLAGS = -w362,401
$(generated_file_list): $(srcdir)/python.i $(srcdir)/../qpid.i $(srcdir)/../../swig_python_typemaps.i
- swig -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o cqpid.cpp $(srcdir)/python.i
+ $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o cqpid.cpp $(srcdir)/python.i
pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _cqpid.la
-cqpiddir = $(pythondir)
+cqpiddir = $(pyexecdir)
cqpid_PYTHON = cqpid.py
_cqpid_la_LDFLAGS = -avoid-version -module -shared
diff --git a/qpid/cpp/bindings/qpid/ruby/Makefile.am b/qpid/cpp/bindings/qpid/ruby/Makefile.am
index d92eb969de..a2a5dd76bd 100644
--- a/qpid/cpp/bindings/qpid/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qpid/ruby/Makefile.am
@@ -33,7 +33,7 @@ cqpid.cpp: $(srcdir)/ruby.i $(srcdir)/../qpid.i $(srcdir)/../../swig_ruby_typema
rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = cqpid.la
-cqpid_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
+cqpid_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)"
cqpid_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidmessaging -lqpidtypes \
$(top_builddir)/src/libqpidmessaging.la $(top_builddir)/src/libqpidtypes.la
cqpid_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
diff --git a/qpid/cpp/configure.ac b/qpid/cpp/configure.ac
index 43a32d3ad7..092694d56b 100644
--- a/qpid/cpp/configure.ac
+++ b/qpid/cpp/configure.ac
@@ -68,8 +68,10 @@ if test x$GXX = xyes; then
# The following warnings are deliberately omitted, they warn on valid code.
# -Wunreachable-code -Wpadded -Winline
# -Wshadow - warns about boost headers.
+ # Can't test for -Werror as whether it fails or not depends on what's in
+ # CFLAGS/CXXFLAGS. In any case it's been in gcc for a long time (since 2.95 at least)
if test "${enableval}" = yes; then
- gl_COMPILER_FLAGS(-Werror)
+ COMPILER_FLAGS="-Werror"
gl_COMPILER_FLAGS(-pedantic)
gl_COMPILER_FLAGS(-Wall)
gl_COMPILER_FLAGS(-Wextra)
diff --git a/qpid/cpp/examples/messaging/drain.cpp b/qpid/cpp/examples/messaging/drain.cpp
index 5c938e9742..7700244fa8 100644
--- a/qpid/cpp/examples/messaging/drain.cpp
+++ b/qpid/cpp/examples/messaging/drain.cpp
@@ -50,7 +50,7 @@ struct Options : OptionParser
add("broker,b", url, "url of broker to connect to");
add("timeout,t", timeout, "timeout in seconds to wait before exiting");
add("forever,f", forever, "ignore timeout and wait forever");
- add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
+ add("connection-options", connectionOptions, "connection options string in the form {name1:value1, name2:value2}");
add("count,c", count, "number of messages to read before exiting");
}
diff --git a/qpid/cpp/examples/messaging/spout.cpp b/qpid/cpp/examples/messaging/spout.cpp
index 57b955c1de..cd11a7ad81 100644
--- a/qpid/cpp/examples/messaging/spout.cpp
+++ b/qpid/cpp/examples/messaging/spout.cpp
@@ -65,7 +65,7 @@ struct Options : OptionParser
add("property,P", properties, "specify message property");
add("map,M", entries, "specify entry for map content");
add("content", content, "specify textual content");
- add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
+ add("connection-options", connectionOptions, "connection options string in the form {name1:value1, name2:value2}");
}
static bool nameval(const std::string& in, std::string& name, std::string& value)
diff --git a/qpid/cpp/include/qpid/framing/FieldTable.h b/qpid/cpp/include/qpid/framing/FieldTable.h
index fed431129a..e8ec524863 100644
--- a/qpid/cpp/include/qpid/framing/FieldTable.h
+++ b/qpid/cpp/include/qpid/framing/FieldTable.h
@@ -65,6 +65,8 @@ class FieldTable
QPID_COMMON_EXTERN void decode(Buffer& buffer);
QPID_COMMON_EXTERN int count() const;
+ QPID_COMMON_EXTERN size_t size() const { return values.size(); }
+ QPID_COMMON_EXTERN bool empty() { return size() == 0; }
QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value);
QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const;
QPID_COMMON_INLINE_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; }
diff --git a/qpid/cpp/include/qpid/messaging/Connection.h b/qpid/cpp/include/qpid/messaging/Connection.h
index e938f23189..165573e2ef 100644
--- a/qpid/cpp/include/qpid/messaging/Connection.h
+++ b/qpid/cpp/include/qpid/messaging/Connection.h
@@ -54,27 +54,27 @@ class QPID_MESSAGING_CLASS_EXTERN Connection : public qpid::messaging::Handle<Co
* username
* password
* heartbeat
- * tcp-nodelay
- * sasl-mechanism
- * sasl-service
- * sasl-min-ssf
- * sasl-max-ssf
+ * tcp_nodelay
+ * sasl_mechanisms
+ * sasl_service
+ * sasl_min_ssf
+ * sasl_max_ssf
* transport
*
* Reconnect behaviour can be controlled through the following options:
*
* reconnect: true/false (enables/disables reconnect entirely)
- * reconnect-timeout: number of seconds (give up and report failure after specified time)
- * reconnect-limit: n (give up and report failure after specified number of attempts)
- * reconnect-interval-min: number of seconds (initial delay between failed reconnection attempts)
- * reconnect-interval-max: number of seconds (maximum delay between failed reconnection attempts)
- * reconnect-interval: shorthand for setting the same reconnect_interval_min/max
- * reconnect-urls: list of alternate urls to try when connecting
+ * reconnect_timeout: number of seconds (give up and report failure after specified time)
+ * reconnect_limit: n (give up and report failure after specified number of attempts)
+ * reconnect_interval_min: number of seconds (initial delay between failed reconnection attempts)
+ * reconnect_interval_max: number of seconds (maximum delay between failed reconnection attempts)
+ * reconnect_interval: shorthand for setting the same reconnect_interval_min/max
+ * reconnect_urls: list of alternate urls to try when connecting
*
- * The reconnect-interval is the time that the client waits
+ * The reconnect_interval is the time that the client waits
* for after a failed attempt to reconnect before retrying. It
- * starts at the value of the min-retry-interval and is
- * doubled every failure until the value of max-retry-interval
+ * starts at the value of the min_retry_interval and is
+ * doubled every failure until the value of max_retry_interval
* is reached.
*/
QPID_MESSAGING_EXTERN Connection(const std::string& url, const qpid::types::Variant::Map& options = qpid::types::Variant::Map());
diff --git a/qpid/cpp/include/qpid/messaging/Message.h b/qpid/cpp/include/qpid/messaging/Message.h
index 5cd978f2a2..e89a6ce02f 100644
--- a/qpid/cpp/include/qpid/messaging/Message.h
+++ b/qpid/cpp/include/qpid/messaging/Message.h
@@ -55,23 +55,58 @@ class QPID_MESSAGING_CLASS_EXTERN Message
QPID_MESSAGING_EXTERN void setSubject(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getSubject() const;
+ /**
+ * Set the content type (i.e. the MIME type) for the message. This
+ * should be set by the sending application and indicates to
+ * recipients of message how to interpret or decode the content.
+ */
QPID_MESSAGING_EXTERN void setContentType(const std::string&);
+ /**
+ * Returns the content type (i.e. the MIME type) for the
+ * message. This can be used to determine how to decode the
+ * message content.
+ */
QPID_MESSAGING_EXTERN const std::string& getContentType() const;
+ /**
+ * Set an application defined identifier for the message. At
+ * present this must be a stringfied UUID (support for less
+ * restrictive IDs is anticipated however).
+ */
QPID_MESSAGING_EXTERN void setMessageId(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getMessageId() const;
+ /**
+ * Sets the user id of the message. This should in general be the
+ * user-id as which the sending connection authenticated itself as
+ * the messaging infrastructure will verify this. See
+ * Connection::getAuthenticatedUsername()
+ */
QPID_MESSAGING_EXTERN void setUserId(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getUserId() const;
+ /**
+ * Can be used to set application specific correlation identifiers
+ * as part of a protocol for message exchange patterns. E.g. a
+ * request-reponse pattern might require the correlation-id of the
+ * request and response to match, or might use the message-id of
+ * the request as the correlation-id on the response etc.
+ */
QPID_MESSAGING_EXTERN void setCorrelationId(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getCorrelationId() const;
+ /**
+ * Sets a priority level on the message. This may be used by the
+ * messaging infrastructure to prioritise delivery of higher
+ * priority messages.
+ */
QPID_MESSAGING_EXTERN void setPriority(uint8_t);
QPID_MESSAGING_EXTERN uint8_t getPriority() const;
/**
- * Set the time to live for this message in milliseconds.
+ * Set the time to live for this message in milliseconds. This can
+ * be used by the messaging infrastructure to discard messages
+ * that are no longer of relevance.
*/
QPID_MESSAGING_EXTERN void setTtl(Duration ttl);
/**
@@ -79,24 +114,62 @@ class QPID_MESSAGING_CLASS_EXTERN Message
*/
QPID_MESSAGING_EXTERN Duration getTtl() const;
+ /**
+ * Mark the message as durable. This is a hint to the messaging
+ * infrastructure that the message should be persisted or
+ * otherwise stored such that failoures or shutdown do not cause
+ * it to be lost.
+ */
QPID_MESSAGING_EXTERN void setDurable(bool durable);
QPID_MESSAGING_EXTERN bool getDurable() const;
+ /**
+ * The redelivered flag if set implies that the message *may* have
+ * been previously delivered and thus is a hint to the application
+ * or messaging infrastructure that if de-duplication is required
+ * this message should be examined to determine if it is a
+ * duplicate.
+ */
QPID_MESSAGING_EXTERN bool getRedelivered() const;
+ /**
+ * Can be used to provide a hint to the application or messaging
+ * infrastructure that if de-duplication is required this message
+ * should be examined to determine if it is a duplicate.
+ */
QPID_MESSAGING_EXTERN void setRedelivered(bool);
+ /**
+ * In addition to a payload (i.e. the content), messages can
+ * include annotations describing aspectf of the message. In
+ * addition to the standard annotations such as TTL and content
+ * type, application- or context- specific properties can also be
+ * defined. Each message has a map of name values for such custom
+ * properties. The value is specified as a Variant.
+ */
QPID_MESSAGING_EXTERN const qpid::types::Variant::Map& getProperties() const;
QPID_MESSAGING_EXTERN qpid::types::Variant::Map& getProperties();
+ /**
+ * Set the content to the data held in the string parameter. Note:
+ * this is treated as raw bytes and need not be text. Consider
+ * setting the content-type to indicate how the data should be
+ * interpreted by recipients.
+ */
QPID_MESSAGING_EXTERN void setContent(const std::string&);
/**
- * Note that chars are copied.
+ * Copy count bytes from the region pointed to by chars as the
+ * message content.
*/
QPID_MESSAGING_EXTERN void setContent(const char* chars, size_t count);
/** Get the content as a std::string */
QPID_MESSAGING_EXTERN std::string getContent() const;
- /** Get a const pointer to the start of the content data. */
+ /**
+ * Get a const pointer to the start of the content data. The
+ * memory pointed to is owned by the message. The getContentSize()
+ * method indicates how much data there is (i.e. the extent of the
+ * memory region pointed to by the return value of this method).
+ */
QPID_MESSAGING_EXTERN const char* getContentPtr() const;
/** Get the size of content in bytes. */
QPID_MESSAGING_EXTERN size_t getContentSize() const;
diff --git a/qpid/cpp/include/qpid/messaging/Session.h b/qpid/cpp/include/qpid/messaging/Session.h
index 52786eb5f4..428f8aa491 100644
--- a/qpid/cpp/include/qpid/messaging/Session.h
+++ b/qpid/cpp/include/qpid/messaging/Session.h
@@ -78,6 +78,10 @@ class QPID_MESSAGING_CLASS_EXTERN Session : public qpid::messaging::Handle<Sessi
*/
QPID_MESSAGING_EXTERN void acknowledge(Message&, bool sync=false);
/**
+ * Acknowledges all message up to the specified message.
+ */
+ QPID_MESSAGING_EXTERN void acknowledgeUpTo(Message&, bool sync=false);
+ /**
* Rejects the specified message. The broker does not redeliver a
* message that has been rejected. Once a message has been
* acknowledged, it can no longer be rejected.
diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am
index 6c2024ccaa..e10dd63c87 100644
--- a/qpid/cpp/managementgen/Makefile.am
+++ b/qpid/cpp/managementgen/Makefile.am
@@ -19,10 +19,16 @@
qmfpythondir = $(pythondir)
dist_bin_SCRIPTS = \
qmf-gen
-nobase_qmfpython_DATA = \
+
+pkgpyexec_qmfgendir = $(pyexecdir)/qmfgen
+pkgpyexec_qmfgen_PYTHON = \
qmfgen/__init__.py \
qmfgen/generate.py \
qmfgen/schema.py \
+ qmfgen/management-types.xml
+
+pkgpyexec_qmfgentmpldir = $(pyexecdir)/qmfgen/templates
+pkgpyexec_qmfgentmpl_PYTHON = \
qmfgen/templates/Args.h \
qmfgen/templates/Class.cpp \
qmfgen/templates/Class.h \
@@ -32,7 +38,6 @@ nobase_qmfpython_DATA = \
qmfgen/templates/Package.cpp \
qmfgen/templates/Package.h \
qmfgen/templates/V2Package.cpp \
- qmfgen/templates/V2Package.h \
- qmfgen/management-types.xml
+ qmfgen/templates/V2Package.h
EXTRA_DIST = $(nobase_qmfpython_DATA) CMakeLists.txt
diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt
index 0fe2d7e4d0..11554b1034 100644
--- a/qpid/cpp/src/CMakeLists.txt
+++ b/qpid/cpp/src/CMakeLists.txt
@@ -96,7 +96,7 @@ MACRO (add_msvc_version_full verProject verProjectType verProjectFileExt verFN1
inherit_value ("winver_${verProject}_InternalName" "${verProject}")
inherit_value ("winver_${verProject}_OriginalFilename" "${verProject}.${verProjectFileExt}")
inherit_value ("winver_${verProject}_ProductName" "${winver_DESCRIPTION_SUMMARY}")
-
+
# Create strings to be substituted into the template file
set ("winverFileVersionBinary" "${winver_${verProject}_FileVersionBinary}")
set ("winverProductVersionBinary" "${winver_${verProject}_ProductVersionBinary}")
@@ -126,7 +126,7 @@ ENDMACRO (add_msvc_version_full)
#
MACRO (add_msvc_version verProject verProjectType verProjectFileExt)
if (MSVC)
- add_msvc_version_full (${verProject}
+ add_msvc_version_full (${verProject}
${verProjectType}
${verProjectFileExt}
${winver_FILE_VERSION_N1}
@@ -656,7 +656,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL Windows)
set (qpidd_platform_SOURCES
windows/QpiddBroker.cpp
)
-
+
set (qpidmessaging_platform_SOURCES
qpid/messaging/HandleInstantiator.cpp
)
@@ -997,7 +997,6 @@ set (qpidbroker_SOURCES
qpid/broker/QueuePolicy.cpp
qpid/broker/QueueRegistry.cpp
qpid/broker/QueueFlowLimit.cpp
- qpid/broker/RateTracker.cpp
qpid/broker/RecoveryManagerImpl.cpp
qpid/broker/RecoveredEnqueue.cpp
qpid/broker/RecoveredDequeue.cpp
diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am
index 15021cc68b..608afb0660 100644
--- a/qpid/cpp/src/Makefile.am
+++ b/qpid/cpp/src/Makefile.am
@@ -616,8 +616,6 @@ libqpidbroker_la_SOURCES = \
qpid/broker/QueueFlowLimit.h \
qpid/broker/QueueFlowLimit.cpp \
qpid/broker/RateFlowcontrol.h \
- qpid/broker/RateTracker.cpp \
- qpid/broker/RateTracker.h \
qpid/broker/RecoverableConfig.h \
qpid/broker/RecoverableExchange.h \
qpid/broker/RecoverableMessage.h \
diff --git a/qpid/cpp/src/qmf/ConsoleSession.cpp b/qpid/cpp/src/qmf/ConsoleSession.cpp
index 7b839930e1..5df0d83f12 100644
--- a/qpid/cpp/src/qmf/ConsoleSession.cpp
+++ b/qpid/cpp/src/qmf/ConsoleSession.cpp
@@ -66,7 +66,7 @@ Subscription ConsoleSession::subscribe(const string& q, const string& f, const s
//========================================================================================
ConsoleSessionImpl::ConsoleSessionImpl(Connection& c, const string& options) :
- connection(c), domain("default"), maxAgentAgeMinutes(5),
+ connection(c), domain("default"), maxAgentAgeMinutes(5), listenOnDirect(true), strictSecurity(false),
opened(false), thread(0), threadCanceled(false), lastVisit(0), lastAgePass(0),
connectedBrokerInAgentList(false), schemaCache(new SchemaCache())
{
diff --git a/qpid/cpp/src/qmf/engine/ResilientConnection.cpp b/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
index ab65b8d768..41dd9ff00c 100644
--- a/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
+++ b/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
@@ -334,8 +334,7 @@ void ResilientConnectionImpl::notify()
{
if (notifyFd != -1)
{
- int unused_ret; //Suppress warnings about ignoring return value.
- unused_ret = ::write(notifyFd, ".", 1);
+ (void) ::write(notifyFd, ".", 1);
}
}
@@ -432,8 +431,7 @@ void ResilientConnectionImpl::EnqueueEvent(ResilientConnectionEvent::EventKind k
if (notifyFd != -1)
{
- int unused_ret; //Suppress warnings about ignoring return value.
- unused_ret = ::write(notifyFd, ".", 1);
+ (void) ::write(notifyFd, ".", 1);
}
}
diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp
index 240766c443..f80e0f1e61 100644
--- a/qpid/cpp/src/qpid/broker/Broker.cpp
+++ b/qpid/cpp/src/qpid/broker/Broker.cpp
@@ -188,7 +188,7 @@ Broker::Broker(const Broker::Options& conf) :
conf.replayFlushLimit*1024, // convert kb to bytes.
conf.replayHardLimit*1024),
*this),
- queueCleaner(queues, timer),
+ queueCleaner(queues, &timer),
queueEvents(poller,!conf.asyncQueueEvents),
recovery(true),
inCluster(false),
@@ -701,7 +701,7 @@ void Broker::accept() {
}
void Broker::connect(
- const std::string& host, uint16_t port, const std::string& transport,
+ const std::string& host, const std::string& port, const std::string& transport,
boost::function2<void, int, std::string> failed,
sys::ConnectionCodec::Factory* f)
{
@@ -717,7 +717,7 @@ void Broker::connect(
{
url.throwIfEmpty();
const Address& addr=url[0];
- connect(addr.host, addr.port, addr.protocol, failed, f);
+ connect(addr.host, boost::lexical_cast<std::string>(addr.port), addr.protocol, failed, f);
}
uint32_t Broker::queueMoveMessages(
@@ -750,6 +750,7 @@ bool Broker::deferDeliveryImpl(const std::string& ,
void Broker::setClusterTimer(std::auto_ptr<sys::Timer> t) {
clusterTimer = t;
+ queueCleaner.setTimer(clusterTimer.get());
}
const std::string Broker::TCP_TRANSPORT("tcp");
diff --git a/qpid/cpp/src/qpid/broker/Broker.h b/qpid/cpp/src/qpid/broker/Broker.h
index 6d585bf614..40f7b6273f 100644
--- a/qpid/cpp/src/qpid/broker/Broker.h
+++ b/qpid/cpp/src/qpid/broker/Broker.h
@@ -244,7 +244,7 @@ public:
QPID_BROKER_EXTERN void accept();
/** Create a connection to another broker. */
- void connect(const std::string& host, uint16_t port,
+ void connect(const std::string& host, const std::string& port,
const std::string& transport,
boost::function2<void, int, std::string> failed,
sys::ConnectionCodec::Factory* =0);
diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp
index c07e63e68c..8362a9782c 100644
--- a/qpid/cpp/src/qpid/broker/Connection.cpp
+++ b/qpid/cpp/src/qpid/broker/Connection.cpp
@@ -288,11 +288,11 @@ void Connection::raiseConnectEvent() {
}
}
-void Connection::setFederationLink(bool b)
+void Connection::setUserProxyAuth(bool b)
{
- ConnectionState::setFederationLink(b);
+ ConnectionState::setUserProxyAuth(b);
if (mgmtObject != 0)
- mgmtObject->set_federationLink(b);
+ mgmtObject->set_userProxyAuth(b);
}
void Connection::close(connection::CloseCode code, const string& text)
diff --git a/qpid/cpp/src/qpid/broker/Connection.h b/qpid/cpp/src/qpid/broker/Connection.h
index 8f1aa701ef..3522d70b35 100644
--- a/qpid/cpp/src/qpid/broker/Connection.h
+++ b/qpid/cpp/src/qpid/broker/Connection.h
@@ -125,7 +125,7 @@ class Connection : public sys::ConnectionInputHandler,
const std::string& getUserId() const { return ConnectionState::getUserId(); }
const std::string& getMgmtId() const { return mgmtId; }
management::ManagementAgent* getAgent() const { return agent; }
- void setFederationLink(bool b);
+ void setUserProxyAuth(bool b);
/** Connection does not delete the listener. 0 resets. */
void setErrorListener(ErrorListener* l) { errorListener=l; }
ErrorListener* getErrorListener() { return errorListener; }
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
index 3f97e5b9de..270711705e 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
@@ -137,7 +137,9 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper
throw;
}
connection.setFederationLink(clientProperties.get(QPID_FED_LINK));
- connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
+ if (clientProperties.isSet(QPID_FED_TAG)) {
+ connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
+ }
if (connection.isFederationLink()) {
if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){
proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
@@ -256,7 +258,6 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
false ); // disallow interaction
}
std::string supportedMechanismsList;
- bool requestedMechanismIsSupported = false;
Array::const_iterator i;
/*
@@ -269,11 +270,9 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
if (i != supportedMechanisms.begin())
supportedMechanismsList += SPACE;
supportedMechanismsList += (*i)->get<std::string>();
- requestedMechanismIsSupported = true;
}
}
else {
- requestedMechanismIsSupported = false;
/*
The caller has requested a mechanism. If it's available,
make sure it ends up at the head of the list.
@@ -282,7 +281,6 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
string currentMechanism = (*i)->get<std::string>();
if ( requestedMechanism == currentMechanism ) {
- requestedMechanismIsSupported = true;
supportedMechanismsList = currentMechanism + SPACE + supportedMechanismsList;
} else {
if (i != supportedMechanisms.begin())
@@ -292,7 +290,9 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
}
}
- connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG));
+ if (serverProperties.isSet(QPID_FED_TAG)) {
+ connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG));
+ }
FieldTable ft;
ft.setInt(QPID_FED_LINK,1);
diff --git a/qpid/cpp/src/qpid/broker/ConnectionState.h b/qpid/cpp/src/qpid/broker/ConnectionState.h
index 9c31a931d8..fdd3c4ddc0 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionState.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionState.h
@@ -46,6 +46,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
framemax(65535),
heartbeat(0),
heartbeatmax(120),
+ userProxyAuth(false), // Can proxy msgs with non-matching auth ids when true (used by federation links & clustering)
federationLink(true),
clientSupportsThrottling(false),
clusterOrderOut(0)
@@ -67,8 +68,10 @@ class ConnectionState : public ConnectionToken, public management::Manageable
void setUrl(const std::string& _url) { url = _url; }
const std::string& getUrl() const { return url; }
- void setFederationLink(bool b) { federationLink = b; }
- bool isFederationLink() const { return federationLink; }
+ void setUserProxyAuth(const bool b) { userProxyAuth = b; }
+ bool isUserProxyAuth() const { return userProxyAuth || federationPeerTag.size() > 0; } // links can proxy msgs with non-matching auth ids
+ void setFederationLink(bool b) { federationLink = b; } // deprecated - use setFederationPeerTag() instead
+ bool isFederationLink() const { return federationPeerTag.size() > 0; }
void setFederationPeerTag(const std::string& tag) { federationPeerTag = std::string(tag); }
const std::string& getFederationPeerTag() const { return federationPeerTag; }
std::vector<Url>& getKnownHosts() { return knownHosts; }
@@ -105,6 +108,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
uint16_t heartbeatmax;
std::string userId;
std::string url;
+ bool userProxyAuth;
bool federationLink;
std::string federationPeerTag;
std::vector<Url> knownHosts;
diff --git a/qpid/cpp/src/qpid/broker/Daemon.cpp b/qpid/cpp/src/qpid/broker/Daemon.cpp
index b30e5f18cb..c36538beb7 100644
--- a/qpid/cpp/src/qpid/broker/Daemon.cpp
+++ b/qpid/cpp/src/qpid/broker/Daemon.cpp
@@ -93,11 +93,10 @@ void Daemon::fork()
catch (const exception& e) {
QPID_LOG(critical, "Unexpected error: " << e.what());
uint16_t port = 0;
- int unused_ret; //Supress warning about ignoring return value.
- unused_ret = write(pipeFds[1], &port, sizeof(uint16_t));
+ (void) write(pipeFds[1], &port, sizeof(uint16_t));
std::string pipeFailureMessage = e.what();
- unused_ret = write ( pipeFds[1],
+ (void) write ( pipeFds[1],
pipeFailureMessage.c_str(),
strlen(pipeFailureMessage.c_str())
);
diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp
index 64a12d918a..62cb3fc116 100644
--- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp
+++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp
@@ -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
@@ -27,12 +27,12 @@ namespace broker {
ExpiryPolicy::~ExpiryPolicy() {}
-void ExpiryPolicy::willExpire(Message&) {}
-
bool ExpiryPolicy::hasExpired(Message& m) {
return m.getExpiration() < sys::AbsTime::now();
}
-void ExpiryPolicy::forget(Message&) {}
+sys::AbsTime ExpiryPolicy::getCurrentTime() {
+ return sys::AbsTime::now();
+}
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
index a723eb0aa8..2caf00ce00 100644
--- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
@@ -10,9 +10,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
@@ -26,6 +26,11 @@
#include "qpid/broker/BrokerImportExport.h"
namespace qpid {
+
+namespace sys {
+class AbsTime;
+}
+
namespace broker {
class Message;
@@ -37,9 +42,8 @@ class QPID_BROKER_CLASS_EXTERN ExpiryPolicy : public RefCounted
{
public:
QPID_BROKER_EXTERN virtual ~ExpiryPolicy();
- QPID_BROKER_EXTERN virtual void willExpire(Message&);
QPID_BROKER_EXTERN virtual bool hasExpired(Message&);
- QPID_BROKER_EXTERN virtual void forget(Message&);
+ QPID_BROKER_EXTERN virtual qpid::sys::AbsTime getCurrentTime();
};
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
index abcaa5f69d..4bda70d313 100644
--- a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
@@ -112,9 +112,14 @@ bool HeadersExchange::bind(Queue::shared_ptr queue, const string& bindingKey, co
{
Mutex::ScopedLock l(lock);
- Binding::shared_ptr binding (new Binding (bindingKey, queue, this, *args));
+ //NOTE: do not include the fed op/tags/origin in the
+ //arguments as when x-match is 'all' these would prevent
+ //matching (they are internally added properties
+ //controlling binding propagation but not relevant to
+ //actual routing)
+ Binding::shared_ptr binding (new Binding (bindingKey, queue, this, extra_args));
BoundKey bk(binding);
- if (bindings.add_unless(bk, MatchArgs(queue, args))) {
+ if (bindings.add_unless(bk, MatchArgs(queue, &extra_args))) {
binding->startManagement();
propagate = bk.fedBinding.addOrigin(queue->getName(), fedOrigin);
if (mgmtExchange != 0) {
diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp
index 91861ade3f..9ab4379a69 100644
--- a/qpid/cpp/src/qpid/broker/Link.cpp
+++ b/qpid/cpp/src/qpid/broker/Link.cpp
@@ -117,7 +117,7 @@ void Link::startConnectionLH ()
// Set the state before calling connect. It is possible that connect
// will fail synchronously and call Link::closed before returning.
setStateLH(STATE_CONNECTING);
- broker->connect (host, port, transport,
+ broker->connect (host, boost::lexical_cast<std::string>(port), transport,
boost::bind (&Link::closed, this, _1, _2));
QPID_LOG (debug, "Inter-broker link connecting to " << host << ":" << port);
} catch(std::exception& e) {
diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
index 4f64ae2db9..1d52984831 100644
--- a/qpid/cpp/src/qpid/broker/Message.cpp
+++ b/qpid/cpp/src/qpid/broker/Message.cpp
@@ -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
@@ -49,25 +49,21 @@ TransferAdapter Message::TRANSFER;
Message::Message(const framing::SequenceNumber& id) :
frames(id), persistenceId(0), redelivered(false), loaded(false),
- staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
+ staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
expiration(FAR_FUTURE), dequeueCallback(0),
inCallback(false), requiredCredit(0), isManagementMessage(false)
{}
Message::Message(const Message& original) :
PersistableMessage(), frames(original.frames), persistenceId(0), redelivered(false), loaded(false),
- staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
+ staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
expiration(original.expiration), dequeueCallback(0),
inCallback(false), requiredCredit(0)
{
setExpiryPolicy(original.expiryPolicy);
}
-Message::~Message()
-{
- if (expiryPolicy)
- expiryPolicy->forget(*this);
-}
+Message::~Message() {}
void Message::forcePersistent()
{
@@ -87,7 +83,7 @@ std::string Message::getRoutingKey() const
return getAdapter().getRoutingKey(frames);
}
-std::string Message::getExchangeName() const
+std::string Message::getExchangeName() const
{
return getAdapter().getExchange(frames);
}
@@ -96,7 +92,7 @@ const boost::shared_ptr<Exchange> Message::getExchange(ExchangeRegistry& registr
{
if (!exchange) {
exchange = registry.get(getExchangeName());
- }
+ }
return exchange;
}
@@ -196,7 +192,7 @@ void Message::decodeContent(framing::Buffer& buffer)
} else {
//adjust header flags
MarkLastSegment f;
- frames.map_if(f, TypeFilter<HEADER_BODY>());
+ frames.map_if(f, TypeFilter<HEADER_BODY>());
}
//mark content loaded
loaded = true;
@@ -248,7 +244,7 @@ void Message::destroy()
bool Message::getContentFrame(const Queue& queue, AMQFrame& frame, uint16_t maxContentSize, uint64_t offset) const
{
intrusive_ptr<const PersistableMessage> pmsg(this);
-
+
bool done = false;
string& data = frame.castBody<AMQContentBody>()->getData();
store->loadContent(queue, pmsg, data, offset, maxContentSize);
@@ -273,7 +269,7 @@ void Message::sendContent(const Queue& queue, framing::FrameHandler& out, uint16
uint16_t maxContentSize = maxFrameSize - AMQFrame::frameOverhead();
bool morecontent = true;
for (uint64_t offset = 0; morecontent; offset += maxContentSize)
- {
+ {
AMQFrame frame((AMQContentBody()));
morecontent = getContentFrame(queue, frame, maxContentSize, offset);
out.handle(frame);
@@ -291,7 +287,7 @@ void Message::sendHeader(framing::FrameHandler& out, uint16_t /*maxFrameSize*/)
{
sys::Mutex::ScopedLock l(lock);
Relay f(out);
- frames.map_if(f, TypeFilter<HEADER_BODY>());
+ frames.map_if(f, TypeFilter<HEADER_BODY>());
}
// TODO aconway 2007-11-09: Obsolete, remove. Was used to cover over
@@ -321,7 +317,7 @@ bool Message::isContentLoaded() const
}
-namespace
+namespace
{
const std::string X_QPID_TRACE("x-qpid.trace");
}
@@ -358,13 +354,13 @@ void Message::addTraceId(const std::string& id)
trace += ",";
trace += id;
headers.setString(X_QPID_TRACE, trace);
- }
+ }
}
}
-void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
+void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
{
- DeliveryProperties* props = getProperties<DeliveryProperties>();
+ DeliveryProperties* props = getProperties<DeliveryProperties>();
if (props->getTtl()) {
// AMQP requires setting the expiration property to be posix
// time_t in seconds. TTL is in milliseconds
@@ -373,10 +369,14 @@ void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
time_t now = ::time(0);
props->setExpiration(now + (props->getTtl()/1000));
}
- // Use higher resolution time for the internal expiry calculation.
- Duration ttl(std::min(props->getTtl() * TIME_MSEC, (uint64_t) std::numeric_limits<int64_t>::max()));//Prevent overflow
- expiration = AbsTime(AbsTime::now(), ttl);
- setExpiryPolicy(e);
+ if (e) {
+ // Use higher resolution time for the internal expiry calculation.
+ // Prevent overflow as a signed int64_t
+ Duration ttl(std::min(props->getTtl() * TIME_MSEC,
+ (uint64_t) std::numeric_limits<int64_t>::max()));
+ expiration = AbsTime(e->getCurrentTime(), ttl);
+ setExpiryPolicy(e);
+ }
}
}
@@ -386,16 +386,17 @@ void Message::adjustTtl()
if (props->getTtl()) {
sys::Mutex::ScopedLock l(lock);
if (expiration < FAR_FUTURE) {
- sys::Duration d(sys::AbsTime::now(), getExpiration());
- props->setTtl(int64_t(d) > 0 ? int64_t(d)/1000000 : 1); // convert from ns to ms; set to 1 if expired
+ sys::AbsTime current(
+ expiryPolicy ? expiryPolicy->getCurrentTime() : sys::AbsTime::now());
+ sys::Duration ttl(current, getExpiration());
+ // convert from ns to ms; set to 1 if expired
+ props->setTtl(int64_t(ttl) >= 1000000 ? int64_t(ttl)/1000000 : 1);
}
}
}
void Message::setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e) {
expiryPolicy = e;
- if (expiryPolicy)
- expiryPolicy->willExpire(*this);
}
bool Message::hasExpired()
diff --git a/qpid/cpp/src/qpid/broker/Message.h b/qpid/cpp/src/qpid/broker/Message.h
index 8c5d42bcde..38e4f831fd 100644
--- a/qpid/cpp/src/qpid/broker/Message.h
+++ b/qpid/cpp/src/qpid/broker/Message.h
@@ -10,9 +10,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
@@ -34,12 +34,12 @@
#include <vector>
namespace qpid {
-
+
namespace framing {
class FieldTable;
class SequenceNumber;
}
-
+
namespace broker {
class ConnectionToken;
class Exchange;
@@ -51,11 +51,11 @@ class ExpiryPolicy;
class Message : public PersistableMessage {
public:
typedef boost::function<void (const boost::intrusive_ptr<Message>&)> MessageCallback;
-
+
QPID_BROKER_EXTERN Message(const framing::SequenceNumber& id = framing::SequenceNumber());
QPID_BROKER_EXTERN Message(const Message&);
QPID_BROKER_EXTERN ~Message();
-
+
uint64_t getPersistenceId() const { return persistenceId; }
void setPersistenceId(uint64_t _persistenceId) const { persistenceId = _persistenceId; }
@@ -83,10 +83,11 @@ public:
void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e);
bool hasExpired();
sys::AbsTime getExpiration() const { return expiration; }
+ void setExpiration(sys::AbsTime exp) { expiration = exp; }
void adjustTtl();
- framing::FrameSet& getFrames() { return frames; }
- const framing::FrameSet& getFrames() const { return frames; }
+ framing::FrameSet& getFrames() { return frames; }
+ const framing::FrameSet& getFrames() const { return frames; }
template <class T> T* getProperties() {
qpid::framing::AMQHeaderBody* p = frames.getHeaders();
@@ -103,6 +104,11 @@ public:
return p->get<T>();
}
+ template <class T> void eraseProperties() {
+ qpid::framing::AMQHeaderBody* p = frames.getHeaders();
+ p->erase<T>();
+ }
+
template <class T> const T* getMethod() const {
return frames.as<T>();
}
@@ -135,7 +141,7 @@ public:
QPID_BROKER_EXTERN void decodeHeader(framing::Buffer& buffer);
QPID_BROKER_EXTERN void decodeContent(framing::Buffer& buffer);
-
+
void QPID_BROKER_EXTERN tryReleaseContent();
void releaseContent();
void releaseContent(MessageStore* s);//deprecated, use 'setStore(store); releaseContent();' instead
@@ -149,10 +155,10 @@ public:
bool isExcluded(const std::vector<std::string>& excludes) const;
void addTraceId(const std::string& id);
-
+
void forcePersistent();
bool isForcedPersistent();
-
+
/** Call cb when dequeue is complete, may call immediately. Holds cb by reference. */
void setDequeueCompleteCallback(MessageCallback& cb);
diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp
index cf538aaaa7..260a45d7e0 100644
--- a/qpid/cpp/src/qpid/broker/Queue.cpp
+++ b/qpid/cpp/src/qpid/broker/Queue.cpp
@@ -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
@@ -65,7 +65,7 @@ using std::mem_fun;
namespace _qmf = qmf::org::apache::qpid::broker;
-namespace
+namespace
{
const std::string qpidMaxSize("qpid.max_size");
const std::string qpidMaxCount("qpid.max_count");
@@ -87,16 +87,16 @@ const int ENQUEUE_ONLY=1;
const int ENQUEUE_AND_DEQUEUE=2;
}
-Queue::Queue(const string& _name, bool _autodelete,
+Queue::Queue(const string& _name, bool _autodelete,
MessageStore* const _store,
const OwnershipToken* const _owner,
Manageable* parent,
Broker* b) :
- name(_name),
+ name(_name),
autodelete(_autodelete),
store(_store),
- owner(_owner),
+ owner(_owner),
consumerCount(0),
exclusive(0),
noLocal(false),
@@ -179,9 +179,9 @@ void Queue::recover(boost::intrusive_ptr<Message>& msg){
if (policy.get()) policy->recoverEnqueued(msg);
push(msg, true);
- if (store){
+ if (store){
// setup synclist for recovered messages, so they don't get re-stored on lastNodeFailure
- msg->addToSyncList(shared_from_this(), store);
+ msg->addToSyncList(shared_from_this(), store);
}
if (store && (!msg->isContentLoaded() || msg->checkContentReleasable())) {
@@ -206,13 +206,13 @@ void Queue::process(boost::intrusive_ptr<Message>& msg){
void Queue::requeue(const QueuedMessage& msg){
assertClusterSafe();
QueueListeners::NotificationSet copy;
- {
+ {
Mutex::ScopedLock locker(messageLock);
if (!isEnqueued(msg)) return;
messages->reinsert(msg);
listeners.populate(copy);
- // for persistLastNode - don't force a message twice to disk, but force it if no force before
+ // for persistLastNode - don't force a message twice to disk, but force it if no force before
if(inLastNodeFailure && persistLastNode && !msg.payload->isStoredOnQueue(shared_from_this())) {
msg.payload->forcePersistent();
if (msg.payload->isForcedPersistent() ){
@@ -224,7 +224,7 @@ void Queue::requeue(const QueuedMessage& msg){
copy.notify();
}
-bool Queue::acquireMessageAt(const SequenceNumber& position, QueuedMessage& message)
+bool Queue::acquireMessageAt(const SequenceNumber& position, QueuedMessage& message)
{
Mutex::ScopedLock locker(messageLock);
assertClusterSafe();
@@ -268,7 +268,7 @@ bool Queue::getNextMessage(QueuedMessage& m, Consumer::shared_ptr c)
case NO_MESSAGES:
default:
return false;
- }
+ }
} else {
return browseNextMessage(m, c);
}
@@ -278,7 +278,7 @@ Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_
{
while (true) {
Mutex::ScopedLock locker(messageLock);
- if (messages->empty()) {
+ if (messages->empty()) {
QPID_LOG(debug, "No messages to dispatch on queue '" << name << "'");
listeners.addListener(c);
return NO_MESSAGES;
@@ -291,7 +291,7 @@ Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_
}
if (c->filter(msg.payload)) {
- if (c->accept(msg.payload)) {
+ if (c->accept(msg.payload)) {
m = msg;
pop();
return CONSUMED;
@@ -304,7 +304,7 @@ Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_
//consumer will never want this message
QPID_LOG(debug, "Consumer doesn't want message from '" << name << "'");
return CANT_CONSUME;
- }
+ }
}
}
}
@@ -358,7 +358,7 @@ bool Queue::dispatch(Consumer::shared_ptr c)
}
}
-// Find the next message
+// Find the next message
bool Queue::seek(QueuedMessage& msg, Consumer::shared_ptr c) {
Mutex::ScopedLock locker(messageLock);
if (messages->next(c->position, msg)) {
@@ -426,19 +426,25 @@ bool collect_if_expired(std::deque<QueuedMessage>& expired, QueuedMessage& messa
}
}
-void Queue::purgeExpired()
+/**
+ *@param lapse: time since the last purgeExpired
+ */
+void Queue::purgeExpired(qpid::sys::Duration lapse)
{
//As expired messages are discarded during dequeue also, only
//bother explicitly expiring if the rate of dequeues since last
- //attempt is less than one per second.
-
- if (dequeueTracker.sampleRatePerSecond() < 1) {
+ //attempt is less than one per second.
+ int count = dequeueSincePurge.get();
+ dequeueSincePurge -= count;
+ int seconds = int64_t(lapse)/qpid::sys::TIME_SEC;
+ if (seconds == 0 || count / seconds < 1) {
std::deque<QueuedMessage> expired;
{
Mutex::ScopedLock locker(messageLock);
- messages->removeIf(boost::bind(&collect_if_expired, expired, _1));
+ messages->removeIf(boost::bind(&collect_if_expired, boost::ref(expired), _1));
}
- for_each(expired.begin(), expired.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
+ for_each(expired.begin(), expired.end(),
+ boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
}
}
@@ -457,7 +463,7 @@ void Queue::purgeExpired()
uint32_t Queue::purge(const uint32_t purge_request, boost::shared_ptr<Exchange> dest)
{
Mutex::ScopedLock locker(messageLock);
- uint32_t purge_count = purge_request; // only comes into play if >0
+ uint32_t purge_count = purge_request; // only comes into play if >0
std::deque<DeliverableMessage> rerouteQueue;
uint32_t count = 0;
@@ -490,7 +496,7 @@ uint32_t Queue::purge(const uint32_t purge_request, boost::shared_ptr<Exchange>
uint32_t Queue::move(const Queue::shared_ptr destq, uint32_t qty) {
Mutex::ScopedLock locker(messageLock);
- uint32_t move_count = qty; // only comes into play if qty >0
+ uint32_t move_count = qty; // only comes into play if qty >0
uint32_t count = 0; // count how many were moved for returning
while((!qty || move_count--) && !messages->empty()) {
@@ -508,7 +514,7 @@ void Queue::pop()
{
assertClusterSafe();
messages->pop();
- ++dequeueTracker;
+ ++dequeueSincePurge;
}
void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
@@ -517,10 +523,10 @@ void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
QueuedMessage removed;
bool dequeueRequired = false;
{
- Mutex::ScopedLock locker(messageLock);
+ Mutex::ScopedLock locker(messageLock);
QueuedMessage qm(this, msg, ++sequence);
if (insertSeqNo) msg->getOrInsertHeaders().setInt64(seqNoKey, sequence);
-
+
dequeueRequired = messages->push(qm, removed);
listeners.populate(copy);
enqueued(qm);
@@ -599,7 +605,7 @@ void Queue::setLastNodeFailure()
}
-// return true if store exists,
+// return true if store exists,
bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg, bool suppressPolicyCheck)
{
ScopedUse u(barrier);
@@ -619,7 +625,7 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg
if (inLastNodeFailure && persistLastNode){
msg->forcePersistent();
}
-
+
if (traceId.size()) {
//copy on write: take deep copy of message before modifying it
//as the frames may already be available for delivery on other
@@ -649,9 +655,10 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg
void Queue::enqueueAborted(boost::intrusive_ptr<Message> msg)
{
Mutex::ScopedLock locker(messageLock);
- if (policy.get()) policy->enqueueAborted(msg);
+ if (policy.get()) policy->enqueueAborted(msg);
}
+
/**
* Returns a null pointer if the dequeue completed, otherwise the dequeue will complete
* asynchronously, and a pointer to a DequeueCompletion object is returned.
@@ -666,7 +673,7 @@ Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
{
Mutex::ScopedLock locker(messageLock);
if (!isEnqueued(msg)) return empty;
- if (!ctxt) {
+ if (!ctxt) {
dequeued(msg);
}
}
@@ -693,7 +700,7 @@ Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
void Queue::dequeueCommitted(const QueuedMessage& msg)
{
Mutex::ScopedLock locker(messageLock);
- dequeued(msg);
+ dequeued(msg);
if (mgmtObject != 0) {
mgmtObject->inc_msgTxnDequeues();
mgmtObject->inc_byteTxnDequeues(msg.payload->contentSize());
@@ -748,8 +755,8 @@ int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::stri
return v->get<int>();
} else if (v->convertsTo<std::string>()){
std::string s = v->get<std::string>();
- try {
- return boost::lexical_cast<int>(s);
+ try {
+ return boost::lexical_cast<int>(s);
} catch(const boost::bad_lexical_cast&) {
QPID_LOG(warning, "Ignoring invalid integer value for " << key << ": " << s);
return 0;
@@ -773,7 +780,7 @@ void Queue::configureImpl(const FieldTable& _settings)
broker->getQueueEvents().observe(*this, eventMode == ENQUEUE_ONLY);
}
- if (QueuePolicy::getType(_settings) == QueuePolicy::FLOW_TO_DISK &&
+ if (QueuePolicy::getType(_settings) == QueuePolicy::FLOW_TO_DISK &&
(!store || NullMessageStore::isNullStore(store) || (broker && !(broker->getQueueEvents().isSync())) )) {
if ( NullMessageStore::isNullStore(store)) {
QPID_LOG(warning, "Flow to disk not valid for non-persisted queue:" << getName());
@@ -811,7 +818,7 @@ void Queue::configureImpl(const FieldTable& _settings)
QPID_LOG(debug, "Configured queue " << getName() << " as priority queue.");
}
}
-
+
persistLastNode= _settings.get(qpidPersistLastNode);
if (persistLastNode) QPID_LOG(debug, "Configured queue to Persist data if cluster fails to one node for: " << getName());
@@ -820,15 +827,15 @@ void Queue::configureImpl(const FieldTable& _settings)
if (excludeList.size()) {
split(traceExclude, excludeList, ", ");
}
- QPID_LOG(debug, "Configured queue " << getName() << " with qpid.trace.id='" << traceId
+ QPID_LOG(debug, "Configured queue " << getName() << " with qpid.trace.id='" << traceId
<< "' and qpid.trace.exclude='"<< excludeList << "' i.e. " << traceExclude.size() << " elements");
FieldTable::ValuePtr p =_settings.get(qpidInsertSequenceNumbers);
if (p && p->convertsTo<std::string>()) insertSequenceNumbers(p->get<std::string>());
autoDeleteTimeout = getIntegerSetting(_settings, qpidAutoDeleteTimeout);
- if (autoDeleteTimeout)
- QPID_LOG(debug, "Configured queue " << getName() << " with qpid.auto_delete_timeout=" << autoDeleteTimeout);
+ if (autoDeleteTimeout)
+ QPID_LOG(debug, "Configured queue " << getName() << " with qpid.auto_delete_timeout=" << autoDeleteTimeout);
if (mgmtObject != 0) {
mgmtObject->set_arguments(ManagementAgent::toMap(_settings));
@@ -892,9 +899,9 @@ const QueuePolicy* Queue::getPolicy()
return policy.get();
}
-uint64_t Queue::getPersistenceId() const
-{
- return persistenceId;
+uint64_t Queue::getPersistenceId() const
+{
+ return persistenceId;
}
void Queue::setPersistenceId(uint64_t _persistenceId) const
@@ -908,11 +915,11 @@ void Queue::setPersistenceId(uint64_t _persistenceId) const
persistenceId = _persistenceId;
}
-void Queue::encode(Buffer& buffer) const
+void Queue::encode(Buffer& buffer) const
{
buffer.putShortString(name);
buffer.put(settings);
- if (policy.get()) {
+ if (policy.get()) {
buffer.put(*policy);
}
buffer.putShortString(alternateExchange.get() ? alternateExchange->getName() : std::string(""));
@@ -965,7 +972,7 @@ boost::shared_ptr<Exchange> Queue::getAlternateExchange()
void tryAutoDeleteImpl(Broker& broker, Queue::shared_ptr queue)
{
- if (broker.getQueues().destroyIf(queue->getName(),
+ if (broker.getQueues().destroyIf(queue->getName(),
boost::bind(boost::mem_fn(&Queue::canAutoDelete), queue))) {
QPID_LOG(debug, "Auto-deleting " << queue->getName());
queue->destroyed();
@@ -977,7 +984,7 @@ struct AutoDeleteTask : qpid::sys::TimerTask
Broker& broker;
Queue::shared_ptr queue;
- AutoDeleteTask(Broker& b, Queue::shared_ptr q, AbsTime fireTime)
+ AutoDeleteTask(Broker& b, Queue::shared_ptr q, AbsTime fireTime)
: qpid::sys::TimerTask(fireTime, "DelayedAutoDeletion"), broker(b), queue(q) {}
void fire()
@@ -995,27 +1002,27 @@ void Queue::tryAutoDelete(Broker& broker, Queue::shared_ptr queue)
if (queue->autoDeleteTimeout && queue->canAutoDelete()) {
AbsTime time(now(), Duration(queue->autoDeleteTimeout * TIME_SEC));
queue->autoDeleteTask = boost::intrusive_ptr<qpid::sys::TimerTask>(new AutoDeleteTask(broker, queue, time));
- broker.getClusterTimer().add(queue->autoDeleteTask);
+ broker.getClusterTimer().add(queue->autoDeleteTask);
QPID_LOG(debug, "Timed auto-delete for " << queue->getName() << " initiated");
} else {
tryAutoDeleteImpl(broker, queue);
}
}
-bool Queue::isExclusiveOwner(const OwnershipToken* const o) const
-{
+bool Queue::isExclusiveOwner(const OwnershipToken* const o) const
+{
Mutex::ScopedLock locker(ownershipLock);
- return o == owner;
+ return o == owner;
}
-void Queue::releaseExclusiveOwnership()
-{
+void Queue::releaseExclusiveOwnership()
+{
Mutex::ScopedLock locker(ownershipLock);
- owner = 0;
+ owner = 0;
}
-bool Queue::setExclusiveOwner(const OwnershipToken* const o)
-{
+bool Queue::setExclusiveOwner(const OwnershipToken* const o)
+{
//reset auto deletion timer if necessary
if (autoDeleteTimeout && autoDeleteTask) {
autoDeleteTask->cancel();
@@ -1024,20 +1031,20 @@ bool Queue::setExclusiveOwner(const OwnershipToken* const o)
if (owner) {
return false;
} else {
- owner = o;
+ owner = o;
return true;
}
}
-bool Queue::hasExclusiveOwner() const
-{
+bool Queue::hasExclusiveOwner() const
+{
Mutex::ScopedLock locker(ownershipLock);
- return owner != 0;
+ return owner != 0;
}
-bool Queue::hasExclusiveConsumer() const
-{
- return exclusive;
+bool Queue::hasExclusiveConsumer() const
+{
+ return exclusive;
}
void Queue::setExternalQueueStore(ExternalQueueStore* inst) {
@@ -1206,6 +1213,10 @@ const Broker* Queue::getBroker()
return broker;
}
+void Queue::setDequeueSincePurge(uint32_t value) {
+ dequeueSincePurge = value;
+}
+
/** invoked from the store thread when the asynchronous dequeueing of the
* message has completed. */
diff --git a/qpid/cpp/src/qpid/broker/Queue.h b/qpid/cpp/src/qpid/broker/Queue.h
index 86c184676f..63f2397b77 100644
--- a/qpid/cpp/src/qpid/broker/Queue.h
+++ b/qpid/cpp/src/qpid/broker/Queue.h
@@ -10,9 +10,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,9 +32,9 @@
#include "qpid/broker/QueueBindings.h"
#include "qpid/broker/QueueListeners.h"
#include "qpid/broker/QueueObserver.h"
-#include "qpid/broker/RateTracker.h"
#include "qpid/framing/FieldTable.h"
+#include "qpid/sys/AtomicValue.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Timer.h"
#include "qpid/management/Manageable.h"
@@ -75,13 +75,13 @@ class Queue : public boost::enable_shared_from_this<Queue>,
{
Queue& parent;
uint count;
-
+
UsageBarrier(Queue&);
bool acquire();
void release();
void destroy();
};
-
+
struct ScopedUse
{
UsageBarrier& barrier;
@@ -89,7 +89,7 @@ class Queue : public boost::enable_shared_from_this<Queue>,
ScopedUse(UsageBarrier& b) : barrier(b), acquired(barrier.acquire()) {}
~ScopedUse() { if (acquired) barrier.release(); }
};
-
+
typedef std::set< boost::shared_ptr<QueueObserver> > Observers;
enum ConsumeCode {NO_MESSAGES=0, CANT_CONSUME=1, CONSUMED=2};
@@ -120,7 +120,7 @@ class Queue : public boost::enable_shared_from_this<Queue>,
boost::shared_ptr<Exchange> alternateExchange;
framing::SequenceNumber sequence;
qmf::org::apache::qpid::broker::Queue* mgmtObject;
- RateTracker dequeueTracker;
+ sys::AtomicValue<uint32_t> dequeueSincePurge; // Count dequeues since last purge.
int eventMode;
Observers observers;
bool insertSeqNo;
@@ -147,7 +147,7 @@ class Queue : public boost::enable_shared_from_this<Queue>,
void dequeued(const QueuedMessage& msg);
void pop();
void popAndDequeue();
- QueuedMessage getFront();
+
void forcePersistent(QueuedMessage& msg);
int getEventMode();
void configureImpl(const qpid::framing::FieldTable& settings);
@@ -185,8 +185,8 @@ class Queue : public boost::enable_shared_from_this<Queue>,
typedef std::vector<shared_ptr> vector;
QPID_BROKER_EXTERN Queue(const std::string& name,
- bool autodelete = false,
- MessageStore* const store = 0,
+ bool autodelete = false,
+ MessageStore* const store = 0,
const OwnershipToken* const owner = 0,
management::Manageable* parent = 0,
Broker* broker = 0);
@@ -246,11 +246,11 @@ class Queue : public boost::enable_shared_from_this<Queue>,
bool exclusive = false);
QPID_BROKER_EXTERN void cancel(Consumer::shared_ptr c);
- uint32_t purge(const uint32_t purge_request=0, boost::shared_ptr<Exchange> dest=boost::shared_ptr<Exchange>()); //defaults to all messages
- QPID_BROKER_EXTERN void purgeExpired();
+ uint32_t purge(const uint32_t purge_request=0, boost::shared_ptr<Exchange> dest=boost::shared_ptr<Exchange>()); //defaults to all messages
+ QPID_BROKER_EXTERN void purgeExpired(sys::Duration);
//move qty # of messages to destination Queue destq
- uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
+ uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
QPID_BROKER_EXTERN uint32_t getMessageCount() const;
QPID_BROKER_EXTERN uint32_t getEnqueueCompleteMessageCount() const;
@@ -313,8 +313,8 @@ class Queue : public boost::enable_shared_from_this<Queue>,
* Inform queue of messages that were enqueued, have since
* been acquired but not yet accepted or released (and
* thus are still logically on the queue) - used in
- * clustered broker.
- */
+ * clustered broker.
+ */
void updateEnqueued(const QueuedMessage& msg);
/**
@@ -325,9 +325,9 @@ class Queue : public boost::enable_shared_from_this<Queue>,
* accepted it).
*/
bool isEnqueued(const QueuedMessage& msg);
-
+
/**
- * Gets the next available message
+ * Gets the next available message
*/
QPID_BROKER_EXTERN QueuedMessage get();
@@ -408,6 +408,9 @@ class Queue : public boost::enable_shared_from_this<Queue>,
const Broker* getBroker();
+ uint32_t getDequeueSincePurge() { return dequeueSincePurge.get(); }
+ void setDequeueSincePurge(uint32_t value);
+
private:
std::map<PersistableMessage *, boost::intrusive_ptr<DequeueCompletion> > pendingDequeueCompletions;
};
diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.cpp b/qpid/cpp/src/qpid/broker/QueueCleaner.cpp
index 3499ea8a4d..838bc28be8 100644
--- a/qpid/cpp/src/qpid/broker/QueueCleaner.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueCleaner.cpp
@@ -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
@@ -27,7 +27,7 @@
namespace qpid {
namespace broker {
-QueueCleaner::QueueCleaner(QueueRegistry& q, sys::Timer& t) : queues(q), timer(t) {}
+QueueCleaner::QueueCleaner(QueueRegistry& q, sys::Timer* t) : queues(q), timer(t) {}
QueueCleaner::~QueueCleaner()
{
@@ -36,10 +36,16 @@ QueueCleaner::~QueueCleaner()
void QueueCleaner::start(qpid::sys::Duration p)
{
+ period = p;
task = new Task(*this, p);
- timer.add(task);
+ timer->add(task);
}
+void QueueCleaner::setTimer(qpid::sys::Timer* timer) {
+ this->timer = timer;
+}
+
+
QueueCleaner::Task::Task(QueueCleaner& p, qpid::sys::Duration d) : sys::TimerTask(d,"QueueCleaner"), parent(p) {}
void QueueCleaner::Task::fire()
@@ -65,9 +71,9 @@ void QueueCleaner::fired()
std::vector<Queue::shared_ptr> copy;
CollectQueues collect(&copy);
queues.eachQueue(collect);
- std::for_each(copy.begin(), copy.end(), boost::bind(&Queue::purgeExpired, _1));
+ std::for_each(copy.begin(), copy.end(), boost::bind(&Queue::purgeExpired, _1, period));
task->setupNextFire();
- timer.add(task);
+ timer->add(task);
}
diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.h b/qpid/cpp/src/qpid/broker/QueueCleaner.h
index 11c2d180ac..ffebfe3e1b 100644
--- a/qpid/cpp/src/qpid/broker/QueueCleaner.h
+++ b/qpid/cpp/src/qpid/broker/QueueCleaner.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -35,14 +35,15 @@ class QueueRegistry;
class QueueCleaner
{
public:
- QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, sys::Timer& timer);
+ QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, sys::Timer* timer);
QPID_BROKER_EXTERN ~QueueCleaner();
- QPID_BROKER_EXTERN void start(qpid::sys::Duration period);
+ QPID_BROKER_EXTERN void start(sys::Duration period);
+ QPID_BROKER_EXTERN void setTimer(sys::Timer* timer);
private:
class Task : public sys::TimerTask
{
public:
- Task(QueueCleaner& parent, qpid::sys::Duration duration);
+ Task(QueueCleaner& parent, sys::Duration duration);
void fire();
private:
QueueCleaner& parent;
@@ -50,7 +51,8 @@ class QueueCleaner
boost::intrusive_ptr<sys::TimerTask> task;
QueueRegistry& queues;
- sys::Timer& timer;
+ sys::Timer* timer;
+ sys::Duration period;
void fired();
};
diff --git a/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp b/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp
index b2e2e54bdf..fcf8d089f9 100644
--- a/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp
@@ -167,7 +167,8 @@ void QueueFlowLimit::enqueued(const QueuedMessage& msg)
msg.payload->getIngressCompletion().startCompleter(); // don't complete until flow resumes
bool unique;
unique = index.insert(std::pair<framing::SequenceNumber, boost::intrusive_ptr<Message> >(msg.position, msg.payload)).second;
- assert(unique);
+ // Like this to avoid tripping up unused variable warning when NDEBUG set
+ if (!unique) assert(unique);
}
}
@@ -379,7 +380,8 @@ void QueueFlowLimit::setState(const qpid::framing::FieldTable& state)
QueuedMessage msg(queue->find(seq)); // fyi: msg.payload may be null if msg is delivered & unacked
bool unique;
unique = index.insert(std::pair<framing::SequenceNumber, boost::intrusive_ptr<Message> >(seq, msg.payload)).second;
- assert(unique);
+ // Like this to avoid tripping up unused variable warning when NDEBUG set
+ if (!unique) assert(unique);
}
}
}
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
index a93a6332fd..6ae0d53b1a 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
@@ -117,19 +117,20 @@ void QueuePolicy::update(FieldTable& settings)
settings.setString(typeKey, type);
}
-uint32_t QueuePolicy::getCapacity(const FieldTable& settings, const std::string& key, uint32_t defaultValue)
+template <typename T>
+T getCapacity(const FieldTable& settings, const std::string& key, T defaultValue)
{
FieldTable::ValuePtr v = settings.get(key);
- int32_t result = 0;
+ T result = 0;
if (!v) return defaultValue;
if (v->getType() == 0x23) {
QPID_LOG(debug, "Value for " << key << " specified as float: " << v->get<float>());
} else if (v->getType() == 0x33) {
QPID_LOG(debug, "Value for " << key << " specified as double: " << v->get<double>());
- } else if (v->convertsTo<int>()) {
- result = v->get<int>();
+ } else if (v->convertsTo<T>()) {
+ result = v->get<T>();
QPID_LOG(debug, "Got integer value for " << key << ": " << result);
if (result >= 0) return result;
} else if (v->convertsTo<string>()) {
@@ -319,8 +320,8 @@ std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const qpid::framing::F
std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const std::string& name, const qpid::framing::FieldTable& settings)
{
- uint32_t maxCount = getCapacity(settings, maxCountKey, 0);
- uint32_t maxSize = getCapacity(settings, maxSizeKey, defaultMaxSize);
+ uint32_t maxCount = getCapacity<int32_t>(settings, maxCountKey, 0);
+ uint64_t maxSize = getCapacity<int64_t>(settings, maxSizeKey, defaultMaxSize);
if (maxCount || maxSize) {
return createQueuePolicy(name, maxCount, maxSize, getType(settings));
} else {
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.h b/qpid/cpp/src/qpid/broker/QueuePolicy.h
index 3cdd63784d..ec7f846704 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.h
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.h
@@ -43,8 +43,7 @@ class QueuePolicy
uint32_t count;
uint64_t size;
bool policyExceeded;
-
- static uint32_t getCapacity(const qpid::framing::FieldTable& settings, const std::string& key, uint32_t defaultValue);
+
protected:
uint64_t getCurrentQueueSize() const { return size; }
diff --git a/qpid/cpp/src/qpid/broker/RateTracker.cpp b/qpid/cpp/src/qpid/broker/RateTracker.cpp
deleted file mode 100644
index 048349b658..0000000000
--- a/qpid/cpp/src/qpid/broker/RateTracker.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/RateTracker.h"
-
-using qpid::sys::AbsTime;
-using qpid::sys::Duration;
-using qpid::sys::TIME_SEC;
-
-namespace qpid {
-namespace broker {
-
-RateTracker::RateTracker() : currentCount(0), lastCount(0), lastTime(AbsTime::now()) {}
-
-RateTracker& RateTracker::operator++()
-{
- ++currentCount;
- return *this;
-}
-
-double RateTracker::sampleRatePerSecond()
-{
- int32_t increment = currentCount - lastCount;
- AbsTime now = AbsTime::now();
- Duration interval(lastTime, now);
- lastCount = currentCount;
- lastTime = now;
- //if sampling at higher frequency than supported, will just return the number of increments
- if (interval < TIME_SEC) return increment;
- else if (increment == 0) return 0;
- else return increment / (interval / TIME_SEC);
-}
-
-}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/RateTracker.h b/qpid/cpp/src/qpid/broker/RateTracker.h
deleted file mode 100644
index 0c20b37312..0000000000
--- a/qpid/cpp/src/qpid/broker/RateTracker.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef QPID_BROKER_RATETRACKER_H
-#define QPID_BROKER_RATETRACKER_H
-
-/*
- *
- * 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.
- *
- */
-
-#include "qpid/sys/Time.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Simple rate tracker: represents some value that can be incremented,
- * then can periodcially sample the rate of increments.
- */
-class RateTracker
-{
- public:
- RateTracker();
- /**
- * Increments the count being tracked. Can be called concurrently
- * with other calls to this operator as well as with calls to
- * sampleRatePerSecond().
- */
- RateTracker& operator++();
- /**
- * Returns the rate of increments per second since last
- * called. Calls to this method should be serialised, but can be
- * called concurrently with the increment operator
- */
- double sampleRatePerSecond();
- private:
- volatile int32_t currentCount;
- int32_t lastCount;
- qpid::sys::AbsTime lastTime;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_RATETRACKER_H*/
diff --git a/qpid/cpp/src/qpid/broker/SemanticState.cpp b/qpid/cpp/src/qpid/broker/SemanticState.cpp
index 2383978276..9b8c9b8d58 100644
--- a/qpid/cpp/src/qpid/broker/SemanticState.cpp
+++ b/qpid/cpp/src/qpid/broker/SemanticState.cpp
@@ -70,7 +70,7 @@ SemanticState::SemanticState(DeliveryAdapter& da, SessionContext& ss)
deliveryAdapter(da),
tagGenerator("sgen"),
dtxSelected(false),
- authMsg(getSession().getBroker().getOptions().auth && !getSession().getConnection().isFederationLink()),
+ authMsg(getSession().getBroker().getOptions().auth && !getSession().getConnection().isUserProxyAuth()),
userID(getSession().getConnection().getUserId()),
userName(getSession().getConnection().getUserId().substr(0,getSession().getConnection().getUserId().find('@'))),
isDefaultRealm(userID.find('@') != std::string::npos && getSession().getBroker().getOptions().realm == userID.substr(userID.find('@')+1,userID.size())),
@@ -469,7 +469,6 @@ void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) {
/* verify the userid if specified: */
std::string id =
msg->hasProperties<MessageProperties>() ? msg->getProperties<MessageProperties>()->getUserId() : nullstring;
-
if (authMsg && !id.empty() && !(id == userID || (isDefaultRealm && id == userName)))
{
QPID_LOG(debug, "authorised user id : " << userID << " but user id in message declared as " << id);
diff --git a/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp b/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
index fd0e537192..676074a590 100644
--- a/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
+++ b/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
@@ -81,12 +81,11 @@ class SslProtocolFactory : public qpid::sys::ProtocolFactory {
SslProtocolFactory(const SslServerOptions&, int backlog, bool nodelay);
~SslProtocolFactory();
void accept(sys::Poller::shared_ptr, sys::ConnectionCodec::Factory*);
- void connect(sys::Poller::shared_ptr, const std::string& host, int16_t port,
+ void connect(sys::Poller::shared_ptr, const std::string& host, const std::string& port,
sys::ConnectionCodec::Factory*,
ConnectFailedCallback failed);
uint16_t getPort() const;
- std::string getHost() const;
bool supports(const std::string& capability);
private:
@@ -130,7 +129,7 @@ SslProtocolFactory::SslProtocolFactory(const SslServerOptions& options,
int backlog,
bool nodelay)
: tcpNoDelay(nodelay),
- listeningPort(listener.listen(options.port, backlog)),
+ listeningPort(listener.listen("", boost::lexical_cast<std::string>(options.port), backlog)),
clientAuthSelected(options.clientAuth) {
SecInvalidateHandle(&credHandle);
@@ -237,10 +236,6 @@ uint16_t SslProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
-std::string SslProtocolFactory::getHost() const {
- return listener.getSockname();
-}
-
void SslProtocolFactory::accept(sys::Poller::shared_ptr poller,
sys::ConnectionCodec::Factory* fact) {
acceptor.reset(
@@ -251,7 +246,7 @@ void SslProtocolFactory::accept(sys::Poller::shared_ptr poller,
void SslProtocolFactory::connect(sys::Poller::shared_ptr poller,
const std::string& host,
- int16_t port,
+ const std::string& port,
sys::ConnectionCodec::Factory* fact,
ConnectFailedCallback failed)
{
diff --git a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
index 40c004f166..4b7aa07065 100644
--- a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -36,6 +36,7 @@
#include <boost/bind.hpp>
#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <limits>
@@ -258,16 +259,16 @@ void ConnectionImpl::open()
connector->setInputHandler(&handler);
connector->setShutdownHandler(this);
try {
- connector->connect(host, port);
-
+ std::string p = boost::lexical_cast<std::string>(port);
+ connector->connect(host, p);
+
} catch (const std::exception& e) {
QPID_LOG(debug, "Failed to connect to " << protocol << ":" << host << ":" << port << " " << e.what());
connector.reset();
throw;
}
connector->init();
- QPID_LOG(info, *this << " connected to " << protocol << ":" << host << ":" << port);
-
+
// Enable heartbeat if requested
uint16_t heartbeat = static_cast<ConnectionSettings&>(handler).heartbeat;
if (heartbeat) {
@@ -281,6 +282,7 @@ void ConnectionImpl::open()
// - in that case in connector.reset() above;
// - or when we are deleted
handler.waitForOpen();
+ QPID_LOG(info, *this << " connected to " << protocol << ":" << host << ":" << port);
// If the SASL layer has provided an "operational" userId for the connection,
// put it in the negotiated settings.
diff --git a/qpid/cpp/src/qpid/client/Connector.h b/qpid/cpp/src/qpid/client/Connector.h
index 586012f9d6..bc611ffe0d 100644
--- a/qpid/cpp/src/qpid/client/Connector.h
+++ b/qpid/cpp/src/qpid/client/Connector.h
@@ -61,7 +61,7 @@ class Connector : public framing::OutputHandler
static void registerFactory(const std::string& proto, Factory* connectorFactory);
virtual ~Connector() {};
- virtual void connect(const std::string& host, int port) = 0;
+ virtual void connect(const std::string& host, const std::string& port) = 0;
virtual void init() {};
virtual void close() = 0;
virtual void send(framing::AMQFrame& frame) = 0;
diff --git a/qpid/cpp/src/qpid/client/RdmaConnector.cpp b/qpid/cpp/src/qpid/client/RdmaConnector.cpp
index 6af607198c..664640f5e7 100644
--- a/qpid/cpp/src/qpid/client/RdmaConnector.cpp
+++ b/qpid/cpp/src/qpid/client/RdmaConnector.cpp
@@ -95,7 +95,7 @@ class RdmaConnector : public Connector, public sys::Codec
std::string identifier;
- void connect(const std::string& host, int port);
+ void connect(const std::string& host, const std::string& port);
void close();
void send(framing::AMQFrame& frame);
void abort() {} // TODO: need to fix this for heartbeat timeouts to work
@@ -173,7 +173,7 @@ RdmaConnector::~RdmaConnector() {
}
}
-void RdmaConnector::connect(const std::string& host, int port){
+void RdmaConnector::connect(const std::string& host, const std::string& port){
Mutex::ScopedLock l(dataConnectedLock);
assert(!dataConnected);
@@ -184,7 +184,7 @@ void RdmaConnector::connect(const std::string& host, int port){
boost::bind(&RdmaConnector::disconnected, this),
boost::bind(&RdmaConnector::rejected, this, poller, _1, _2));
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
+ SocketAddress sa(host, port);
acon->start(poller, sa);
}
diff --git a/qpid/cpp/src/qpid/client/SslConnector.cpp b/qpid/cpp/src/qpid/client/SslConnector.cpp
index 35c7e6bdf6..f121cfb1ab 100644
--- a/qpid/cpp/src/qpid/client/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/SslConnector.cpp
@@ -114,7 +114,7 @@ class SslConnector : public Connector
std::string identifier;
- void connect(const std::string& host, int port);
+ void connect(const std::string& host, const std::string& port);
void init();
void close();
void send(framing::AMQFrame& frame);
@@ -190,7 +190,7 @@ SslConnector::~SslConnector() {
close();
}
-void SslConnector::connect(const std::string& host, int port){
+void SslConnector::connect(const std::string& host, const std::string& port){
Mutex::ScopedLock l(closedLock);
assert(closed);
try {
diff --git a/qpid/cpp/src/qpid/client/TCPConnector.cpp b/qpid/cpp/src/qpid/client/TCPConnector.cpp
index d90781b365..0070b24ec0 100644
--- a/qpid/cpp/src/qpid/client/TCPConnector.cpp
+++ b/qpid/cpp/src/qpid/client/TCPConnector.cpp
@@ -88,7 +88,7 @@ TCPConnector::~TCPConnector() {
close();
}
-void TCPConnector::connect(const std::string& host, int port) {
+void TCPConnector::connect(const std::string& host, const std::string& port) {
Mutex::ScopedLock l(lock);
assert(closed);
connector = AsynchConnector::create(
@@ -121,7 +121,7 @@ void TCPConnector::start(sys::AsynchIO* aio_) {
aio->queueReadBuffer(new Buff(maxFrameSize));
}
- identifier = str(format("[%1% %2%]") % socket.getLocalPort() % socket.getPeerAddress());
+ identifier = str(format("[%1%]") % socket.getFullAddress());
}
void TCPConnector::initAmqp() {
diff --git a/qpid/cpp/src/qpid/client/TCPConnector.h b/qpid/cpp/src/qpid/client/TCPConnector.h
index c756469182..eb3f696013 100644
--- a/qpid/cpp/src/qpid/client/TCPConnector.h
+++ b/qpid/cpp/src/qpid/client/TCPConnector.h
@@ -98,7 +98,7 @@ class TCPConnector : public Connector, public sys::Codec
protected:
virtual ~TCPConnector();
- void connect(const std::string& host, int port);
+ void connect(const std::string& host, const std::string& port);
void start(sys::AsynchIO* aio_);
void initAmqp();
virtual void connectFailed(const std::string& msg);
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp
index bfb20118b5..e8d250de0f 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp
@@ -30,12 +30,23 @@ void AcceptTracker::State::accept()
unaccepted.clear();
}
-void AcceptTracker::State::accept(qpid::framing::SequenceNumber id)
+SequenceSet AcceptTracker::State::accept(qpid::framing::SequenceNumber id, bool cumulative)
{
- if (unaccepted.contains(id)) {
- unaccepted.remove(id);
- unconfirmed.add(id);
+ SequenceSet accepting;
+ if (cumulative) {
+ for (SequenceSet::iterator i = unaccepted.begin(); i != unaccepted.end() && *i <= id; ++i) {
+ accepting.add(*i);
+ }
+ unconfirmed.add(accepting);
+ unaccepted.remove(accepting);
+ } else {
+ if (unaccepted.contains(id)) {
+ unaccepted.remove(id);
+ unconfirmed.add(id);
+ accepting.add(id);
+ }
}
+ return accepting;
}
void AcceptTracker::State::release()
@@ -71,16 +82,15 @@ void AcceptTracker::accept(qpid::client::AsyncSession& session)
aggregateState.accept();
}
-void AcceptTracker::accept(qpid::framing::SequenceNumber id, qpid::client::AsyncSession& session)
+void AcceptTracker::accept(qpid::framing::SequenceNumber id, qpid::client::AsyncSession& session, bool cumulative)
{
for (StateMap::iterator i = destinationState.begin(); i != destinationState.end(); ++i) {
- i->second.accept(id);
+ i->second.accept(id, cumulative);
}
Record record;
- record.accepted.add(id);
+ record.accepted = aggregateState.accept(id, cumulative);
record.status = session.messageAccept(record.accepted);
pending.push_back(record);
- aggregateState.accept(id);
}
void AcceptTracker::release(qpid::client::AsyncSession& session)
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h
index 87890e41cc..9e801e8147 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h
@@ -42,7 +42,7 @@ class AcceptTracker
public:
void delivered(const std::string& destination, const qpid::framing::SequenceNumber& id);
void accept(qpid::client::AsyncSession&);
- void accept(qpid::framing::SequenceNumber, qpid::client::AsyncSession&);
+ void accept(qpid::framing::SequenceNumber, qpid::client::AsyncSession&, bool cumulative);
void release(qpid::client::AsyncSession&);
uint32_t acceptsPending();
uint32_t acceptsPending(const std::string& destination);
@@ -62,7 +62,7 @@ class AcceptTracker
qpid::framing::SequenceSet unconfirmed;
void accept();
- void accept(qpid::framing::SequenceNumber);
+ qpid::framing::SequenceSet accept(qpid::framing::SequenceNumber, bool cumulative);
void release();
uint32_t acceptsPending();
void completed(qpid::framing::SequenceSet&);
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp b/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
index f1295a3b66..9cf5f31290 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
@@ -233,6 +233,8 @@ class Subscription : public Exchange, public MessageSource
const bool reliable;
const bool durable;
const std::string actualType;
+ const bool exclusiveQueue;
+ const bool exclusiveSubscription;
FieldTable queueOptions;
FieldTable subscriptionOptions;
Bindings bindings;
@@ -307,6 +309,7 @@ struct Opt
Opt& operator/(const std::string& name);
operator bool() const;
std::string str() const;
+ bool asBool(bool defaultValue) const;
const Variant::List& asList() const;
void collect(qpid::framing::FieldTable& args) const;
@@ -338,6 +341,12 @@ Opt::operator bool() const
return value && !value->isVoid() && value->asBool();
}
+bool Opt::asBool(bool defaultValue) const
+{
+ if (value) return value->asBool();
+ else return defaultValue;
+}
+
std::string Opt::str() const
{
if (value) return value->asString();
@@ -490,7 +499,9 @@ Subscription::Subscription(const Address& address, const std::string& type)
queue(getSubscriptionName(name, (Opt(address)/LINK/NAME).str())),
reliable(AddressResolution::is_reliable(address)),
durable(Opt(address)/LINK/DURABLE),
- actualType(type.empty() ? (specifiedType.empty() ? TOPIC_EXCHANGE : specifiedType) : type)
+ actualType(type.empty() ? (specifiedType.empty() ? TOPIC_EXCHANGE : specifiedType) : type),
+ exclusiveQueue((Opt(address)/LINK/X_DECLARE/EXCLUSIVE).asBool(true)),
+ exclusiveSubscription((Opt(address)/LINK/X_SUBSCRIBE/EXCLUSIVE).asBool(exclusiveQueue))
{
(Opt(address)/LINK/X_DECLARE/ARGUMENTS).collect(queueOptions);
(Opt(address)/LINK/X_SUBSCRIBE/ARGUMENTS).collect(subscriptionOptions);
@@ -550,7 +561,7 @@ void Subscription::subscribe(qpid::client::AsyncSession& session, const std::str
checkAssert(session, FOR_RECEIVER);
//create subscription queue:
- session.queueDeclare(arg::queue=queue, arg::exclusive=true,
+ session.queueDeclare(arg::queue=queue, arg::exclusive=exclusiveQueue,
arg::autoDelete=!reliable, arg::durable=durable, arg::arguments=queueOptions);
//'default' binding:
bindings.bind(session);
@@ -559,15 +570,15 @@ void Subscription::subscribe(qpid::client::AsyncSession& session, const std::str
linkBindings.bind(session);
//subscribe to subscription queue:
AcceptMode accept = reliable ? ACCEPT_MODE_EXPLICIT : ACCEPT_MODE_NONE;
- session.messageSubscribe(arg::queue=queue, arg::destination=destination,
- arg::exclusive=true, arg::acceptMode=accept, arg::arguments=subscriptionOptions);
+ session.messageSubscribe(arg::queue=queue, arg::destination=destination,
+ arg::exclusive=exclusiveSubscription, arg::acceptMode=accept, arg::arguments=subscriptionOptions);
}
void Subscription::cancel(qpid::client::AsyncSession& session, const std::string& destination)
{
linkBindings.unbind(session);
session.messageCancel(destination);
- session.queueDelete(arg::queue=queue);
+ if (reliable) session.queueDelete(arg::queue=queue, arg::ifUnused=true);
checkDelete(session, FOR_RECEIVER);
}
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
index a87a8dea67..473f5ecd1c 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
@@ -40,11 +40,15 @@ using qpid::types::VAR_LIST;
using qpid::framing::Uuid;
namespace {
-void convert(const Variant::List& from, std::vector<std::string>& to)
+void merge(const std::string& value, std::vector<std::string>& list) {
+ if (std::find(list.begin(), list.end(), value) == list.end())
+ list.push_back(value);
+}
+
+void merge(const Variant::List& from, std::vector<std::string>& to)
{
- for (Variant::List::const_iterator i = from.begin(); i != from.end(); ++i) {
- to.push_back(i->asString());
- }
+ for (Variant::List::const_iterator i = from.begin(); i != from.end(); ++i)
+ merge(i->asString(), to);
}
std::string asString(const std::vector<std::string>& v) {
@@ -93,9 +97,9 @@ void ConnectionImpl::setOption(const std::string& name, const Variant& value)
maxReconnectInterval = value;
} else if (name == "reconnect-urls" || name == "reconnect_urls") {
if (value.getType() == VAR_LIST) {
- convert(value.asList(), urls);
+ merge(value.asList(), urls);
} else {
- urls.push_back(value.asString());
+ merge(value.asString(), urls);
}
} else if (name == "username") {
settings.username = value.asString();
@@ -198,7 +202,7 @@ qpid::messaging::Session ConnectionImpl::newSession(bool transactional, const st
sessions[name] = impl;
break;
} catch (const qpid::TransportFailure&) {
- open();
+ reopen();
} catch (const qpid::SessionException& e) {
throw qpid::messaging::SessionError(e.what());
} catch (const std::exception& e) {
@@ -219,6 +223,15 @@ void ConnectionImpl::open()
catch (const qpid::Exception& e) { throw messaging::ConnectionError(e.what()); }
}
+void ConnectionImpl::reopen()
+{
+ if (!reconnect) {
+ throw qpid::messaging::TransportFailure("Failed to connect (reconnect disabled)");
+ }
+ open();
+}
+
+
bool expired(const qpid::sys::AbsTime& start, int64_t timeout)
{
if (timeout == 0) return true;
@@ -246,14 +259,9 @@ void ConnectionImpl::connect(const qpid::sys::AbsTime& started)
}
void ConnectionImpl::mergeUrls(const std::vector<Url>& more, const sys::Mutex::ScopedLock&) {
- if (more.size()) {
- for (size_t i = 0; i < more.size(); ++i) {
- if (std::find(urls.begin(), urls.end(), more[i].str()) == urls.end()) {
- urls.push_back(more[i].str());
- }
- }
- QPID_LOG(debug, "Added known-hosts, reconnect-urls=" << asString(urls));
- }
+ for (std::vector<Url>::const_iterator i = more.begin(); i != more.end(); ++i)
+ merge(i->str(), urls);
+ QPID_LOG(debug, "Added known-hosts, reconnect-urls=" << asString(urls));
}
bool ConnectionImpl::tryConnect()
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h
index 09f2038312..9e31238bc1 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h
@@ -43,6 +43,7 @@ class ConnectionImpl : public qpid::messaging::ConnectionImpl
public:
ConnectionImpl(const std::string& url, const qpid::types::Variant::Map& options);
void open();
+ void reopen();
bool isOpen() const;
void close();
qpid::messaging::Session newSession(bool transactional, const std::string& name);
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
index 71e89bdba1..5cf20c92eb 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
@@ -144,10 +144,10 @@ void IncomingMessages::accept()
acceptTracker.accept(session);
}
-void IncomingMessages::accept(qpid::framing::SequenceNumber id)
+void IncomingMessages::accept(qpid::framing::SequenceNumber id, bool cumulative)
{
sys::Mutex::ScopedLock l(lock);
- acceptTracker.accept(id, session);
+ acceptTracker.accept(id, session, cumulative);
}
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h
index f6a291bc68..9053b70312 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h
@@ -72,7 +72,7 @@ class IncomingMessages
bool get(Handler& handler, qpid::sys::Duration timeout);
bool getNextDestination(std::string& destination, qpid::sys::Duration timeout);
void accept();
- void accept(qpid::framing::SequenceNumber id);
+ void accept(qpid::framing::SequenceNumber id, bool cumulative);
void releaseAll();
void releasePending(const std::string& destination);
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
index 75a71997fd..787be7de2a 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
@@ -112,13 +112,14 @@ void SessionImpl::release(qpid::messaging::Message& m)
execute1<Release>(m);
}
-void SessionImpl::acknowledge(qpid::messaging::Message& m)
+void SessionImpl::acknowledge(qpid::messaging::Message& m, bool cumulative)
{
//Should probably throw an exception on failure here, or indicate
//it through a return type at least. Failure means that the
//message may be redelivered; i.e. the application cannot delete
//any state necessary for preventing reprocessing of the message
- execute1<Acknowledge1>(m);
+ Acknowledge2 ack(*this, m, cumulative);
+ execute(ack);
}
void SessionImpl::close()
@@ -467,10 +468,10 @@ void SessionImpl::acknowledgeImpl()
if (!transactional) incoming.accept();
}
-void SessionImpl::acknowledgeImpl(qpid::messaging::Message& m)
+void SessionImpl::acknowledgeImpl(qpid::messaging::Message& m, bool cumulative)
{
ScopedLock l(lock);
- if (!transactional) incoming.accept(MessageImplAccess::get(m).getInternalId());
+ if (!transactional) incoming.accept(MessageImplAccess::get(m).getInternalId(), cumulative);
}
void SessionImpl::rejectImpl(qpid::messaging::Message& m)
@@ -509,7 +510,7 @@ void SessionImpl::senderCancelled(const std::string& name)
void SessionImpl::reconnect()
{
- connection->open();
+ connection->reopen();
}
bool SessionImpl::backoff()
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h
index 2a2aa47df6..c7dea77d18 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h
@@ -63,7 +63,7 @@ class SessionImpl : public qpid::messaging::SessionImpl
void acknowledge(bool sync);
void reject(qpid::messaging::Message&);
void release(qpid::messaging::Message&);
- void acknowledge(qpid::messaging::Message& msg);
+ void acknowledge(qpid::messaging::Message& msg, bool cumulative);
void close();
void sync(bool block);
qpid::messaging::Sender createSender(const qpid::messaging::Address& address);
@@ -139,7 +139,7 @@ class SessionImpl : public qpid::messaging::SessionImpl
void commitImpl();
void rollbackImpl();
void acknowledgeImpl();
- void acknowledgeImpl(qpid::messaging::Message&);
+ void acknowledgeImpl(qpid::messaging::Message&, bool cumulative);
void rejectImpl(qpid::messaging::Message&);
void releaseImpl(qpid::messaging::Message&);
void closeImpl();
@@ -204,12 +204,13 @@ class SessionImpl : public qpid::messaging::SessionImpl
void operator()() { impl.releaseImpl(message); }
};
- struct Acknowledge1 : Command
+ struct Acknowledge2 : Command
{
qpid::messaging::Message& message;
+ bool cumulative;
- Acknowledge1(SessionImpl& i, qpid::messaging::Message& m) : Command(i), message(m) {}
- void operator()() { impl.acknowledgeImpl(message); }
+ Acknowledge2(SessionImpl& i, qpid::messaging::Message& m, bool c) : Command(i), message(m), cumulative(c) {}
+ void operator()() { impl.acknowledgeImpl(message, cumulative); }
};
struct CreateSender;
diff --git a/qpid/cpp/src/qpid/client/windows/SslConnector.cpp b/qpid/cpp/src/qpid/client/windows/SslConnector.cpp
index a33713e1a8..785c817928 100644
--- a/qpid/cpp/src/qpid/client/windows/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/windows/SslConnector.cpp
@@ -77,7 +77,7 @@ public:
framing::ProtocolVersion pVersion,
const ConnectionSettings&,
ConnectionImpl*);
- virtual void connect(const std::string& host, int port);
+ virtual void connect(const std::string& host, const std::string& port);
virtual void connected(const Socket&);
unsigned int getSSF();
};
@@ -153,7 +153,7 @@ SslConnector::~SslConnector()
// Will this get reach via virtual method via boost::bind????
-void SslConnector::connect(const std::string& host, int port) {
+void SslConnector::connect(const std::string& host, const std::string& port) {
brokerHost = host;
TCPConnector::connect(host, port);
}
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.cpp b/qpid/cpp/src/qpid/cluster/Cluster.cpp
index 0daf0c7f5a..82ed8bf8c9 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.cpp
+++ b/qpid/cpp/src/qpid/cluster/Cluster.cpp
@@ -146,6 +146,7 @@
#include "qpid/framing/AMQP_AllOperations.h"
#include "qpid/framing/AllInvoker.h"
#include "qpid/framing/ClusterConfigChangeBody.h"
+#include "qpid/framing/ClusterClockBody.h"
#include "qpid/framing/ClusterConnectionDeliverCloseBody.h"
#include "qpid/framing/ClusterConnectionAbortBody.h"
#include "qpid/framing/ClusterRetractOfferBody.h"
@@ -198,7 +199,7 @@ namespace _qmf = ::qmf::org::apache::qpid::cluster;
* Currently use SVN revision to avoid clashes with versions from
* different branches.
*/
-const uint32_t Cluster::CLUSTER_VERSION = 1097431;
+const uint32_t Cluster::CLUSTER_VERSION = 1128070;
struct ClusterDispatcher : public framing::AMQP_AllOperations::ClusterHandler {
qpid::cluster::Cluster& cluster;
@@ -230,7 +231,6 @@ struct ClusterDispatcher : public framing::AMQP_AllOperations::ClusterHandler {
cluster.updateOffer(member, updatee, l);
}
void retractOffer(uint64_t updatee) { cluster.retractOffer(member, updatee, l); }
- void messageExpired(uint64_t id) { cluster.messageExpired(member, id, l); }
void errorCheck(uint8_t type, const framing::SequenceNumber& frameSeq) {
cluster.errorCheck(member, type, frameSeq, l);
}
@@ -240,6 +240,7 @@ struct ClusterDispatcher : public framing::AMQP_AllOperations::ClusterHandler {
void deliverToQueue(const std::string& queue, const std::string& message) {
cluster.deliverToQueue(queue, message, l);
}
+ void clock(uint64_t time) { cluster.clock(time, l); }
bool invoke(AMQBody& body) { return framing::invoke(*this, body).wasHandled(); }
};
@@ -253,7 +254,7 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
self(cpg.self()),
clusterId(true),
mAgent(0),
- expiryPolicy(new ExpiryPolicy(mcast, self, broker.getTimer())),
+ expiryPolicy(new ExpiryPolicy(*this)),
mcast(cpg, poller, boost::bind(&Cluster::leave, this)),
dispatcher(cpg, poller, boost::bind(&Cluster::leave, this)),
deliverEventQueue(boost::bind(&Cluster::deliveredEvent, this, _1),
@@ -365,7 +366,8 @@ void Cluster::addShadowConnection(const boost::intrusive_ptr<Connection>& c) {
assert(discarding);
pair<ConnectionMap::iterator, bool> ib
= connections.insert(ConnectionMap::value_type(c->getId(), c));
- assert(ib.second);
+ // Like this to avoid tripping up unused variable warning when NDEBUG set
+ if (!ib.second) assert(ib.second);
}
void Cluster::erase(const ConnectionId& id) {
@@ -667,6 +669,8 @@ void Cluster::initMapCompleted(Lock& l) {
else { // I can go ready.
discarding = false;
setReady(l);
+ // Must be called *before* memberUpdate so first update will be generated.
+ failoverExchange->setReady();
memberUpdate(l);
updateMgmtMembership(l);
mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
@@ -719,6 +723,20 @@ void Cluster::configChange(const MemberId&,
updateMgmtMembership(l); // Update on every config change for consistency
}
+struct ClusterClockTask : public sys::TimerTask {
+ Cluster& cluster;
+ sys::Timer& timer;
+
+ ClusterClockTask(Cluster& cluster, sys::Timer& timer, uint16_t clockInterval)
+ : TimerTask(Duration(clockInterval * TIME_MSEC),"ClusterClock"), cluster(cluster), timer(timer) {}
+
+ void fire() {
+ cluster.sendClockUpdate();
+ setupNextFire();
+ timer.add(this);
+ }
+};
+
void Cluster::becomeElder(Lock&) {
if (elder) return; // We were already the elder.
// We are the oldest, reactive links if necessary
@@ -726,6 +744,8 @@ void Cluster::becomeElder(Lock&) {
elder = true;
broker.getLinks().setPassive(false);
timer->becomeElder();
+
+ clockTimer.add(new ClusterClockTask(*this, clockTimer, settings.clockInterval));
}
void Cluster::makeOffer(const MemberId& id, Lock& ) {
@@ -846,7 +866,7 @@ void Cluster::updateOffer(const MemberId& updater, uint64_t updateeInt, Lock& l)
if (updatee != self && url) {
QPID_LOG(debug, debugSnapshot());
if (mAgent) mAgent->clusterUpdate();
- // Updatee will call clusterUpdate when update completes
+ // Updatee will call clusterUpdate() via checkUpdateIn() when update completes
}
}
@@ -927,10 +947,11 @@ void Cluster::checkUpdateIn(Lock& l) {
if (!updateClosed) return; // Wait till update connection closes.
if (updatedMap) { // We're up to date
map = *updatedMap;
- failoverExchange->setUrls(getUrls(l));
mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
state = CATCHUP;
memberUpdate(l);
+ // Must be called *after* memberUpdate() to avoid sending an extra update.
+ failoverExchange->setReady();
// NB: don't updateMgmtMembership() here as we are not in the deliver
// thread. It will be updated on delivery of the "ready" we just mcast.
broker.setClusterUpdatee(false);
@@ -1120,10 +1141,6 @@ void Cluster::setClusterId(const Uuid& uuid, Lock&) {
QPID_LOG(notice, *this << " cluster-uuid = " << clusterId);
}
-void Cluster::messageExpired(const MemberId&, uint64_t id, Lock&) {
- expiryPolicy->deliverExpire(id);
-}
-
void Cluster::errorCheck(const MemberId& from, uint8_t type, framing::SequenceNumber frameSeq, Lock&) {
// If we see an errorCheck here (rather than in the ErrorCheck
// class) then we have processed succesfully past the point of the
@@ -1161,6 +1178,35 @@ void Cluster::deliverToQueue(const std::string& queue, const std::string& messag
q->deliver(msg);
}
+sys::AbsTime Cluster::getClusterTime() {
+ Mutex::ScopedLock l(lock);
+ return clusterTime;
+}
+
+// This method is called during update on the updatee to set the initial cluster time.
+void Cluster::clock(const uint64_t time) {
+ Mutex::ScopedLock l(lock);
+ clock(time, l);
+}
+
+// called when broadcast message received
+void Cluster::clock(const uint64_t time, Lock&) {
+ clusterTime = AbsTime(EPOCH, time);
+ AbsTime now = AbsTime::now();
+
+ if (!elder) {
+ clusterTimeOffset = Duration(now, clusterTime);
+ }
+}
+
+// called by elder timer to send clock broadcast
+void Cluster::sendClockUpdate() {
+ Mutex::ScopedLock l(lock);
+ int64_t nanosecondsSinceEpoch = Duration(EPOCH, now());
+ nanosecondsSinceEpoch += clusterTimeOffset;
+ mcast.mcastControl(ClusterClockBody(ProtocolVersion(), nanosecondsSinceEpoch), self);
+}
+
bool Cluster::deferDeliveryImpl(const std::string& queue,
const boost::intrusive_ptr<broker::Message>& msg)
{
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.h b/qpid/cpp/src/qpid/cluster/Cluster.h
index 78d325cdf9..adb06b2783 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.h
+++ b/qpid/cpp/src/qpid/cluster/Cluster.h
@@ -63,6 +63,12 @@ class AMQBody;
struct Uuid;
}
+namespace sys {
+class Timer;
+class AbsTime;
+class Duration;
+}
+
namespace cluster {
class Connection;
@@ -135,6 +141,9 @@ class Cluster : private Cpg::Handler, public management::Manageable {
bool deferDeliveryImpl(const std::string& queue,
const boost::intrusive_ptr<broker::Message>& msg);
+ sys::AbsTime getClusterTime();
+ void sendClockUpdate();
+ void clock(const uint64_t time);
private:
typedef sys::Monitor::ScopedLock Lock;
@@ -180,12 +189,12 @@ class Cluster : private Cpg::Handler, public management::Manageable {
const std::string& left,
const std::string& joined,
Lock& l);
- void messageExpired(const MemberId&, uint64_t, Lock& l);
void errorCheck(const MemberId&, uint8_t type, SequenceNumber frameSeq, Lock&);
void timerWakeup(const MemberId&, const std::string& name, Lock&);
void timerDrop(const MemberId&, const std::string& name, Lock&);
void shutdown(const MemberId&, const framing::Uuid& shutdownId, Lock&);
void deliverToQueue(const std::string& queue, const std::string& message, Lock&);
+ void clock(const uint64_t time, Lock&);
// Helper functions
ConnectionPtr getConnection(const EventFrame&, Lock&);
@@ -296,6 +305,9 @@ class Cluster : private Cpg::Handler, public management::Manageable {
ErrorCheck error;
UpdateReceiver updateReceiver;
ClusterTimer* timer;
+ sys::Timer clockTimer;
+ sys::AbsTime clusterTime;
+ sys::Duration clusterTimeOffset;
friend std::ostream& operator<<(std::ostream&, const Cluster&);
friend struct ClusterDispatcher;
diff --git a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
index 2962daaa07..69ba095f16 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
@@ -72,6 +72,7 @@ struct ClusterOptions : public Options {
("cluster-cman", optValue(settings.quorum), "Integrate with Cluster Manager (CMAN) cluster.")
#endif
("cluster-size", optValue(settings.size, "N"), "Wait for N cluster members before allowing clients to connect.")
+ ("cluster-clock-interval", optValue(settings.clockInterval,"N"), "How often to broadcast the current time to the cluster nodes, in milliseconds. A value between 5 and 1000 is recommended.")
("cluster-read-max", optValue(settings.readMax,"N"), "Experimental: flow-control limit reads per connection. 0=no limit.")
;
}
diff --git a/qpid/cpp/src/qpid/cluster/ClusterSettings.h b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
index 8e708aa139..2f7b5be20a 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterSettings.h
+++ b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
@@ -35,8 +35,9 @@ struct ClusterSettings {
size_t readMax;
std::string username, password, mechanism;
size_t size;
+ uint16_t clockInterval;
- ClusterSettings() : quorum(false), readMax(10), size(1)
+ ClusterSettings() : quorum(false), readMax(10), size(1), clockInterval(10)
{}
Url getUrl(uint16_t port) const {
diff --git a/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp b/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp
index f6e1c7a849..b4f7d00f38 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp
@@ -70,6 +70,7 @@ void ClusterTimer::add(intrusive_ptr<TimerTask> task)
if (i != map.end())
throw Exception(QPID_MSG("Task already exists with name " << task->getName()));
map[task->getName()] = task;
+
// Only the elder actually activates the task with the Timer base class.
if (cluster.isElder()) {
QPID_LOG(trace, "Elder activating cluster timer task " << task->getName());
@@ -112,6 +113,9 @@ void ClusterTimer::deliverWakeup(const std::string& name) {
else {
intrusive_ptr<TimerTask> t = i->second;
map.erase(i);
+ // Move the nextFireTime so readyToFire() is true. This is to ensure we
+ // don't get an error if the fired task calls setupNextFire()
+ t->setFired();
Timer::fire(t);
}
}
diff --git a/qpid/cpp/src/qpid/cluster/Connection.cpp b/qpid/cpp/src/qpid/cluster/Connection.cpp
index b9895290e9..030d6e34c1 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.cpp
+++ b/qpid/cpp/src/qpid/cluster/Connection.cpp
@@ -322,10 +322,10 @@ size_t Connection::decode(const char* data, size_t size) {
while (localDecoder.decode(buf))
received(localDecoder.getFrame());
if (!wasOpen && connection->isOpen()) {
- // Connections marked as federation links are allowed to proxy
+ // Connections marked with setUserProxyAuth are allowed to proxy
// messages with user-ID that doesn't match the connection's
// authenticated ID. This is important for updates.
- connection->setFederationLink(isCatchUp());
+ connection->setUserProxyAuth(isCatchUp());
}
}
else { // Multicast local connections.
@@ -601,10 +601,6 @@ void Connection::queueObserverState(const std::string& qname, const std::string&
QPID_LOG(error, "Failed to find observer " << observerId << " state on queue " << qname << "; this will result in inconsistencies.");
}
-void Connection::expiryId(uint64_t id) {
- cluster.getExpiryPolicy().setId(id);
-}
-
std::ostream& operator<<(std::ostream& o, const Connection& c) {
const char* type="unknown";
if (c.isLocal()) type = "local";
@@ -724,5 +720,16 @@ void Connection::doCatchupIoCallbacks() {
if (catchUp) getBrokerConnection()->doIoCallbacks();
}
+
+void Connection::clock(uint64_t time) {
+ QPID_LOG(debug, "Cluster connection received time update");
+ cluster.clock(time);
+}
+
+void Connection::queueDequeueSincePurgeState(const std::string& qname, uint32_t dequeueSincePurge) {
+ boost::shared_ptr<broker::Queue> queue(findQueue(qname));
+ queue->setDequeueSincePurge(dequeueSincePurge);
+}
+
}} // Namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/Connection.h b/qpid/cpp/src/qpid/cluster/Connection.h
index a0da9efbb8..a9740f97f8 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.h
+++ b/qpid/cpp/src/qpid/cluster/Connection.h
@@ -155,7 +155,6 @@ class Connection :
void queuePosition(const std::string&, const framing::SequenceNumber&);
void queueFairshareState(const std::string&, const uint8_t priority, const uint8_t count);
void queueObserverState(const std::string&, const std::string&, const framing::FieldTable&);
- void expiryId(uint64_t);
void txStart();
void txAccept(const framing::SequenceSet&);
@@ -192,6 +191,10 @@ class Connection :
void doCatchupIoCallbacks();
+ void clock(uint64_t time);
+
+ void queueDequeueSincePurgeState(const std::string&, uint32_t);
+
private:
struct NullFrameHandler : public framing::FrameHandler {
void handle(framing::AMQFrame&) {}
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
index d9a7b0122a..0ef5c2a35d 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
@@ -21,106 +21,21 @@
#include "qpid/broker/Message.h"
#include "qpid/cluster/ExpiryPolicy.h"
-#include "qpid/cluster/Multicaster.h"
-#include "qpid/framing/ClusterMessageExpiredBody.h"
+#include "qpid/cluster/Cluster.h"
#include "qpid/sys/Time.h"
-#include "qpid/sys/Timer.h"
#include "qpid/log/Statement.h"
namespace qpid {
namespace cluster {
-ExpiryPolicy::ExpiryPolicy(Multicaster& m, const MemberId& id, sys::Timer& t)
- : expiryId(1), expiredPolicy(new Expired), mcast(m), memberId(id), timer(t) {}
+ExpiryPolicy::ExpiryPolicy(Cluster& cluster) : cluster(cluster) {}
-struct ExpiryTask : public sys::TimerTask {
- ExpiryTask(const boost::intrusive_ptr<ExpiryPolicy>& policy, uint64_t id, sys::AbsTime when)
- : TimerTask(when,"ExpiryPolicy"), expiryPolicy(policy), expiryId(id) {}
- void fire() { expiryPolicy->sendExpire(expiryId); }
- boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
- const uint64_t expiryId;
-};
-
-// Called while receiving an update
-void ExpiryPolicy::setId(uint64_t id) {
- sys::Mutex::ScopedLock l(lock);
- expiryId = id;
-}
-
-// Called while giving an update
-uint64_t ExpiryPolicy::getId() const {
- sys::Mutex::ScopedLock l(lock);
- return expiryId;
-}
-
-// Called in enqueuing connection thread
-void ExpiryPolicy::willExpire(broker::Message& m) {
- uint64_t id;
- {
- // When messages are fanned out to multiple queues, update sends
- // them as independenty messages so we can have multiple messages
- // with the same expiry ID.
- //
- sys::Mutex::ScopedLock l(lock);
- id = expiryId++;
- if (!id) { // This is an update of an already-expired message.
- m.setExpiryPolicy(expiredPolicy);
- }
- else {
- assert(unexpiredByMessage.find(&m) == unexpiredByMessage.end());
- // If this is an update, the id may already exist
- unexpiredById.insert(IdMessageMap::value_type(id, &m));
- unexpiredByMessage[&m] = id;
- }
- }
- timer.add(new ExpiryTask(this, id, m.getExpiration()));
-}
-
-// Called in dequeueing connection thread
-void ExpiryPolicy::forget(broker::Message& m) {
- sys::Mutex::ScopedLock l(lock);
- MessageIdMap::iterator i = unexpiredByMessage.find(&m);
- assert(i != unexpiredByMessage.end());
- unexpiredById.erase(i->second);
- unexpiredByMessage.erase(i);
-}
-
-// Called in dequeueing connection or cleanup thread.
bool ExpiryPolicy::hasExpired(broker::Message& m) {
- sys::Mutex::ScopedLock l(lock);
- return unexpiredByMessage.find(&m) == unexpiredByMessage.end();
-}
-
-// Called in timer thread
-void ExpiryPolicy::sendExpire(uint64_t id) {
- {
- sys::Mutex::ScopedLock l(lock);
- // Don't multicast an expiry notice if message is already forgotten.
- if (unexpiredById.find(id) == unexpiredById.end()) return;
- }
- mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId);
+ return m.getExpiration() < cluster.getClusterTime();
}
-// Called in CPG deliver thread.
-void ExpiryPolicy::deliverExpire(uint64_t id) {
- sys::Mutex::ScopedLock l(lock);
- std::pair<IdMessageMap::iterator, IdMessageMap::iterator> expired = unexpiredById.equal_range(id);
- IdMessageMap::iterator i = expired.first;
- while (i != expired.second) {
- i->second->setExpiryPolicy(expiredPolicy); // hasExpired() == true;
- unexpiredByMessage.erase(i->second);
- unexpiredById.erase(i++);
- }
+sys::AbsTime ExpiryPolicy::getCurrentTime() {
+ return cluster.getClusterTime();
}
-// Called in update thread on the updater.
-boost::optional<uint64_t> ExpiryPolicy::getId(broker::Message& m) {
- sys::Mutex::ScopedLock l(lock);
- MessageIdMap::iterator i = unexpiredByMessage.find(&m);
- return i == unexpiredByMessage.end() ? boost::optional<uint64_t>() : i->second;
-}
-
-bool ExpiryPolicy::Expired::hasExpired(broker::Message&) { return true; }
-void ExpiryPolicy::Expired::willExpire(broker::Message&) { }
-
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
index 77a656aa68..d8ddbca8b3 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
@@ -36,12 +36,8 @@ namespace broker {
class Message;
}
-namespace sys {
-class Timer;
-}
-
namespace cluster {
-class Multicaster;
+class Cluster;
/**
* Cluster expiry policy
@@ -49,43 +45,13 @@ class Multicaster;
class ExpiryPolicy : public broker::ExpiryPolicy
{
public:
- ExpiryPolicy(Multicaster&, const MemberId&, sys::Timer&);
+ ExpiryPolicy(Cluster& cluster);
- void willExpire(broker::Message&);
bool hasExpired(broker::Message&);
- void forget(broker::Message&);
-
- // Send expiration notice to cluster.
- void sendExpire(uint64_t);
+ qpid::sys::AbsTime getCurrentTime();
- // Cluster delivers expiry notice.
- void deliverExpire(uint64_t);
-
- void setId(uint64_t id);
- uint64_t getId() const;
-
- boost::optional<uint64_t> getId(broker::Message&);
-
private:
- typedef std::map<broker::Message*, uint64_t> MessageIdMap;
- // When messages are fanned out to multiple queues, update sends
- // them as independenty messages so we can have multiple messages
- // with the same expiry ID.
- typedef std::multimap<uint64_t, broker::Message*> IdMessageMap;
-
- struct Expired : public broker::ExpiryPolicy {
- bool hasExpired(broker::Message&);
- void willExpire(broker::Message&);
- };
-
- mutable sys::Mutex lock;
- MessageIdMap unexpiredByMessage;
- IdMessageMap unexpiredById;
- uint64_t expiryId;
- boost::intrusive_ptr<Expired> expiredPolicy;
- Multicaster& mcast;
- MemberId memberId;
- sys::Timer& timer;
+ Cluster& cluster;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp b/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp
index 84232dac1b..cfbe34a460 100644
--- a/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp
+++ b/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp
@@ -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
@@ -39,8 +39,10 @@ using namespace broker;
using namespace framing;
const string FailoverExchange::typeName("amq.failover");
-
-FailoverExchange::FailoverExchange(management::Manageable* parent, Broker* b) : Exchange(typeName, parent, b ) {
+
+FailoverExchange::FailoverExchange(management::Manageable* parent, Broker* b)
+ : Exchange(typeName, parent, b ), ready(false)
+{
if (mgmtExchange != 0)
mgmtExchange->set_type(typeName);
}
@@ -53,16 +55,17 @@ void FailoverExchange::setUrls(const vector<Url>& u) {
void FailoverExchange::updateUrls(const vector<Url>& u) {
Lock l(lock);
urls=u;
- if (urls.empty()) return;
- std::for_each(queues.begin(), queues.end(),
- boost::bind(&FailoverExchange::sendUpdate, this, _1));
+ if (ready && !urls.empty()) {
+ std::for_each(queues.begin(), queues.end(),
+ boost::bind(&FailoverExchange::sendUpdate, this, _1));
+ }
}
string FailoverExchange::getType() const { return typeName; }
bool FailoverExchange::bind(Queue::shared_ptr queue, const string&, const framing::FieldTable*) {
Lock l(lock);
- sendUpdate(queue);
+ if (ready) sendUpdate(queue);
return queues.insert(queue).second;
}
@@ -84,7 +87,7 @@ void FailoverExchange::sendUpdate(const Queue::shared_ptr& queue) {
// Called with lock held.
if (urls.empty()) return;
framing::Array array(0x95);
- for (Urls::const_iterator i = urls.begin(); i != urls.end(); ++i)
+ for (Urls::const_iterator i = urls.begin(); i != urls.end(); ++i)
array.add(boost::shared_ptr<Str16Value>(new Str16Value(i->str())));
const ProtocolVersion v;
boost::intrusive_ptr<Message> msg(new Message);
@@ -96,9 +99,12 @@ void FailoverExchange::sendUpdate(const Queue::shared_ptr& queue) {
header.get<MessageProperties>(true)->getApplicationHeaders().setArray(typeName, array);
AMQFrame headerFrame(header);
headerFrame.setFirstSegment(false);
- msg->getFrames().append(headerFrame);
+ msg->getFrames().append(headerFrame);
DeliverableMessage(msg).deliverTo(queue);
}
+void FailoverExchange::setReady() {
+ ready = true;
+}
}} // namespace cluster
diff --git a/qpid/cpp/src/qpid/cluster/FailoverExchange.h b/qpid/cpp/src/qpid/cluster/FailoverExchange.h
index 2e1edfc0ae..c3e50c6929 100644
--- a/qpid/cpp/src/qpid/cluster/FailoverExchange.h
+++ b/qpid/cpp/src/qpid/cluster/FailoverExchange.h
@@ -10,9 +10,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
@@ -46,6 +46,8 @@ class FailoverExchange : public broker::Exchange
void setUrls(const std::vector<Url>&);
/** Set the URLs and send an update.*/
void updateUrls(const std::vector<Url>&);
+ /** Flag the failover exchange as ready to generate updates (caught up) */
+ void setReady();
// Exchange overrides
std::string getType() const;
@@ -56,7 +58,7 @@ class FailoverExchange : public broker::Exchange
private:
void sendUpdate(const boost::shared_ptr<broker::Queue>&);
-
+
typedef sys::Mutex::ScopedLock Lock;
typedef std::vector<Url> Urls;
typedef std::set<boost::shared_ptr<broker::Queue> > Queues;
@@ -64,7 +66,7 @@ class FailoverExchange : public broker::Exchange
sys::Mutex lock;
Urls urls;
Queues queues;
-
+ bool ready;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
index a15c14ff48..77448789db 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
@@ -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
@@ -26,9 +26,9 @@
#include "qpid/cluster/Decoder.h"
#include "qpid/cluster/ExpiryPolicy.h"
#include "qpid/cluster/UpdateDataExchange.h"
-#include "qpid/client/SessionBase_0_10Access.h"
-#include "qpid/client/ConnectionAccess.h"
-#include "qpid/client/SessionImpl.h"
+#include "qpid/client/SessionBase_0_10Access.h"
+#include "qpid/client/ConnectionAccess.h"
+#include "qpid/client/SessionImpl.h"
#include "qpid/client/ConnectionImpl.h"
#include "qpid/client/Future.h"
#include "qpid/broker/Broker.h"
@@ -83,11 +83,20 @@ using namespace framing;
namespace arg=client::arg;
using client::SessionBase_0_10Access;
+// Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges.
+const std::string UpdateClient::UPDATE("x-qpid.cluster-update");
+// Name for header used to carry expiration information.
+const std::string UpdateClient::X_QPID_EXPIRATION = "x-qpid.expiration";
+// Headers used to flag headers/properties added by the UpdateClient so they can be
+// removed on the other side.
+const std::string UpdateClient::X_QPID_NO_MESSAGE_PROPS = "x-qpid.no-message-props";
+const std::string UpdateClient::X_QPID_NO_HEADERS = "x-qpid.no-headers";
+
std::ostream& operator<<(std::ostream& o, const UpdateClient& c) {
return o << "cluster(" << c.updaterId << " UPDATER)";
}
-struct ClusterConnectionProxy : public AMQP_AllProxy::ClusterConnection, public framing::FrameHandler
+struct ClusterConnectionProxy : public AMQP_AllProxy::ClusterConnection, public framing::FrameHandler
{
boost::shared_ptr<qpid::client::ConnectionImpl> connection;
@@ -121,7 +130,7 @@ void send(client::AsyncSession& s, const AMQBody& body) {
// TODO aconway 2008-09-24: optimization: update connections/sessions in parallel.
UpdateClient::UpdateClient(const MemberId& updater, const MemberId& updatee, const Url& url,
- broker::Broker& broker, const ClusterMap& m, ExpiryPolicy& expiry_,
+ broker::Broker& broker, const ClusterMap& m, ExpiryPolicy& expiry_,
const Cluster::ConnectionVector& cons, Decoder& decoder_,
const boost::function<void()>& ok,
const boost::function<void(const std::exception&)>& fail,
@@ -135,9 +144,6 @@ UpdateClient::UpdateClient(const MemberId& updater, const MemberId& updatee, con
UpdateClient::~UpdateClient() {}
-// Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges.
-const std::string UpdateClient::UPDATE("qpid.cluster-update");
-
void UpdateClient::run() {
try {
connection.open(updateeUrl, connectionSettings);
@@ -155,6 +161,13 @@ void UpdateClient::update() {
<< " at " << updateeUrl);
Broker& b = updaterBroker;
+ if(b.getExpiryPolicy()) {
+ QPID_LOG(debug, *this << "Updating updatee with cluster time");
+ qpid::sys::AbsTime clusterTime = b.getExpiryPolicy()->getCurrentTime();
+ int64_t time = qpid::sys::Duration(qpid::sys::EPOCH, clusterTime);
+ ClusterConnectionProxy(session).clock(time);
+ }
+
updateManagementSetupState();
b.getExchanges().eachExchange(boost::bind(&UpdateClient::updateExchange, this, _1));
@@ -174,7 +187,6 @@ void UpdateClient::update() {
// Update queue listeners: must come after sessions so consumerNumbering is populated
b.getQueues().eachQueue(boost::bind(&UpdateClient::updateQueueListeners, this, _1));
- ClusterConnectionProxy(session).expiryId(expiry.getId());
updateLinks();
updateManagementAgent();
@@ -188,7 +200,7 @@ void UpdateClient::update() {
// NOTE: connection will be closed from the other end, don't close
// it here as that causes a race.
-
+
// TODO aconway 2010-03-15: This sleep avoids the race condition
// described in // https://bugzilla.redhat.com/show_bug.cgi?id=568831.
// It allows the connection to fully close before destroying the
@@ -280,7 +292,7 @@ class MessageUpdater {
framing::SequenceNumber lastPos;
client::AsyncSession session;
ExpiryPolicy& expiry;
-
+
public:
MessageUpdater(const string& q, const client::AsyncSession s, ExpiryPolicy& expiry_) : queue(q), haveLastPos(false), session(s), expiry(expiry_) {
@@ -297,7 +309,6 @@ class MessageUpdater {
}
}
-
void updateQueuedMessage(const broker::QueuedMessage& message) {
// Send the queue position if necessary.
if (!haveLastPos || message.position - lastPos != 1) {
@@ -306,10 +317,23 @@ class MessageUpdater {
}
lastPos = message.position;
- // Send the expiry ID if necessary.
- if (message.payload->getProperties<DeliveryProperties>()->getTtl()) {
- boost::optional<uint64_t> expiryId = expiry.getId(*message.payload);
- ClusterConnectionProxy(session).expiryId(expiryId?*expiryId:0);
+ // if the ttl > 0, we need to send the calculated expiration time to the updatee
+ if (message.payload->getProperties<DeliveryProperties>()->getTtl() > 0) {
+ bool hadMessageProps =
+ message.payload->hasProperties<framing::MessageProperties>();
+ framing::MessageProperties* mprops =
+ message.payload->getProperties<framing::MessageProperties>();
+ bool hadApplicationHeaders = mprops->hasApplicationHeaders();
+ FieldTable& applicationHeaders = mprops->getApplicationHeaders();
+ applicationHeaders.setInt64(
+ UpdateClient::X_QPID_EXPIRATION,
+ sys::Duration(sys::EPOCH, message.payload->getExpiration()));
+ // If message properties or application headers didn't exist
+ // prior to us adding data, we want to remove them on the other side.
+ if (!hadMessageProps)
+ applicationHeaders.setInt(UpdateClient::X_QPID_NO_MESSAGE_PROPS, 0);
+ else if (!hadApplicationHeaders)
+ applicationHeaders.setInt(UpdateClient::X_QPID_NO_HEADERS, 0);
}
// We can't send a broker::Message via the normal client API,
@@ -322,7 +346,7 @@ class MessageUpdater {
framing::MessageTransferBody transfer(
*message.payload->getFrames().as<framing::MessageTransferBody>());
transfer.setDestination(UpdateClient::UPDATE);
-
+
sb.get()->send(transfer, message.payload->getFrames(),
!message.payload->isContentReleased());
if (message.payload->isContentReleased()){
@@ -330,12 +354,21 @@ class MessageUpdater {
uint16_t maxContentSize = maxFrameSize - AMQFrame::frameOverhead();
bool morecontent = true;
for (uint64_t offset = 0; morecontent; offset += maxContentSize)
- {
+ {
AMQFrame frame((AMQContentBody()));
morecontent = message.payload->getContentFrame(*(message.queue), frame, maxContentSize, offset);
sb.get()->sendRawFrame(frame);
}
}
+ // If the ttl > 0, we need to send the calculated expiration time to the updatee
+ // Careful not to alter the message as a side effect e.g. by adding
+ // an empty DeliveryProperties or setting TTL when it wasn't set before.
+ uint64_t ttl = 0;
+ if (message.payload->hasProperties<DeliveryProperties>()) {
+ DeliveryProperties* dprops =
+ message.payload->getProperties<DeliveryProperties>();
+ if (dprops->hasTtl()) ttl = dprops->getTtl();
+ };
}
void updateMessage(const boost::intrusive_ptr<broker::Message>& message) {
@@ -361,6 +394,8 @@ void UpdateClient::updateQueue(client::AsyncSession& s, const boost::shared_ptr<
if (qpid::broker::Fairshare::getState(q->getMessages(), priority, count)) {
ClusterConnectionProxy(s).queueFairshareState(q->getName(), priority, count);
}
+
+ ClusterConnectionProxy(s).queueDequeueSincePurgeState(q->getName(), q->getDequeueSincePurge());
}
void UpdateClient::updateExclusiveQueue(const boost::shared_ptr<broker::Queue>& q) {
@@ -393,7 +428,7 @@ void UpdateClient::updateConnection(const boost::intrusive_ptr<Connection>& upda
QPID_LOG(debug, *this << " updating connection " << *updateConnection);
assert(updateConnection->getBrokerConnection());
broker::Connection& bc = *updateConnection->getBrokerConnection();
-
+
// Send the management ID first on the main connection.
std::string mgmtId = updateConnection->getBrokerConnection()->getMgmtId();
ClusterConnectionProxy(session).shadowPrepare(mgmtId);
@@ -430,7 +465,7 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
QPID_LOG(debug, *this << " updating session " << ss->getId());
- // Create a client session to update session state.
+ // Create a client session to update session state.
boost::shared_ptr<client::ConnectionImpl> cimpl = client::ConnectionAccess::getImpl(shadowConnection);
boost::shared_ptr<client::SessionImpl> simpl = cimpl->newSession(ss->getId().getName(), ss->getTimeout(), sh.getChannel());
simpl->disableAutoDetach();
@@ -456,12 +491,12 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
// Adjust command counter for message in progress, will be sent after state update.
boost::intrusive_ptr<Message> inProgress = ss->getMessageInProgress();
SequenceNumber received = ss->receiverGetReceived().command;
- if (inProgress)
+ if (inProgress)
--received;
// Sync the session to ensure all responses from broker have been processed.
shadowSession.sync();
-
+
// Reset command-sequence state.
proxy.sessionState(
ss->senderGetReplayPoint().command,
@@ -511,7 +546,7 @@ void UpdateClient::updateConsumer(
QPID_LOG(debug, *this << " updated consumer " << ci->getName()
<< " on " << shadowSession.getId());
}
-
+
void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) {
if (!dr.isEnded() && dr.isAcquired() && dr.getMessage().payload) {
// If the message is acquired then it is no longer on the
@@ -543,7 +578,7 @@ class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
void operator()(const broker::DtxAck& ) {
throw InternalErrorException("DTX transactions not currently supported by cluster.");
}
-
+
void operator()(const broker::RecoveredDequeue& rdeq) {
updateMessage(rdeq.getMessage());
proxy.txEnqueue(rdeq.getQueue()->getName());
@@ -563,7 +598,7 @@ class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
typedef std::list<Queue::shared_ptr> QueueList;
const QueueList& qlist = txPub.getQueues();
Array qarray(TYPE_CODE_STR8);
- for (QueueList::const_iterator i = qlist.begin(); i != qlist.end(); ++i)
+ for (QueueList::const_iterator i = qlist.begin(); i != qlist.end(); ++i)
qarray.push_back(Array::ValuePtr(new Str8Value((*i)->getName())));
proxy.txPublish(qarray, txPub.delivered);
}
@@ -573,7 +608,7 @@ class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
client::AsyncSession session;
ClusterConnectionProxy proxy;
};
-
+
void UpdateClient::updateTxState(broker::SemanticState& s) {
QPID_LOG(debug, *this << " updating TX transaction state.");
ClusterConnectionProxy proxy(shadowSession);
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.h b/qpid/cpp/src/qpid/cluster/UpdateClient.h
index b72d090d73..21bf6024e0 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.h
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.h
@@ -10,9 +10,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
@@ -69,14 +69,19 @@ class ExpiryPolicy;
class UpdateClient : public sys::Runnable {
public:
static const std::string UPDATE; // Name for special update queue and exchange.
+ static const std::string X_QPID_EXPIRATION; // Update message expiration
+ // Flag to remove props/headers that were added by the UpdateClient
+ static const std::string X_QPID_NO_MESSAGE_PROPS;
+ static const std::string X_QPID_NO_HEADERS;
+
static client::Connection catchUpConnection();
-
+
UpdateClient(const MemberId& updater, const MemberId& updatee, const Url&,
broker::Broker& donor, const ClusterMap& map, ExpiryPolicy& expiry,
const std::vector<boost::intrusive_ptr<Connection> >&, Decoder&,
const boost::function<void()>& done,
const boost::function<void(const std::exception&)>& fail,
- const client::ConnectionSettings&
+ const client::ConnectionSettings&
);
~UpdateClient();
diff --git a/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp b/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp
index 11937f296f..e830459aba 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp
@@ -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
@@ -19,6 +19,7 @@
*
*/
#include "qpid/framing/MessageTransferBody.h"
+#include "qpid/framing/FieldTable.h"
#include "qpid/broker/Message.h"
#include "UpdateExchange.h"
@@ -27,6 +28,8 @@ namespace cluster {
using framing::MessageTransferBody;
using framing::DeliveryProperties;
+using framing::MessageProperties;
+using framing::FieldTable;
UpdateExchange::UpdateExchange(management::Manageable* parent)
: broker::Exchange(UpdateClient::UPDATE, parent),
@@ -34,6 +37,7 @@ UpdateExchange::UpdateExchange(management::Manageable* parent)
void UpdateExchange::setProperties(const boost::intrusive_ptr<broker::Message>& msg) {
+ // Copy exchange name to destination property.
MessageTransferBody* transfer = msg->getMethod<MessageTransferBody>();
assert(transfer);
const DeliveryProperties* props = msg->getProperties<DeliveryProperties>();
@@ -42,6 +46,23 @@ void UpdateExchange::setProperties(const boost::intrusive_ptr<broker::Message>&
transfer->setDestination(props->getExchange());
else
transfer->clearDestinationFlag();
-}
+ // Copy expiration from x-property if present.
+ if (msg->hasProperties<MessageProperties>()) {
+ MessageProperties* mprops = msg->getProperties<MessageProperties>();
+ if (mprops->hasApplicationHeaders()) {
+ FieldTable& headers = mprops->getApplicationHeaders();
+ if (headers.isSet(UpdateClient::X_QPID_EXPIRATION)) {
+ msg->setExpiration(
+ sys::AbsTime(sys::EPOCH, headers.getAsInt64(UpdateClient::X_QPID_EXPIRATION)));
+ headers.erase(UpdateClient::X_QPID_EXPIRATION);
+ // Erase props/headers that were added by the UpdateClient
+ if (headers.isSet(UpdateClient::X_QPID_NO_MESSAGE_PROPS))
+ msg->eraseProperties<MessageProperties>();
+ else if (headers.isSet(UpdateClient::X_QPID_NO_HEADERS))
+ mprops->clearApplicationHeadersFlag();
+ }
+ }
+ }
+}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/console/SessionManager.cpp b/qpid/cpp/src/qpid/console/SessionManager.cpp
index 80c5959417..910ae22be8 100644
--- a/qpid/cpp/src/qpid/console/SessionManager.cpp
+++ b/qpid/cpp/src/qpid/console/SessionManager.cpp
@@ -362,12 +362,11 @@ void SessionManager::handleCommandComplete(Broker* broker, Buffer& inBuffer, uin
void SessionManager::handleClassInd(Broker* broker, Buffer& inBuffer, uint32_t)
{
- uint8_t kind;
string packageName;
string className;
uint8_t hash[16];
- kind = inBuffer.getOctet();
+ /*kind*/ (void) inBuffer.getOctet();
inBuffer.getShortString(packageName);
inBuffer.getShortString(className);
inBuffer.getBin128(hash);
diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
index a8c326969a..452154eb5c 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
@@ -10,9 +10,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
@@ -58,7 +58,7 @@ class QPID_COMMON_CLASS_EXTERN AMQHeaderBody : public AMQBody
}
else
return Base::decode(buffer, size, type);
- }
+ }
void print(std::ostream& out) const {
const boost::optional<T>& p=this->OptProps<T>::props;
if (p) out << *p;
@@ -77,7 +77,7 @@ class QPID_COMMON_CLASS_EXTERN AMQHeaderBody : public AMQBody
typedef PropSet<PropSet<Empty, DeliveryProperties>, MessageProperties> Properties;
Properties properties;
-
+
public:
inline uint8_t type() const { return HEADER_BODY; }
@@ -99,6 +99,10 @@ public:
return properties.OptProps<T>::props.get_ptr();
}
+ template <class T> void erase() {
+ properties.OptProps<T>::props.reset();
+ }
+
boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
diff --git a/qpid/cpp/src/qpid/messaging/Session.cpp b/qpid/cpp/src/qpid/messaging/Session.cpp
index 496953a8e5..cccfd9a873 100644
--- a/qpid/cpp/src/qpid/messaging/Session.cpp
+++ b/qpid/cpp/src/qpid/messaging/Session.cpp
@@ -39,7 +39,8 @@ Session& Session::operator=(const Session& s) { return PI::assign(*this, s); }
void Session::commit() { impl->commit(); }
void Session::rollback() { impl->rollback(); }
void Session::acknowledge(bool sync) { impl->acknowledge(sync); }
-void Session::acknowledge(Message& m, bool s) { impl->acknowledge(m); sync(s); }
+void Session::acknowledge(Message& m, bool s) { impl->acknowledge(m, false); sync(s); }
+void Session::acknowledgeUpTo(Message& m, bool s) { impl->acknowledge(m, true); sync(s); }
void Session::reject(Message& m) { impl->reject(m); }
void Session::release(Message& m) { impl->release(m); }
void Session::close() { impl->close(); }
diff --git a/qpid/cpp/src/qpid/messaging/SessionImpl.h b/qpid/cpp/src/qpid/messaging/SessionImpl.h
index 02a254e4f2..60ae615253 100644
--- a/qpid/cpp/src/qpid/messaging/SessionImpl.h
+++ b/qpid/cpp/src/qpid/messaging/SessionImpl.h
@@ -41,7 +41,7 @@ class SessionImpl : public virtual qpid::RefCounted
virtual void commit() = 0;
virtual void rollback() = 0;
virtual void acknowledge(bool sync) = 0;
- virtual void acknowledge(Message&) = 0;
+ virtual void acknowledge(Message&, bool cumulative) = 0;
virtual void reject(Message&) = 0;
virtual void release(Message&) = 0;
virtual void close() = 0;
diff --git a/qpid/cpp/src/qpid/sys/AsynchIO.h b/qpid/cpp/src/qpid/sys/AsynchIO.h
index 50da8fa4fc..41f74f7ed0 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIO.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIO.h
@@ -64,8 +64,8 @@ public:
// deletes. To correctly manage heaps when needed, the allocate and
// delete should both be done from the same class/library.
QPID_COMMON_EXTERN static AsynchConnector* create(const Socket& s,
- std::string hostname,
- uint16_t port,
+ const std::string& hostname,
+ const std::string& port,
ConnectedCallback connCb,
FailedCallback failCb);
virtual void start(boost::shared_ptr<Poller> poller) = 0;
diff --git a/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h b/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h
index d022b07c1d..724bae422e 100644
--- a/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h
+++ b/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h
@@ -10,9 +10,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
@@ -39,6 +39,9 @@ class AtomicValue
public:
AtomicValue(T init=0) : value(init) {}
+ // Not atomic. Don't call concurrently with atomic ops.
+ AtomicValue<T>& operator=(T newValue) { value = newValue; return *this; }
+
// Update and return new value.
inline T operator+=(T n) { return __sync_add_and_fetch(&value, n); }
inline T operator-=(T n) { return __sync_sub_and_fetch(&value, n); }
@@ -54,11 +57,11 @@ class AtomicValue
/** If current value == testval then set to newval. Returns the old value. */
T valueCompareAndSwap(T testval, T newval) { return __sync_val_compare_and_swap(&value, testval, newval); }
- /** If current value == testval then set to newval. Returns true if the swap was performed. */
+ /** If current value == testval then set to newval. Returns true if the swap was performed. */
bool boolCompareAndSwap(T testval, T newval) { return __sync_bool_compare_and_swap(&value, testval, newval); }
T get() const { return const_cast<AtomicValue<T>*>(this)->fetchAndAdd(static_cast<T>(0)); }
-
+
private:
T value;
};
diff --git a/qpid/cpp/src/qpid/sys/ProtocolFactory.h b/qpid/cpp/src/qpid/sys/ProtocolFactory.h
index b233b2da1a..4d198a92da 100644
--- a/qpid/cpp/src/qpid/sys/ProtocolFactory.h
+++ b/qpid/cpp/src/qpid/sys/ProtocolFactory.h
@@ -39,11 +39,10 @@ class ProtocolFactory : public qpid::SharedObject<ProtocolFactory>
virtual ~ProtocolFactory() = 0;
virtual uint16_t getPort() const = 0;
- virtual std::string getHost() const = 0;
virtual void accept(boost::shared_ptr<Poller>, ConnectionCodec::Factory*) = 0;
virtual void connect(
boost::shared_ptr<Poller>,
- const std::string& host, int16_t port,
+ const std::string& host, const std::string& port,
ConnectionCodec::Factory* codec,
ConnectFailedCallback failed) = 0;
virtual bool supports(const std::string& /*capability*/) { return false; }
diff --git a/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp b/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp
index d53db20598..6769e5383c 100644
--- a/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp
@@ -31,7 +31,6 @@
#include "qpid/sys/SecuritySettings.h"
#include <boost/bind.hpp>
-#include <boost/lexical_cast.hpp>
#include <memory>
#include <netdb.h>
@@ -212,10 +211,9 @@ void RdmaIOHandler::readbuff(Rdma::AsynchIO&, Rdma::Buffer* buff) {
if (readError) {
return;
}
- size_t decoded = 0;
try {
if (codec) {
- decoded = codec->decode(buff->bytes(), buff->dataCount());
+ (void) codec->decode(buff->bytes(), buff->dataCount());
}else{
// Need to start protocol processing
initProtocolIn(buff);
@@ -230,9 +228,7 @@ void RdmaIOHandler::readbuff(Rdma::AsynchIO&, Rdma::Buffer* buff) {
void RdmaIOHandler::initProtocolIn(Rdma::Buffer* buff) {
framing::Buffer in(buff->bytes(), buff->dataCount());
framing::ProtocolInitiation protocolInit;
- size_t decoded = 0;
if (protocolInit.decode(in)) {
- decoded = in.getPosition();
QPID_LOG(debug, "Rdma: RECV [" << identifier << "] INIT(" << protocolInit << ")");
codec = factory->create(protocolInit.getVersion(), *this, identifier, SecuritySettings());
@@ -254,10 +250,9 @@ class RdmaIOProtocolFactory : public ProtocolFactory {
public:
RdmaIOProtocolFactory(int16_t port, int backlog);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const string& host, int16_t port, ConnectionCodec::Factory*, ConnectFailedCallback);
+ void connect(Poller::shared_ptr, const string& host, const std::string& port, ConnectionCodec::Factory*, ConnectFailedCallback);
uint16_t getPort() const;
- string getHost() const;
private:
bool request(Rdma::Connection::intrusive_ptr, const Rdma::ConnectionParams&, ConnectionCodec::Factory*);
@@ -347,18 +342,7 @@ uint16_t RdmaIOProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
-string RdmaIOProtocolFactory::getHost() const {
- //return listener.getSockname();
- return "";
-}
-
void RdmaIOProtocolFactory::accept(Poller::shared_ptr poller, ConnectionCodec::Factory* fact) {
- ::sockaddr_in sin;
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(listeningPort);
- sin.sin_addr.s_addr = INADDR_ANY;
-
listener.reset(
new Rdma::Listener(
Rdma::ConnectionParams(65536, Rdma::DEFAULT_WR_ENTRIES),
@@ -387,7 +371,7 @@ void RdmaIOProtocolFactory::connected(Poller::shared_ptr poller, Rdma::Connectio
void RdmaIOProtocolFactory::connect(
Poller::shared_ptr poller,
- const std::string& host, int16_t port,
+ const std::string& host, const std::string& port,
ConnectionCodec::Factory* f,
ConnectFailedCallback failed)
{
@@ -399,7 +383,7 @@ void RdmaIOProtocolFactory::connect(
boost::bind(&RdmaIOProtocolFactory::disconnected, this, _1),
boost::bind(&RdmaIOProtocolFactory::rejected, this, _1, _2, failed));
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
+ SocketAddress sa(host, port);
c->start(poller, sa);
}
diff --git a/qpid/cpp/src/qpid/sys/Socket.h b/qpid/cpp/src/qpid/sys/Socket.h
index b1cded1aa1..9f62f3be1c 100644
--- a/qpid/cpp/src/qpid/sys/Socket.h
+++ b/qpid/cpp/src/qpid/sys/Socket.h
@@ -39,15 +39,12 @@ public:
/** Create a socket wrapper for descriptor. */
QPID_COMMON_EXTERN Socket();
- /** Set timeout for read and write */
- void setTimeout(const Duration& interval) const;
-
/** Set socket non blocking */
void setNonblocking() const;
QPID_COMMON_EXTERN void setTcpNoDelay() const;
- QPID_COMMON_EXTERN void connect(const std::string& host, uint16_t port) const;
+ QPID_COMMON_EXTERN void connect(const std::string& host, const std::string& port) const;
QPID_COMMON_EXTERN void connect(const SocketAddress&) const;
QPID_COMMON_EXTERN void close() const;
@@ -57,19 +54,9 @@ public:
*@param backlog maximum number of pending connections.
*@return The bound port.
*/
- QPID_COMMON_EXTERN int listen(uint16_t port = 0, int backlog = 10) const;
+ QPID_COMMON_EXTERN int listen(const std::string& host = "", const std::string& port = "0", int backlog = 10) const;
QPID_COMMON_EXTERN int listen(const SocketAddress&, int backlog = 10) const;
- /** Returns the "socket name" ie the address bound to
- * the near end of the socket
- */
- QPID_COMMON_EXTERN std::string getSockname() const;
-
- /** Returns the "peer name" ie the address bound to
- * the remote end of the socket
- */
- std::string getPeername() const;
-
/**
* Returns an address (host and port) for the remote end of the
* socket
@@ -86,9 +73,6 @@ public:
*/
QPID_COMMON_INLINE_EXTERN std::string getFullAddress() const { return getLocalAddress()+"-"+getPeerAddress(); }
- QPID_COMMON_EXTERN uint16_t getLocalPort() const;
- uint16_t getRemotePort() const;
-
/**
* Returns the error code stored in the socket. This may be used
* to determine the result of a non-blocking connect.
@@ -109,7 +93,8 @@ private:
void createSocket(const SocketAddress&) const;
Socket(IOHandlePrivate*);
- mutable std::string connectname;
+ mutable std::string localname;
+ mutable std::string peername;
mutable bool nonblocking;
mutable bool nodelay;
};
diff --git a/qpid/cpp/src/qpid/sys/SocketAddress.h b/qpid/cpp/src/qpid/sys/SocketAddress.h
index 27b9642f2c..c2120338cf 100644
--- a/qpid/cpp/src/qpid/sys/SocketAddress.h
+++ b/qpid/cpp/src/qpid/sys/SocketAddress.h
@@ -41,7 +41,7 @@ public:
QPID_COMMON_EXTERN SocketAddress& operator=(const SocketAddress&);
QPID_COMMON_EXTERN ~SocketAddress();
- std::string asString() const;
+ std::string asString(bool numeric=true) const;
private:
std::string host;
diff --git a/qpid/cpp/src/qpid/sys/SslPlugin.cpp b/qpid/cpp/src/qpid/sys/SslPlugin.cpp
index 0ec051caab..471a0cef60 100644
--- a/qpid/cpp/src/qpid/sys/SslPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/SslPlugin.cpp
@@ -66,12 +66,11 @@ class SslProtocolFactory : public ProtocolFactory {
public:
SslProtocolFactory(const SslServerOptions&, int backlog, bool nodelay);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const std::string& host, int16_t port,
+ void connect(Poller::shared_ptr, const std::string& host, const std::string& port,
ConnectionCodec::Factory*,
boost::function2<void, int, std::string> failed);
uint16_t getPort() const;
- std::string getHost() const;
bool supports(const std::string& capability);
private:
@@ -146,10 +145,6 @@ uint16_t SslProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
-std::string SslProtocolFactory::getHost() const {
- return listener.getSockname();
-}
-
void SslProtocolFactory::accept(Poller::shared_ptr poller,
ConnectionCodec::Factory* fact) {
acceptor.reset(
@@ -160,7 +155,7 @@ void SslProtocolFactory::accept(Poller::shared_ptr poller,
void SslProtocolFactory::connect(
Poller::shared_ptr poller,
- const std::string& host, int16_t port,
+ const std::string& host, const std::string& port,
ConnectionCodec::Factory* fact,
ConnectFailedCallback failed)
{
diff --git a/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp b/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
index a6528f9ad9..34338ce434 100644
--- a/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
@@ -42,14 +42,13 @@ class AsynchIOProtocolFactory : public ProtocolFactory {
std::auto_ptr<AsynchAcceptor> acceptor;
public:
- AsynchIOProtocolFactory(int16_t port, int backlog, bool nodelay);
+ AsynchIOProtocolFactory(const std::string& host, const std::string& port, int backlog, bool nodelay);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const std::string& host, int16_t port,
+ void connect(Poller::shared_ptr, const std::string& host, const std::string& port,
ConnectionCodec::Factory*,
ConnectFailedCallback);
uint16_t getPort() const;
- std::string getHost() const;
private:
void established(Poller::shared_ptr, const Socket&, ConnectionCodec::Factory*,
@@ -61,22 +60,25 @@ class AsynchIOProtocolFactory : public ProtocolFactory {
static class TCPIOPlugin : public Plugin {
void earlyInitialize(Target&) {
}
-
+
void initialize(Target& target) {
broker::Broker* broker = dynamic_cast<broker::Broker*>(&target);
// Only provide to a Broker
if (broker) {
const broker::Broker::Options& opts = broker->getOptions();
- ProtocolFactory::shared_ptr protocol(new AsynchIOProtocolFactory(opts.port, opts.connectionBacklog,
- opts.tcpNoDelay));
- QPID_LOG(notice, "Listening on TCP port " << protocol->getPort());
- broker->registerProtocolFactory("tcp", protocol);
+ ProtocolFactory::shared_ptr protocolt(
+ new AsynchIOProtocolFactory(
+ "", boost::lexical_cast<std::string>(opts.port),
+ opts.connectionBacklog,
+ opts.tcpNoDelay));
+ QPID_LOG(notice, "Listening on TCP port " << protocolt->getPort());
+ broker->registerProtocolFactory("tcp", protocolt);
}
}
} tcpPlugin;
-AsynchIOProtocolFactory::AsynchIOProtocolFactory(int16_t port, int backlog, bool nodelay) :
- tcpNoDelay(nodelay), listeningPort(listener.listen(port, backlog))
+AsynchIOProtocolFactory::AsynchIOProtocolFactory(const std::string& host, const std::string& port, int backlog, bool nodelay) :
+ tcpNoDelay(nodelay), listeningPort(listener.listen(host, port, backlog))
{}
void AsynchIOProtocolFactory::established(Poller::shared_ptr poller, const Socket& s,
@@ -107,10 +109,6 @@ uint16_t AsynchIOProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
-std::string AsynchIOProtocolFactory::getHost() const {
- return listener.getSockname();
-}
-
void AsynchIOProtocolFactory::accept(Poller::shared_ptr poller,
ConnectionCodec::Factory* fact) {
acceptor.reset(
@@ -130,7 +128,7 @@ void AsynchIOProtocolFactory::connectFailed(
void AsynchIOProtocolFactory::connect(
Poller::shared_ptr poller,
- const std::string& host, int16_t port,
+ const std::string& host, const std::string& port,
ConnectionCodec::Factory* fact,
ConnectFailedCallback failed)
{
@@ -139,7 +137,6 @@ void AsynchIOProtocolFactory::connect(
// upon connection failure or by the AsynchIO upon connection
// shutdown. The allocated AsynchConnector frees itself when it
// is no longer needed.
-
Socket* socket = new Socket();
AsynchConnector* c = AsynchConnector::create(
*socket,
diff --git a/qpid/cpp/src/qpid/sys/Timer.cpp b/qpid/cpp/src/qpid/sys/Timer.cpp
index fdb2e8c6bb..47752e4584 100644
--- a/qpid/cpp/src/qpid/sys/Timer.cpp
+++ b/qpid/cpp/src/qpid/sys/Timer.cpp
@@ -75,6 +75,12 @@ void TimerTask::cancel() {
cancelled = true;
}
+void TimerTask::setFired() {
+ // Set nextFireTime to just before now, making readyToFire() true.
+ nextFireTime = AbsTime(sys::now(), Duration(-1));
+}
+
+
Timer::Timer() :
active(false),
late(50 * TIME_MSEC),
diff --git a/qpid/cpp/src/qpid/sys/Timer.h b/qpid/cpp/src/qpid/sys/Timer.h
index 98ba39ce38..fccb17dbc2 100644
--- a/qpid/cpp/src/qpid/sys/Timer.h
+++ b/qpid/cpp/src/qpid/sys/Timer.h
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -64,6 +64,10 @@ class TimerTask : public RefCounted {
std::string getName() const { return name; }
+ // Move the nextFireTime so readyToFire is true.
+ // Used by the cluster, where tasks are fired on cluster events, not on local time.
+ QPID_COMMON_EXTERN void setFired();
+
protected:
// Must be overridden with callback
virtual void fire() = 0;
diff --git a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
index 119a6aa8a4..b5a0b0bf32 100644
--- a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
@@ -152,8 +152,8 @@ private:
public:
AsynchConnector(const Socket& socket,
- std::string hostname,
- uint16_t port,
+ const std::string& hostname,
+ const std::string& port,
ConnectedCallback connCb,
FailedCallback failCb);
void start(Poller::shared_ptr poller);
@@ -161,8 +161,8 @@ public:
};
AsynchConnector::AsynchConnector(const Socket& s,
- std::string hostname,
- uint16_t port,
+ const std::string& hostname,
+ const std::string& port,
ConnectedCallback connCb,
FailedCallback failCb) :
DispatchHandle(s,
@@ -174,7 +174,7 @@ AsynchConnector::AsynchConnector(const Socket& s,
socket(s)
{
socket.setNonblocking();
- SocketAddress sa(hostname, boost::lexical_cast<std::string>(port));
+ SocketAddress sa(hostname, port);
// Note, not catching any exceptions here, also has effect of destructing
socket.connect(sa);
}
@@ -589,8 +589,8 @@ AsynchAcceptor* AsynchAcceptor::create(const Socket& s,
}
AsynchConnector* AsynchConnector::create(const Socket& s,
- std::string hostname,
- uint16_t port,
+ const std::string& hostname,
+ const std::string& port,
ConnectedCallback connCb,
FailedCallback failCb)
{
diff --git a/qpid/cpp/src/qpid/sys/posix/LockFile.cpp b/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
index 1862ff6ac9..f5a6c292cb 100755
--- a/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
@@ -58,8 +58,7 @@ LockFile::~LockFile() {
if (impl) {
int f = impl->fd;
if (f >= 0) {
- int unused_ret;
- unused_ret = ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
+ (void) ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
::close(f);
impl->fd = -1;
}
diff --git a/qpid/cpp/src/qpid/sys/posix/Socket.cpp b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
index 3449a753e3..aa25f8062d 100644
--- a/qpid/cpp/src/qpid/sys/posix/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
@@ -37,13 +37,12 @@
#include <iostream>
#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
namespace qpid {
namespace sys {
namespace {
-std::string getName(int fd, bool local, bool includeService = false)
+std::string getName(int fd, bool local)
{
::sockaddr_storage name; // big enough for any socket address
::socklen_t namelen = sizeof(name);
@@ -54,45 +53,15 @@ std::string getName(int fd, bool local, bool includeService = false)
} else {
result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
}
-
QPID_POSIX_CHECK(result);
char servName[NI_MAXSERV];
char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return std::string(dispName) + ":" + std::string(servName);
-
- } else {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName), 0, 0, NI_NUMERICHOST) != 0)
- throw QPID_POSIX_ERROR(rc);
- return dispName;
- }
-}
-
-std::string getService(int fd, bool local)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, 0, 0,
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
+ servName, sizeof(servName),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0)
throw QPID_POSIX_ERROR(rc);
- return servName;
+ return std::string(dispName) + ":" + std::string(servName);
}
}
@@ -126,15 +95,6 @@ void Socket::createSocket(const SocketAddress& sa) const
}
}
-void Socket::setTimeout(const Duration& interval) const
-{
- const int& socket = impl->fd;
- struct timeval tv;
- toTimeval(tv, interval);
- setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-}
-
void Socket::setNonblocking() const {
int& socket = impl->fd;
nonblocking = true;
@@ -154,15 +114,22 @@ void Socket::setTcpNoDelay() const
}
}
-void Socket::connect(const std::string& host, uint16_t port) const
+void Socket::connect(const std::string& host, const std::string& port) const
{
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
+ SocketAddress sa(host, port);
connect(sa);
}
void Socket::connect(const SocketAddress& addr) const
{
- connectname = addr.asString();
+ // The display name for an outbound connection needs to be the name that was specified
+ // for the address rather than a resolved IP address as we don't know which of
+ // the IP addresses is actually the one that will be connected to.
+ peername = addr.asString(false);
+
+ // However the string we compare with the local port must be numeric or it might not
+ // match when it should as getLocalAddress() will always be numeric
+ std::string connectname = addr.asString();
createSocket(addr);
@@ -170,7 +137,7 @@ void Socket::connect(const SocketAddress& addr) const
// TODO the correct thing to do here is loop on failure until you've used all the returned addresses
if ((::connect(socket, getAddrInfo(addr).ai_addr, getAddrInfo(addr).ai_addrlen) < 0) &&
(errno != EINPROGRESS)) {
- throw Exception(QPID_MSG(strError(errno) << ": " << connectname));
+ throw Exception(QPID_MSG(strError(errno) << ": " << peername));
}
// When connecting to a port on the same host which no longer has
// a process associated with it, the OS occasionally chooses the
@@ -185,9 +152,9 @@ void Socket::connect(const SocketAddress& addr) const
// Raise an error if we see such a connection, since we know there is
// no listener on the peer address.
//
- if (getLocalAddress() == getPeerAddress()) {
+ if (getLocalAddress() == connectname) {
close();
- throw Exception(QPID_MSG("Connection refused: " << connectname));
+ throw Exception(QPID_MSG("Connection refused: " << peername));
}
}
@@ -200,9 +167,9 @@ Socket::close() const
socket = -1;
}
-int Socket::listen(uint16_t port, int backlog) const
+int Socket::listen(const std::string& host, const std::string& port, int backlog) const
{
- SocketAddress sa("", boost::lexical_cast<std::string>(port));
+ SocketAddress sa(host, port);
return listen(sa, backlog);
}
@@ -230,8 +197,11 @@ int Socket::listen(const SocketAddress& sa, int backlog) const
Socket* Socket::accept() const
{
int afd = ::accept(impl->fd, 0, 0);
- if ( afd >= 0)
- return new Socket(new IOHandlePrivate(afd));
+ if ( afd >= 0) {
+ Socket* s = new Socket(new IOHandlePrivate(afd));
+ s->localname = localname;
+ return s;
+ }
else if (errno == EAGAIN)
return 0;
else throw QPID_POSIX_ERROR(errno);
@@ -247,37 +217,20 @@ int Socket::write(const void *buf, size_t count) const
return ::write(impl->fd, buf, count);
}
-std::string Socket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string Socket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
std::string Socket::getPeerAddress() const
{
- if (connectname.empty()) {
- connectname = getName(impl->fd, false, true);
+ if (peername.empty()) {
+ peername = getName(impl->fd, false);
}
- return connectname;
+ return peername;
}
std::string Socket::getLocalAddress() const
{
- return getName(impl->fd, true, true);
-}
-
-uint16_t Socket::getLocalPort() const
-{
- return std::atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t Socket::getRemotePort() const
-{
- return std::atoi(getService(impl->fd, true).c_str());
+ if (localname.empty()) {
+ localname = getName(impl->fd, true);
+ }
+ return localname;
}
int Socket::getError() const
diff --git a/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp b/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp
index 8f5f29d793..10f1c8a563 100644
--- a/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp
@@ -27,6 +27,8 @@
#include <string.h>
#include <netdb.h>
+#include <algorithm>
+
namespace qpid {
namespace sys {
@@ -46,15 +48,9 @@ SocketAddress::SocketAddress(const SocketAddress& sa) :
SocketAddress& SocketAddress::operator=(const SocketAddress& sa)
{
- if (&sa != this) {
- host = sa.host;
- port = sa.port;
+ SocketAddress temp(sa);
- if (addrInfo) {
- ::freeaddrinfo(addrInfo);
- addrInfo = 0;
- }
- }
+ std::swap(temp, *this);
return *this;
}
@@ -65,9 +61,23 @@ SocketAddress::~SocketAddress()
}
}
-std::string SocketAddress::asString() const
+std::string SocketAddress::asString(bool numeric) const
{
- return host + ":" + port;
+ if (!numeric)
+ return host + ":" + port;
+ // Canonicalise into numeric id
+ const ::addrinfo& ai = getAddrInfo(*this);
+ char servName[NI_MAXSERV];
+ char dispName[NI_MAXHOST];
+ if (int rc=::getnameinfo(ai.ai_addr, ai.ai_addrlen,
+ dispName, sizeof(dispName),
+ servName, sizeof(servName),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ throw QPID_POSIX_ERROR(rc);
+ std::string s(dispName);
+ s += ":";
+ s += servName;
+ return s;
}
const ::addrinfo& getAddrInfo(const SocketAddress& sa)
@@ -88,7 +98,7 @@ const ::addrinfo& getAddrInfo(const SocketAddress& sa)
int n = ::getaddrinfo(node, service, &hints, &sa.addrInfo);
if (n != 0)
- throw Exception(QPID_MSG("Cannot resolve " << sa.host << ": " << ::gai_strerror(n)));
+ throw Exception(QPID_MSG("Cannot resolve " << sa.asString(false) << ": " << ::gai_strerror(n)));
}
return *sa.addrInfo;
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
index a58a137473..734ebb483a 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
@@ -117,7 +117,7 @@ void SslAcceptor::readable(DispatchHandle& h) {
SslConnector::SslConnector(const SslSocket& s,
Poller::shared_ptr poller,
std::string hostname,
- uint16_t port,
+ std::string port,
ConnectedCallback connCb,
FailedCallback failCb) :
DispatchHandle(s,
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.h b/qpid/cpp/src/qpid/sys/ssl/SslIo.h
index 53ac69d8d6..8785852c24 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslIo.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.h
@@ -73,7 +73,7 @@ public:
SslConnector(const SslSocket& socket,
Poller::shared_ptr poller,
std::string hostname,
- uint16_t port,
+ std::string port,
ConnectedCallback connCb,
FailedCallback failCb = 0);
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
index 01e2658877..f7483a220c 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
@@ -158,7 +158,7 @@ void SslSocket::setNonblocking() const
PR_SetSocketOption(socket, &option);
}
-void SslSocket::connect(const std::string& host, uint16_t port) const
+void SslSocket::connect(const std::string& host, const std::string& port) const
{
std::stringstream namestream;
namestream << host << ":" << port;
@@ -180,7 +180,7 @@ void SslSocket::connect(const std::string& host, uint16_t port) const
PRHostEnt hostEntry;
PR_CHECK(PR_GetHostByName(host.data(), hostBuffer, PR_NETDB_BUF_SIZE, &hostEntry));
PRNetAddr address;
- int value = PR_EnumerateHostEnt(0, &hostEntry, port, &address);
+ int value = PR_EnumerateHostEnt(0, &hostEntry, boost::lexical_cast<PRUint16>(port), &address);
if (value < 0) {
throw Exception(QPID_MSG("Error getting address for host: " << ErrorString()));
} else if (value == 0) {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
index 25712c98d5..993859495b 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
@@ -53,7 +53,7 @@ public:
* NSSInit().*/
void setCertName(const std::string& certName);
- void connect(const std::string& host, uint16_t port) const;
+ void connect(const std::string& host, const std::string& port) const;
void close() const;
diff --git a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
index 71138757a5..8d84fdb7b2 100644
--- a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
@@ -175,20 +175,20 @@ private:
FailedCallback failCallback;
const Socket& socket;
const std::string hostname;
- const uint16_t port;
+ const std::string port;
public:
AsynchConnector(const Socket& socket,
- std::string hostname,
- uint16_t port,
+ const std::string& hostname,
+ const std::string& port,
ConnectedCallback connCb,
FailedCallback failCb = 0);
void start(Poller::shared_ptr poller);
};
AsynchConnector::AsynchConnector(const Socket& sock,
- std::string hname,
- uint16_t p,
+ const std::string& hname,
+ const std::string& p,
ConnectedCallback connCb,
FailedCallback failCb) :
connCallback(connCb), failCallback(failCb), socket(sock),
@@ -218,8 +218,8 @@ AsynchAcceptor* AsynchAcceptor::create(const Socket& s,
}
AsynchConnector* qpid::sys::AsynchConnector::create(const Socket& s,
- std::string hostname,
- uint16_t port,
+ const std::string& hostname,
+ const std::string& port,
ConnectedCallback connCb,
FailedCallback failCb)
{
diff --git a/qpid/cpp/src/qpid/sys/windows/Socket.cpp b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
index 2ce274acc9..baa80f04e0 100755
--- a/qpid/cpp/src/qpid/sys/windows/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
@@ -89,7 +89,7 @@ namespace sys {
namespace {
-std::string getName(SOCKET fd, bool local, bool includeService = false)
+std::string getName(SOCKET fd, bool local)
{
sockaddr_in name; // big enough for any socket address
socklen_t namelen = sizeof(name);
@@ -101,41 +101,12 @@ std::string getName(SOCKET fd, bool local, bool includeService = false)
char servName[NI_MAXSERV];
char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return std::string(dispName) + ":" + std::string(servName);
- } else {
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
- 0, 0,
- NI_NUMERICHOST) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return dispName;
- }
-}
-
-std::string getService(SOCKET fd, bool local)
-{
- sockaddr_in name; // big enough for any socket address
- socklen_t namelen = sizeof(name);
-
- if (local) {
- QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen));
- } else {
- QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen));
- }
-
- char servName[NI_MAXSERV];
if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- 0, 0,
+ dispName, sizeof(dispName),
servName, sizeof(servName),
NI_NUMERICHOST | NI_NUMERICSERV) != 0)
throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return servName;
+ return std::string(dispName) + ":" + std::string(servName);
}
} // namespace
@@ -179,34 +150,22 @@ Socket::createSocket(const SocketAddress& sa) const
}
}
-void Socket::setTimeout(const Duration& interval) const
-{
- const SOCKET& socket = impl->fd;
- int64_t nanosecs = interval;
- nanosecs /= (1000 * 1000); // nsecs -> usec -> msec
- int msec = 0;
- if (nanosecs > std::numeric_limits<int>::max())
- msec = std::numeric_limits<int>::max();
- else
- msec = static_cast<int>(nanosecs);
- setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&msec, sizeof(msec));
- setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&msec, sizeof(msec));
-}
-
void Socket::setNonblocking() const {
u_long nonblock = 1;
QPID_WINSOCK_CHECK(ioctlsocket(impl->fd, FIONBIO, &nonblock));
}
-void Socket::connect(const std::string& host, uint16_t port) const
+void Socket::connect(const std::string& host, const std::string& port) const
{
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
+ SocketAddress sa(host, port);
connect(sa);
}
void
Socket::connect(const SocketAddress& addr) const
{
+ peername = addr.asString(false);
+
const SOCKET& socket = impl->fd;
const addrinfo *addrs = &(getAddrInfo(addr));
int error = 0;
@@ -221,7 +180,7 @@ Socket::connect(const SocketAddress& addr) const
addrs = addrs->ai_next;
}
if (error)
- throw qpid::Exception(QPID_MSG(strError(error) << ": " << connectname));
+ throw qpid::Exception(QPID_MSG(strError(error) << ": " << peername));
}
void
@@ -252,7 +211,7 @@ int Socket::read(void *buf, size_t count) const
return received;
}
-int Socket::listen(uint16_t port, int backlog) const
+int Socket::listen(const std::string&, const std::string& port, int backlog) const
{
const SOCKET& socket = impl->fd;
BOOL yes=1;
@@ -260,7 +219,7 @@ int Socket::listen(uint16_t port, int backlog) const
struct sockaddr_in name;
memset(&name, 0, sizeof(name));
name.sin_family = AF_INET;
- name.sin_port = htons(port);
+ name.sin_port = htons(boost::lexical_cast<uint16_t>(port));
name.sin_addr.s_addr = 0;
if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) == SOCKET_ERROR)
throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(WSAGetLastError())));
@@ -282,36 +241,18 @@ Socket* Socket::accept() const
else throw QPID_WINDOWS_ERROR(WSAGetLastError());
}
-std::string Socket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string Socket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
std::string Socket::getPeerAddress() const
{
- if (!connectname.empty())
- return std::string (connectname);
- return getName(impl->fd, false, true);
+ if (peername.empty())
+ peername = getName(impl->fd, false);
+ return peername;
}
std::string Socket::getLocalAddress() const
{
- return getName(impl->fd, true, true);
-}
-
-uint16_t Socket::getLocalPort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t Socket::getRemotePort() const
-{
- return atoi(getService(impl->fd, true).c_str());
+ if (localname.empty())
+ localname = getName(impl->fd, true);
+ return localname;
}
int Socket::getError() const
diff --git a/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp b/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp
index 5efdad0183..ac43cd2d23 100644
--- a/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp
@@ -63,7 +63,7 @@ SocketAddress::~SocketAddress()
::freeaddrinfo(addrInfo);
}
-std::string SocketAddress::asString() const
+std::string SocketAddress::asString(bool) const
{
return host + ":" + port;
}
diff --git a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
index d0c6668b72..1d5289dc90 100644
--- a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
+++ b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
@@ -599,13 +599,12 @@ namespace qpid {
// populate the agent with multiple test objects
const size_t objCount = 50;
std::vector<TestManageable *> tmv;
- uint32_t objLen;
for (size_t i = 0; i < objCount; i++) {
std::stringstream key;
key << "testobj-" << i;
TestManageable *tm = new TestManageable(agent, key.str());
- objLen = tm->GetManagementObject()->writePropertiesSize();
+ (void) tm->GetManagementObject()->writePropertiesSize();
agent->addObject(tm->GetManagementObject(), key.str());
tmv.push_back(tm);
}
diff --git a/qpid/cpp/src/tests/ClientSessionTest.cpp b/qpid/cpp/src/tests/ClientSessionTest.cpp
index 939f8f2b88..3c0cff7350 100644
--- a/qpid/cpp/src/tests/ClientSessionTest.cpp
+++ b/qpid/cpp/src/tests/ClientSessionTest.cpp
@@ -271,8 +271,12 @@ QPID_AUTO_TEST_CASE(testOpenFailure) {
QPID_AUTO_TEST_CASE(testPeriodicExpiration) {
Broker::Options opts;
opts.queueCleanInterval = 1;
+ opts.queueFlowStopRatio = 0;
+ opts.queueFlowResumeRatio = 0;
ClientSessionFixture fix(opts);
- fix.session.queueDeclare(arg::queue="my-queue", arg::exclusive=true, arg::autoDelete=true);
+ FieldTable args;
+ args.setInt("qpid.max_count",10);
+ fix.session.queueDeclare(arg::queue="my-queue", arg::exclusive=true, arg::autoDelete=true, arg::arguments=args);
for (uint i = 0; i < 10; i++) {
Message m((boost::format("Message_%1%") % (i+1)).str(), "my-queue");
@@ -283,6 +287,7 @@ QPID_AUTO_TEST_CASE(testPeriodicExpiration) {
BOOST_CHECK_EQUAL(fix.session.queueQuery(string("my-queue")).getMessageCount(), 10u);
qpid::sys::sleep(2);
BOOST_CHECK_EQUAL(fix.session.queueQuery(string("my-queue")).getMessageCount(), 5u);
+ fix.session.messageTransfer(arg::content=Message("Message_11", "my-queue"));//ensure policy is also updated
}
QPID_AUTO_TEST_CASE(testExpirationOnPop) {
diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp
index 53eaa7e1ce..10674b5175 100644
--- a/qpid/cpp/src/tests/ForkedBroker.cpp
+++ b/qpid/cpp/src/tests/ForkedBroker.cpp
@@ -68,8 +68,7 @@ ForkedBroker::~ForkedBroker() {
}
if (!dataDir.empty())
{
- int unused_ret; // Suppress warnings about ignoring return value.
- unused_ret = ::system(("rm -rf "+dataDir).c_str());
+ (void) ::system(("rm -rf "+dataDir).c_str());
}
}
diff --git a/qpid/cpp/src/tests/MessagingSessionTests.cpp b/qpid/cpp/src/tests/MessagingSessionTests.cpp
index 6aa4c63ed7..fae45a94d0 100644
--- a/qpid/cpp/src/tests/MessagingSessionTests.cpp
+++ b/qpid/cpp/src/tests/MessagingSessionTests.cpp
@@ -992,6 +992,78 @@ QPID_AUTO_TEST_CASE(testTtlForever)
BOOST_CHECK(in.getTtl() == Duration::FOREVER);
}
+QPID_AUTO_TEST_CASE(testExclusiveTopicSubscriber)
+{
+ TopicFixture fix;
+ std::string address = (boost::format("%1%; { link: { name: 'my-subscription', x-declare: { auto-delete: true, exclusive: true }}}") % fix.topic).str();
+ Sender sender = fix.session.createSender(fix.topic);
+ Receiver receiver1 = fix.session.createReceiver(address);
+ {
+ ScopedSuppressLogging sl;
+ try {
+ fix.session.createReceiver(address);
+ fix.session.sync();
+ BOOST_FAIL("Expected exception.");
+ } catch (const MessagingException& /*e*/) {}
+ }
+}
+
+QPID_AUTO_TEST_CASE(testNonExclusiveSubscriber)
+{
+ TopicFixture fix;
+ std::string address = (boost::format("%1%; {node:{type:topic}, link:{name:'my-subscription', x-declare:{auto-delete:true, exclusive:false}}}") % fix.topic).str();
+ Receiver receiver1 = fix.session.createReceiver(address);
+ Receiver receiver2 = fix.session.createReceiver(address);
+ Sender sender = fix.session.createSender(fix.topic);
+ sender.send(Message("one"), true);
+ Message in = receiver1.fetch(Duration::IMMEDIATE);
+ BOOST_CHECK_EQUAL(in.getContent(), std::string("one"));
+ sender.send(Message("two"), true);
+ in = receiver2.fetch(Duration::IMMEDIATE);
+ BOOST_CHECK_EQUAL(in.getContent(), std::string("two"));
+ fix.session.acknowledge();
+}
+
+QPID_AUTO_TEST_CASE(testAcknowledgeUpTo)
+{
+ QueueFixture fix;
+ Sender sender = fix.session.createSender(fix.queue);
+ const uint count(20);
+ for (uint i = 0; i < count; ++i) {
+ sender.send(Message((boost::format("Message_%1%") % (i+1)).str()));
+ }
+
+ Session other = fix.connection.createSession();
+ Receiver receiver = other.createReceiver(fix.queue);
+ std::vector<Message> messages;
+ for (uint i = 0; i < count; ++i) {
+ Message msg = receiver.fetch();
+ BOOST_CHECK_EQUAL(msg.getContent(), (boost::format("Message_%1%") % (i+1)).str());
+ messages.push_back(msg);
+ }
+ const uint batch = 10;
+ other.acknowledgeUpTo(messages[batch-1]);//acknowledge first 10 messages only
+
+ messages.clear();
+ other.sync();
+ other.close();
+
+ other = fix.connection.createSession();
+ receiver = other.createReceiver(fix.queue);
+ Message msg;
+ for (uint i = 0; i < (count-batch); ++i) {
+ msg = receiver.fetch();
+ BOOST_CHECK_EQUAL(msg.getContent(), (boost::format("Message_%1%") % (i+1+batch)).str());
+ }
+ other.acknowledgeUpTo(msg);
+ other.sync();
+ other.close();
+
+ Message m;
+ //check queue is empty
+ BOOST_CHECK(!fix.session.createReceiver(fix.queue).fetch(m, Duration::IMMEDIATE));
+}
+
QPID_AUTO_TEST_SUITE_END()
}} // namespace qpid::tests
diff --git a/qpid/cpp/src/tests/QueueTest.cpp b/qpid/cpp/src/tests/QueueTest.cpp
index a752e3afec..6372aa93c3 100644
--- a/qpid/cpp/src/tests/QueueTest.cpp
+++ b/qpid/cpp/src/tests/QueueTest.cpp
@@ -681,7 +681,7 @@ QPID_AUTO_TEST_CASE(testPurgeExpired) {
addMessagesToQueue(10, queue);
BOOST_CHECK_EQUAL(queue.getMessageCount(), 10u);
::usleep(300*1000);
- queue.purgeExpired();
+ queue.purgeExpired(0);
BOOST_CHECK_EQUAL(queue.getMessageCount(), 5u);
}
@@ -692,7 +692,7 @@ QPID_AUTO_TEST_CASE(testQueueCleaner) {
addMessagesToQueue(10, *queue, 200, 400);
BOOST_CHECK_EQUAL(queue->getMessageCount(), 10u);
- QueueCleaner cleaner(queues, timer);
+ QueueCleaner cleaner(queues, &timer);
cleaner.start(100 * qpid::sys::TIME_MSEC);
::usleep(300*1000);
BOOST_CHECK_EQUAL(queue->getMessageCount(), 5u);
diff --git a/qpid/cpp/src/tests/SocketProxy.h b/qpid/cpp/src/tests/SocketProxy.h
index 0c6f39d62e..d195f11aa9 100644
--- a/qpid/cpp/src/tests/SocketProxy.h
+++ b/qpid/cpp/src/tests/SocketProxy.h
@@ -35,6 +35,8 @@
#include "qpid/sys/Mutex.h"
#include "qpid/log/Statement.h"
+#include <boost/lexical_cast.hpp>
+
namespace qpid {
namespace tests {
@@ -62,7 +64,7 @@ class SocketProxy : private qpid::sys::Runnable
: closed(false), joined(true),
port(listener.listen()), dropClient(), dropServer()
{
- client.connect(host, connectPort);
+ client.connect(host, boost::lexical_cast<std::string>(connectPort));
joined = false;
thread = qpid::sys::Thread(static_cast<qpid::sys::Runnable*>(this));
}
diff --git a/qpid/cpp/src/tests/brokertest.py b/qpid/cpp/src/tests/brokertest.py
index a19dd305e5..0415a667a2 100644
--- a/qpid/cpp/src/tests/brokertest.py
+++ b/qpid/cpp/src/tests/brokertest.py
@@ -157,8 +157,13 @@ class Popen(subprocess.Popen):
try: self.kill() # Just make sure its dead
except: pass
elif self.expect == EXPECT_RUNNING:
- try: self.kill()
- except: self.unexpected("expected running, exit code %d" % self.wait())
+ if self.poll() != None:
+ self.unexpected("expected running, exit code %d" % self.returncode)
+ else:
+ try:
+ self.kill()
+ except Exception,e:
+ self.unexpected("exception from kill: %s" % str(e))
else:
retry(lambda: self.poll() is not None)
if self.returncode is None: # Still haven't stopped
@@ -544,6 +549,7 @@ class NumberedSender(Thread):
"--broker", "localhost:%s"%broker.port(),
"--address", "%s;{create:always}"%queue,
"--failover-updates",
+ "--connection-options", "{reconnect:true}",
"--content-stdin"
],
expect=EXPECT_RUNNING,
@@ -562,6 +568,7 @@ class NumberedSender(Thread):
try:
self.sent = 0
while not self.stopped:
+ self.sender.assert_running()
if self.max:
self.condition.acquire()
while not self.stopped and self.sent - self.received > self.max:
@@ -604,6 +611,7 @@ class NumberedReceiver(Thread):
"--broker", "localhost:%s"%broker.port(),
"--address", "%s;{create:always}"%queue,
"--failover-updates",
+ "--connection-options", "{reconnect:true}",
"--forever"
],
expect=EXPECT_RUNNING,
@@ -611,15 +619,16 @@ class NumberedReceiver(Thread):
self.lock = Lock()
self.error = None
self.sender = sender
+ self.received = 0
def read_message(self):
return int(self.receiver.stdout.readline())
def run(self):
try:
- self.received = 0
m = self.read_message()
while m != -1:
+ self.receiver.assert_running()
assert(m <= self.received) # Check for missing messages
if (m == self.received): # Ignore duplicates
self.received += 1
diff --git a/qpid/cpp/src/tests/cluster_test_logs.py b/qpid/cpp/src/tests/cluster_test_logs.py
index 9f7d1e2f6c..a0ce8fb9c3 100755
--- a/qpid/cpp/src/tests/cluster_test_logs.py
+++ b/qpid/cpp/src/tests/cluster_test_logs.py
@@ -54,7 +54,7 @@ def filter_log(log):
'caught up',
'active for links|Passivating links|Activating links',
'info Connection.* connected to', # UpdateClient connection
- 'warning Connection [\d+ [0-9.:]+] closed', # UpdateClient connection
+ 'warning Connection \\[[-0-9.: ]+\\] closed', # UpdateClient connection
'warning Broker closed connection: 200, OK',
'task late',
'task overran',
diff --git a/qpid/cpp/src/tests/cluster_tests.py b/qpid/cpp/src/tests/cluster_tests.py
index caa41fa001..c1d9103f08 100755
--- a/qpid/cpp/src/tests/cluster_tests.py
+++ b/qpid/cpp/src/tests/cluster_tests.py
@@ -18,11 +18,12 @@
# under the License.
#
-import os, signal, sys, time, imp, re, subprocess, glob, cluster_test_logs
+import os, signal, sys, time, imp, re, subprocess, glob, random, logging
+import cluster_test_logs
from qpid import datatypes, messaging
from brokertest import *
from qpid.harness import Skipped
-from qpid.messaging import Message, Empty, Disposition, REJECTED
+from qpid.messaging import Message, Empty, Disposition, REJECTED, util
from threading import Thread, Lock, Condition
from logging import getLogger
from itertools import chain
@@ -96,9 +97,15 @@ class ShortTests(BrokerTest):
destination="amq.direct",
message=qpid.datatypes.Message(props, "content"))
+ # Try message with TTL and differnet headers/properties
+ cluster[0].send_message("q", Message(durable=True, ttl=100000))
+ cluster[0].send_message("q", Message(durable=True, properties={}, ttl=100000))
+ cluster[0].send_message("q", Message(durable=True, properties={"x":10}, ttl=100000))
+
# Now update a new member and compare their dumps.
cluster.start(args=["--test-store-dump", "updatee.dump"])
assert readfile("direct.dump") == readfile("updatee.dump")
+
os.remove("direct.dump")
os.remove("updatee.dump")
@@ -253,6 +260,7 @@ acl allow all all
client was attached.
"""
args=["--mgmt-pub-interval=1","--log-enable=trace+:management"]
+ # First broker will be killed.
cluster0 = self.cluster(1, args=args)
cluster1 = self.cluster(1, args=args)
assert 0 == subprocess.call(
@@ -287,6 +295,7 @@ acl allow all all
# Force a change of elder
cluster0.start()
+ cluster0[0].expect=EXPECT_EXIT_FAIL # About to die.
cluster0[0].kill()
time.sleep(2) # Allow a management interval to pass.
# Verify logs are consistent
@@ -525,7 +534,7 @@ acl allow all all
receiver.wait()
q_obj.update()
assert not q_obj.flowStopped
- assert q_obj.msgDepth == 0
+ self.assertEqual(q_obj.msgDepth, 0)
# verify that the sender has become unblocked
sender.join(timeout=5)
@@ -685,6 +694,25 @@ acl allow all all
self.assert_browse(s1, "q", ["foo"])
+ def test_ttl_consistent(self):
+ """Ensure we don't get inconsistent errors with message that have TTL very close together"""
+ messages = [ Message(str(i), ttl=i/1000.0) for i in xrange(0,1000)]
+ messages.append(Message("x"))
+ cluster = self.cluster(2)
+ sender = cluster[0].connect().session().sender("q;{create:always}")
+
+ def fetch(b):
+ receiver = b.connect().session().receiver("q;{create:always}")
+ while receiver.fetch().content != "x": pass
+
+ for m in messages: sender.send(m, sync=False)
+ for m in messages: sender.send(m, sync=False)
+ fetch(cluster[0])
+ fetch(cluster[1])
+ for m in messages: sender.send(m, sync=False)
+ cluster.start()
+ fetch(cluster[2])
+
class LongTests(BrokerTest):
"""Tests that can run for a long time if -DDURATION=<minutes> is set"""
def duration(self):
@@ -697,22 +725,28 @@ class LongTests(BrokerTest):
# Original cluster will all be killed so expect exit with failure
cluster = self.cluster(3, expect=EXPECT_EXIT_FAIL)
+ for b in cluster: b.ready() # Wait for brokers to be ready
for b in cluster: ErrorGenerator(b)
# Start sender and receiver threads
cluster[0].declare_queue("test-queue")
- sender = NumberedSender(cluster[1], 1000) # Max queue depth
- receiver = NumberedReceiver(cluster[2], sender)
+ sender = NumberedSender(cluster[0], 1000) # Max queue depth
+ receiver = NumberedReceiver(cluster[0], sender)
receiver.start()
sender.start()
+ # Wait for sender & receiver to get up and running
+ retry(lambda: receiver.received > 0)
# Kill original brokers, start new ones for the duration.
endtime = time.time() + self.duration()
i = 0
while time.time() < endtime:
+ sender.sender.assert_running()
+ receiver.receiver.assert_running()
cluster[i].kill()
i += 1
b = cluster.start(expect=EXPECT_EXIT_FAIL)
+ for b in cluster[i:]: b.ready()
ErrorGenerator(b)
time.sleep(5)
sender.stop()
@@ -782,7 +816,7 @@ class LongTests(BrokerTest):
args += ["--log-enable=trace+:management"]
# Use store if present.
if BrokerTest.store_lib: args +=["--load-module", BrokerTest.store_lib]
- cluster = self.cluster(3, args)
+ cluster = self.cluster(3, args, expect=EXPECT_EXIT_FAIL) # brokers will be killed
clients = [] # Per-broker list of clients that only connect to one broker.
mclients = [] # Management clients that connect to every broker in the cluster.
@@ -806,7 +840,7 @@ class LongTests(BrokerTest):
endtime = time.time() + self.duration()
# For long duration, first run is a quarter of the duration.
- runtime = max(5, self.duration() / 4.0)
+ runtime = min(5.0, self.duration() / 3.0)
alive = 0 # First live cluster member
for i in range(len(cluster)): start_clients(cluster[i])
start_mclients(cluster[alive])
@@ -817,7 +851,7 @@ class LongTests(BrokerTest):
for b in cluster[alive:]: b.ready() # Check if a broker crashed.
# Kill the first broker, expect the clients to fail.
b = cluster[alive]
- b.expect = EXPECT_EXIT_FAIL
+ b.ready()
b.kill()
# Stop the brokers clients and all the mclients.
for c in clients[alive] + mclients:
@@ -827,11 +861,15 @@ class LongTests(BrokerTest):
mclients = []
# Start another broker and clients
alive += 1
- cluster.start()
+ cluster.start(expect=EXPECT_EXIT_FAIL)
+ cluster[-1].ready() # Wait till its ready
start_clients(cluster[-1])
start_mclients(cluster[alive])
for c in chain(mclients, *clients):
c.stop()
+ for b in cluster[alive:]:
+ b.ready() # Verify still alive
+ b.kill()
# Verify that logs are consistent
cluster_test_logs.verify_logs()
@@ -844,7 +882,7 @@ class LongTests(BrokerTest):
end = time.time() + self.duration()
while (time.time() < end): # Get a management interval
for i in xrange(1000): cluster[0].connect().close()
- cluster_test_logs.verify_logs()
+ cluster_test_logs.verify_logs()
def test_flowlimit_failover(self):
"""Test fail-over during continuous send-receive with flow control
@@ -853,34 +891,149 @@ class LongTests(BrokerTest):
# Original cluster will all be killed so expect exit with failure
cluster = self.cluster(3, expect=EXPECT_EXIT_FAIL)
- #for b in cluster: ErrorGenerator(b)
+ for b in cluster: b.ready() # Wait for brokers to be ready
# create a queue with rather draconian flow control settings
ssn0 = cluster[0].connect().session()
s0 = ssn0.sender("test-queue; {create:always, node:{type:queue, x-declare:{arguments:{'qpid.flow_stop_count':2000, 'qpid.flow_resume_count':100}}}}")
- receiver = NumberedReceiver(cluster[2])
+ receiver = NumberedReceiver(cluster[0])
receiver.start()
- senders = [NumberedSender(cluster[i]) for i in range(1,3)]
+ senders = [NumberedSender(cluster[0]) for i in range(1,3)]
for s in senders:
s.start()
+ # Wait for senders & receiver to get up and running
+ retry(lambda: receiver.received > 2*senders)
# Kill original brokers, start new ones for the duration.
endtime = time.time() + self.duration();
i = 0
while time.time() < endtime:
+ for s in senders: s.sender.assert_running()
+ receiver.receiver.assert_running()
+ for b in cluster[i:]: b.ready() # Check if any broker crashed.
cluster[i].kill()
i += 1
b = cluster.start(expect=EXPECT_EXIT_FAIL)
- #ErrorGenerator(b)
time.sleep(5)
- #b = cluster[0]
- #b.startQmf()
for s in senders:
s.stop()
receiver.stop()
for i in range(i, len(cluster)): cluster[i].kill()
+ def test_ttl_failover(self):
+ """Test that messages with TTL don't cause problems in a cluster with failover"""
+
+ class Client(StoppableThread):
+
+ def __init__(self, broker):
+ StoppableThread.__init__(self)
+ self.connection = broker.connect(reconnect=True)
+ self.auto_fetch_reconnect_urls(self.connection)
+ self.session = self.connection.session()
+
+ def auto_fetch_reconnect_urls(self, conn):
+ """Replacment for qpid.messaging.util version which is noisy"""
+ ssn = conn.session("auto-fetch-reconnect-urls")
+ rcv = ssn.receiver("amq.failover")
+ rcv.capacity = 10
+
+ def main():
+ while True:
+ try:
+ msg = rcv.fetch()
+ qpid.messaging.util.set_reconnect_urls(conn, msg)
+ ssn.acknowledge(msg, sync=False)
+ except messaging.exceptions.LinkClosed: return
+ except messaging.exceptions.ConnectionError: return
+
+ thread = Thread(name="auto-fetch-reconnect-urls", target=main)
+ thread.setDaemon(True)
+ thread.start()
+
+ def stop(self):
+ StoppableThread.stop(self)
+ self.connection.detach()
+
+ class Sender(Client):
+ def __init__(self, broker, address):
+ Client.__init__(self, broker)
+ self.sent = 0 # Number of messages _reliably_ sent.
+ self.sender = self.session.sender(address, capacity=1000)
+
+ def send_counted(self, ttl):
+ self.sender.send(Message(str(self.sent), ttl=ttl))
+ self.sent += 1
+
+ def run(self):
+ while not self.stopped:
+ choice = random.randint(0,4)
+ if choice == 0: self.send_counted(None) # No ttl
+ elif choice == 1: self.send_counted(100000) # Large ttl
+ else: # Small ttl, might expire
+ self.sender.send(Message("", ttl=random.random()/10))
+ self.sender.send(Message("z"), sync=True) # Chaser.
+
+ class Receiver(Client):
+
+ def __init__(self, broker, address):
+ Client.__init__(self, broker)
+ self.received = 0 # Number of non-empty (reliable) messages received.
+ self.receiver = self.session.receiver(address, capacity=1000)
+ def run(self):
+ try:
+ while True:
+ m = self.receiver.fetch(1)
+ if m.content == "z": break
+ if m.content: # Ignore unreliable messages
+ # Ignore duplicates
+ if int(m.content) == self.received: self.received += 1
+ except Exception,e: self.error = e
+
+ # def test_ttl_failover
+
+ # Original cluster will all be killed so expect exit with failure
+ # Set small purge interval.
+ cluster = self.cluster(3, expect=EXPECT_EXIT_FAIL, args=["--queue-purge-interval=1"])
+ for b in cluster: b.ready() # Wait for brokers to be ready
+
+ # Python client failover produces noisy WARN logs, disable temporarily
+ logger = logging.getLogger()
+ log_level = logger.getEffectiveLevel()
+ logger.setLevel(logging.ERROR)
+ try:
+ # Start sender and receiver threads
+ receiver = Receiver(cluster[0], "q;{create:always}")
+ receiver.start()
+ sender = Sender(cluster[0], "q;{create:always}")
+ sender.start()
+ # Wait for sender & receiver to get up and running
+ retry(lambda: receiver.received > 0)
+
+ # Kill brokers in a cycle.
+ endtime = time.time() + self.duration()
+ runtime = min(5.0, self.duration() / 4.0)
+ i = 0
+ while time.time() < endtime:
+ for b in cluster[i:]: b.ready() # Check if any broker crashed.
+ cluster[i].kill()
+ i += 1
+ b = cluster.start(expect=EXPECT_EXIT_FAIL)
+ b.ready()
+ time.sleep(runtime)
+ sender.stop()
+ receiver.stop()
+ for b in cluster[i:]:
+ b.ready() # Check it didn't crash
+ b.kill()
+ self.assertEqual(sender.sent, receiver.received)
+ cluster_test_logs.verify_logs()
+
+ finally:
+ # Detach to avoid slow reconnect attempts during shut-down if test fails.
+ sender.connection.detach()
+ receiver.connection.detach()
+ logger.setLevel(log_level)
class StoreTests(BrokerTest):
"""
diff --git a/qpid/cpp/src/tests/federation.py b/qpid/cpp/src/tests/federation.py
index 201b06a4a2..49bdecdd95 100755
--- a/qpid/cpp/src/tests/federation.py
+++ b/qpid/cpp/src/tests/federation.py
@@ -649,10 +649,17 @@ class FederationTests(TestBase010):
self.verify_cleanup()
- def test_dynamic_headers(self):
+ def test_dynamic_headers_any(self):
+ self.do_test_dynamic_headers('any')
+
+ def test_dynamic_headers_all(self):
+ self.do_test_dynamic_headers('all')
+
+
+ def do_test_dynamic_headers(self, match_mode):
session = self.session
r_conn = self.connect(host=self.remote_host(), port=self.remote_port())
- r_session = r_conn.session("test_dynamic_headers")
+ r_session = r_conn.session("test_dynamic_headers_%s" % match_mode)
session.exchange_declare(exchange="fed.headers", type="headers")
r_session.exchange_declare(exchange="fed.headers", type="headers")
@@ -671,7 +678,7 @@ class FederationTests(TestBase010):
sleep(5)
session.queue_declare(queue="fed1", exclusive=True, auto_delete=True)
- session.exchange_bind(queue="fed1", exchange="fed.headers", binding_key="key1", arguments={'x-match':'any', 'class':'first'})
+ session.exchange_bind(queue="fed1", exchange="fed.headers", binding_key="key1", arguments={'x-match':match_mode, 'class':'first'})
self.subscribe(queue="fed1", destination="f1")
queue = session.incoming("f1")
diff --git a/qpid/cpp/xml/cluster.xml b/qpid/cpp/xml/cluster.xml
index 4d83c5b5de..c33f2e4852 100644
--- a/qpid/cpp/xml/cluster.xml
+++ b/qpid/cpp/xml/cluster.xml
@@ -8,9 +8,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
@@ -78,10 +78,6 @@
<field name="left" type="vbin16"/> <!-- packed member-id array -->
</control>
- <control name="message-expired" code="0x12">
- <field name="id" type="uint64"/>
- </control>
-
<domain name="error-type" type="uint8" label="Types of error">
<enum>
<choice name="none" value="0"/>
@@ -89,7 +85,7 @@
<choice name="connection" value="2"/>
</enum>
</domain>
-
+
<!-- Check for error consistency across the cluster -->
<control name="error-check" code="0x14">
<field name="type" type="error-type"/>
@@ -116,6 +112,11 @@
<field name="message" type="vbin32"/>
</control>
+ <!-- Update the cluster time -->
+ <control name="clock" code="0x22">
+ <field name="time" type="uint64"/>
+ </control>
+
</class>
<!-- Controls associated with a specific connection. -->
@@ -149,7 +150,7 @@
<!-- Abort a connection that is sending invalid data. -->
<control name="abort" code="0x4"/>
-
+
<!-- Update controls. Sent to a new broker in joining mode.
A connection is updated as followed:
- send the shadow's management ID in shadow-perpare on the update connection
@@ -183,7 +184,7 @@
<field name="position" type="sequence-no"/>
<field name="tag" type="str8"/>
<field name="id" type="sequence-no"/>
- <field name="acquired" type="bit"/> <!--If not set, message follows. -->
+ <field name="acquired" type="bit"/> <!--If not set, message is on update queue. -->
<field name="accepted" type="bit"/>
<field name="cancelled" type="bit"/>
<field name="completed" type="bit"/>
@@ -192,9 +193,9 @@
<field name="enqueued" type="bit"/>
<field name="credit" type="uint32"/>
</control>
-
+
<!-- Tx transaction state. -->
- <control name="tx-start" code="0x12"/>
+ <control name="tx-start" code="0x12"/>
<control name="tx-accept" code="0x13"> <field name="commands" type="sequence-set"/> </control>
<control name="tx-dequeue" code="0x14"> <field name="queue" type="str8"/> </control>
<control name="tx-enqueue" code="0x15"> <field name="queue" type="str8"/> </control>
@@ -204,7 +205,7 @@
</control>
<control name="tx-end" code="0x17"/>
<control name="accumulated-ack" code="0x18"> <field name="commands" type="sequence-set"/> </control>
-
+
<!-- Consumers in the connection's output task -->
<control name="output-task" code="0x19">
<field name="channel" type="uint16"/>
@@ -253,9 +254,6 @@
<!-- Replicate encoded exchanges/queues. -->
<control name="exchange" code="0x31"><field name="encoded" type="str32"/></control>
- <!-- Set expiry-id for subsequent messages. -->
- <control name="expiry-id" code="0x33"><field name="expiry-id" type="uint64"/></control>
-
<!-- Add a listener to a queue -->
<control name="add-queue-listener" code="0x34">
<field name="queue" type="str8"/>
@@ -289,6 +287,18 @@
<field name="state" type="map"/> <!-- "name"=value -->
</control>
+ <!-- Update the cluster time -->
+ <control name="clock" code="0x40">
+ <field name="time" type="uint64"/>
+ </control>
+
+ <!-- Update a queue's dequeue rate -->
+ <control name="queue-dequeue-since-purge-state" code="0x41">
+ <field name="queue" type="str8"/>
+ <field name="dequeueSincePurge" type="uint32"/>
+ </control>
+
+
</class>
</amqp>
diff --git a/qpid/doc/book/build-book.sh b/qpid/doc/book/build-book.sh
index 74a2ec963d..46192907e6 100755
--- a/qpid/doc/book/build-book.sh
+++ b/qpid/doc/book/build-book.sh
@@ -29,6 +29,12 @@
#
########################################################################
+# DOCBOOK XSL STYLESHEET LOCATION
+# Fedora, RHEL:
+DOCBOOK_XSL=/usr/share/sgml/docbook/xsl-stylesheets
+# Ubuntu:
+# DOCBOOK_XSL=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh
+
rm -rf build/$1
mkdir -p build/$1
mkdir -p build/$1/html-single
@@ -38,16 +44,16 @@ cp -r src/images build/$1/html-single
cp -r src/images build/$1/html
# Create single-page .html
-xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 /usr/share/sgml/docbook/xsl-stylesheets/html/docbook.xsl src/$1.xml >build/$1/html-single/$1.html
+xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 ${DOCBOOK_XSL}/html/docbook.xsl src/$1.xml >build/$1/html-single/$1.html
# Create chunked .html
INFILE=$(readlink -f src/$1.xml)
pushd build/$1/html
-xsltproc --xinclude --stringparam chunk.section.depth 1 --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 /usr/share/sgml/docbook/xsl-stylesheets/html/chunk.xsl $INFILE
+xsltproc --xinclude --stringparam chunk.section.depth 1 --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 ${DOCBOOK_XSL}/html/chunk.xsl $INFILE
popd
# Create the .fo
-xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 /usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl src/$1.xml >build/$1/pdf/$1.fo
+xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 ${DOCBOOK_XSL}/fo/docbook.xsl src/$1.xml >build/$1/pdf/$1.fo
# Use Apache FOP to create the PDF
fop build/$1/pdf/$1.fo build/$1/pdf/$1.pdf
diff --git a/qpid/doc/website/README.txt b/qpid/doc/website/README.txt
index 6a0c2876ab..dcb3b423e5 100644
--- a/qpid/doc/website/README.txt
+++ b/qpid/doc/website/README.txt
@@ -1,26 +1,10 @@
-This is the source directory for creating web pages for the Qpid web
-site.
+To edit the website, check out the /site repo area:
-The template used for all pages (template.html), stylesheet
-(style.css), and images are in the ./template directory.
+ svn co https://svn.apache.org/repos/asf/qpid/site
-The tools directory contains a very simple Python script (wrap) that
-combines a template and content to create static html pages. Content
-should be written in XHTML, with one <div/> element at the root - see
-./content/home.html for an example.
+The HTML files for the site reside in the docs directory, where a README
+can be found to describe the process of adding new content.
-Use wrap like this:
+It is no longer necessary to generate the main website pages, the live files
+are now edited directly, and are deployed to the web server after check in.
-$ tools/wrap template/template.html content/<filename> build/<filename>
-
-Content for the main pages should be check into the content
-directory. Content for documentation is created in the ../book
-directory.
-
-To publish generated content, check out the website repo:
-
-$ svn co https://svn.apache.org/repos/asf/qpid/site/docs
-
-Copy generated content (NOT the source!) into the website repo, add it
-using $ svn add, and commit it. When it is committed, it appears on
-the website.
diff --git a/qpid/doc/website/build.sh b/qpid/doc/website/build.sh
deleted file mode 100755
index 25162b4de0..0000000000
--- a/qpid/doc/website/build.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/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.
-#
-
-TEMPLATE_DIR=template
-TEMPLATE=template.html
-CONTENT_DIR=content
-BUILD_DIR=build
-WRAP="tools/wrap"
-
-# Gather the *.html filenames to wrap
-pushd $CONTENT_DIR >/dev/null
-HTML_FILES=`ls *.html`
-popd >/dev/null
-
-# Clear the existing artefacts, or create the build dir
-if [ -d $BUILD_DIR ];
-then
- rm -rf $BUILD_DIR/*;
-else
- mkdir $BUILD_DIR
-fi
-
-# Wrap the html files
-for FILE in $HTML_FILES;
-do
- ./$WRAP "$TEMPLATE_DIR/$TEMPLATE" "$CONTENT_DIR/$FILE" "$BUILD_DIR/$FILE"
-done
-
-# Copy the .htaccess, style.css, images, and any specifically required non-html content
-cp $CONTENT_DIR/.htaccess $BUILD_DIR/
-cp $TEMPLATE_DIR/style.css $BUILD_DIR/
-cp -R $TEMPLATE_DIR/images $BUILD_DIR/
-cp -R $CONTENT_DIR/images $BUILD_DIR/
-cp $CONTENT_DIR/download.cgi $BUILD_DIR/
-
-
diff --git a/qpid/doc/website/content/.htaccess b/qpid/doc/website/content/.htaccess
deleted file mode 100644
index a6ab32531b..0000000000
--- a/qpid/doc/website/content/.htaccess
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-Redirect /download.html http://qpid.apache.org/download.cgi
-Redirect /licence.html http://www.apache.org/licenses/
diff --git a/qpid/doc/website/content/acknowledgements.html b/qpid/doc/website/content/acknowledgements.html
deleted file mode 100644
index daeb21c172..0000000000
--- a/qpid/doc/website/content/acknowledgements.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>Acknowledgements</h1>
- <div>
- <table>
- <tbody>
- <tr>
- <td><a href="http://www.ej-technologies.com/products/jprofiler/overview.html">
- <img src="images/jprofiler.png" /></a>
- </td>
- <td><p>We acknowledge <a href="http://www.ej-technologies.com">ej-technologies</a> for giving us a free team license for profiling Qpid Java code.</p></td>
-
- </tr>
- <tr>
- <td><a href="http://www.headwaysoftware.com/products/structure101"><img src="images/structure101.jpg"/></a> </td>
- <td><p>We acknowledge <a href="http://www.headwaysoftware.com">Headway Software</a> for giving us free licenses of Structure101 for analyzing and managing the architecture of Qpid Java code.</p></td>
- </tr>
- </tbody></table>
- </div>
-</div>
diff --git a/qpid/doc/website/content/amqp.html b/qpid/doc/website/content/amqp.html
deleted file mode 100644
index a251164d07..0000000000
--- a/qpid/doc/website/content/amqp.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>What is AMQP?</h1>
-
- <p>AMQP <a href="http://www.amqp.org">Advanced Message Queuing Protocol</a> is an open standard designed to support reliable, high-performance messaging over the Internet. AMQP can be used for any distributed or business application, and supports common messaging paradigms like point-to-point, fanout, publish-subscribe, and request-response.</p>
-
- <p>Apache Qpid implements AMQP, including transaction management, queuing, clustering, federation, security, management and multi-platform support.</p>
-
-
- <p>Apache Qpid implements the latest AMQP specification, providing transaction management, queuing, distribution, security, management, clustering, federation and heterogeneous multi-platform support and a lot more. </p>
-
- <p>Apache Qpid is highly optimized, and <a href="compatibility.html" title="AMQP compatibility">aims to be 100% AMQP Compliant</a>.</p>
-
- <h2><a name="AMQP%28AdvancedMessageQueueingProtocol%29-DownloadtheAMQPSpecifications"></a>Download the AMQP Specifications</h2>
-
- <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion010"></a>AMQP version 0-10</h3>
-
-
- <ul>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.pdf?version=1">AMQP 0-10 Specification (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.xml?version=1">AMQP 0-10 Protocol Definition XML </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.dfd?version=1">AMQP 0-10 Protocol Definition DTD </a></li>
-
- </ul>
-
-
- <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion091"></a>AMQP version 0-9-1</h3>
-
- <ul>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.pdf?version=1">AMQP 0-9-1 Specification (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.xml?version=1">AMQP 0-9-1 Protocol Documentation (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.dtd?version=1">AMQP 0-9-1 Protocol Definitions (XML) </a></li>
- </ul>
-
-
- <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion09"></a>AMQP version 0-9</h3>
-
- <ul>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.pdf?version=1">AMQP 0-9 Specification (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.xml?version=1">AMQP 0-9 Protocol Documentation (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.dtd?version=1">AMQP 0-9 Protocol Definitions (XML) </a></li>
- </ul>
-
- <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion08"></a>AMQP version 0-8</h3>
-
- <ul>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1">AMQP 0-8 Specification (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.dtd?version=1">AMQP 0-8 Protocol Documentation (PDF) </a></li>
- <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.xml?version=1">AMQP 0-8 Protocol Definitions (XML) </a></li>
- </ul>
-</div>
-
diff --git a/qpid/doc/website/content/compatibility.html b/qpid/doc/website/content/compatibility.html
deleted file mode 100644
index a213665ba6..0000000000
--- a/qpid/doc/website/content/compatibility.html
+++ /dev/null
@@ -1,386 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <p><b>Qpid provides the most complete and compatible implementation of AMQP and is the most aggressive in implementing the latest version of the specification. Qpid can be</b> <b><a href="./download.cgi" title="Download"><b>downloaded here</b></a></b>.</p>
-
- <p>There are two brokers:</p>
-
- <ul>
- <li>C+&#43; with support for AMQP 0-10.</li>
- <li>Java with support for AMQP 0-8, 0-9, and 0-10.</li>
- </ul>
-
- <p>There are client libraries for C++, Java (JMS), .Net (written in C#), python and ruby.</p>
-
- <ul>
- <li>All clients support 0-10 and interoperate with both brokers as of Qpid 0.6.</li>
- <li>The JMS client supports 0-8, 0-9 and 0-10 and interoperates with both brokers.</li>
- <li>The python and ruby clients will also support all versions, but the API is dynamically driven by the specification used and so differs between versions. To work with the C+&#43; broker you must use 0-10. To work with the Java broker you can use any version as of Qpid 0.6, or prior to that you can use 0-8 or 0-9.</li>
- <li>There is also a WCF channel, which wraps the 0-10 native C++ client library.</li>
- </ul>
-
- <p>QMF Management is supported in Ruby, Python, C++, and can be translated to Java JMX &amp; WS-DM via the QMan management tool.</p>
-
- <h3><a name="AMQPcompatibility-AMQPCompatibilityofQpidreleases%3A"></a>AMQP Compatibility of Qpid releases:</h3>
-
- <p>Qpid implements the AMQP Specification, and as the specification has progressed Qpid is keeping up with the updates. This means that different Qpid versions support different versions of AMQP. Here is a simple guide on what to use.</p>
-
- <p>Here is a matrix that describes the different versions supported by each release<br/>
- Y = supported<br/>
- N = unsupported<br/>
-
- IP = in progress<br/>
- P = planned</p>
- <div >
- <table ><tbody>
- <tr>
- <th > Component </th>
- <th > Spec </th>
- <th >&nbsp;</th>
- <th >&nbsp;</th>
- <th >&nbsp;</th>
- <th >&nbsp;</th>
- <th >&nbsp;</th>
- <th >&nbsp;</th>
- <th >&nbsp;</th>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <th > M2.1 </th>
- <th > M3 </th>
- <th > M4 </th>
- <th > 0.5 </th>
- <th > 0.6 </th>
- <th > 0.8 </th>
- <th > 0.10 </th>
- </tr>
- <tr>
- <th > Java client </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-9 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-8 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <th > Java broker </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-9 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-8 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
-
- <th > C+&#43; client/broker </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-9 </td>
- <td > Y </td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- </tr>
-
- <tr>
- <th > Python client </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-9 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-8 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <th > WCF channel </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <th > Ruby client </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td >&nbsp;</td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-8 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td >&nbsp;</td>
- </tr>
- <tr>
-
- <th > C# client </th>
- <td > 0-10 </td>
- <td >&nbsp;</td>
- <td >&nbsp;</td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td >&nbsp;</td>
- </tr>
- <tr>
- <td >&nbsp;</td>
- <td > 0-8 </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- <td >&nbsp;</td>
- </tr>
- </tbody></table>
- </div>
-
-
- <h3><a name="AMQPcompatibility-InteroptablebyAMQPspecificationversion"></a>Interop table by AMQP specification version</h3>
-
- <p>Above table represented in another format.</p>
- <div >
- <table ><tbody>
- <tr>
- <th >Component</th>
- <th >Release </th>
-
- <th > 0-8 </th>
- <th > 0-9 </th>
- <th > 0-10 </th>
- </tr>
- <tr>
- <td > Java client </td>
- <td > M3, M4, 0.5, 0.6, 0.8, 0.10</td>
-
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td > Java client </td>
- <td > M2.1 </td>
-
- <td > Y </td>
- <td > Y </td>
- <td > N </td>
- </tr>
- <tr>
- <td > Java broker </td>
- <td > 0.6, 0.8, 0.10</td>
-
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td > Java broker </td>
- <td > M3, M4, 0.5 </td>
-
- <td > Y </td>
- <td > Y </td>
- <td > N </td>
- </tr>
- <tr>
- <td > Java broker </td>
- <td > M2.1 </td>
-
- <td > Y </td>
- <td > Y </td>
- <td > N </td>
- </tr>
- <tr>
- <td > C+&#43; client/broker </td>
- <td > M3, M4, 0.5, 0.6, 0.8, 0.10</td>
-
- <td > N </td>
- <td > N </td>
- <td > Y </td>
- </tr>
- <tr>
- <td > C+&#43; client/broker </td>
- <td > M2.1 </td>
-
- <td > N </td>
- <td > Y </td>
- <td > N </td>
- </tr>
- <tr>
- <td > Python client </td>
- <td > M3, M4, 0.5, 0.6, 0.8, 0.10</td>
-
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td > Python client </td>
- <td > M2.1 </td>
-
- <td > Y </td>
- <td > Y </td>
- <td > N </td>
- </tr>
- <tr>
- <td > WCF channel </td>
- <td > 0.6, 0.8, 0.10</td>
-
- <td > N </td>
- <td > N </td>
- <td > Y </td>
- </tr>
- <tr>
- <td > Ruby client </td>
- <td > M4, 0.5, 0.6, 0.8</td>
-
- <td > Y </td>
- <td > Y </td>
- <td > Y </td>
- </tr>
- <tr>
- <td > Ruby client </td>
- <td > M3 </td>
-
- <td > Y </td>
- <td > Y </td>
- <td > N </td>
- </tr>
- <tr>
- <td > C# client 0-10 </td>
- <td > M4, 0.5, 0.6, 0.8</td>
-
- <td > N </td>
- <td > N </td>
- <td > Y</td>
- </tr>
- <tr>
- <td > C# client 0-8 </td>
- <td > M3, M4, 0.5, 0.6, 0.8</td>
-
- <td > Y </td>
- <td > N </td>
- <td > N </td>
- </tr>
- </tbody></table>
- </div>
-</div>
diff --git a/qpid/doc/website/content/documentation.html b/qpid/doc/website/content/documentation.html
deleted file mode 100644
index 304c9ea26f..0000000000
--- a/qpid/doc/website/content/documentation.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>Qpid Documentation</h1>
-
- <h2 id="doc-release">Documentation for Qpid 0.10 release</h2>
-
- <p>This documentation was converted from the Wiki and organized into
- book form. <a href="#doc-archives">The archives</a> contain the
- original content of the Wiki.</p>
-
- <ul>
- <li><a href="getting_started.html">Getting Started</a></li>
- <li><p>AMQP Messaging Broker (C++ implementation for Linux, Windows, Solaris)</p>
- <p>
- <a href="books/0.10/AMQP-Messaging-Broker-CPP-Book/pdf/AMQP-Messaging-Broker-CPP-Book.pdf"
- name="AMQP Messaging Broker (C++ implemementation)">PDF</a> |
- <a href="books/0.10/AMQP-Messaging-Broker-CPP-Book/html/index.html">HTML</a></p></li>
- <li><p>AMQP Messaging Broker (Java implemementation)</p>
- <p><a href="books/0.10/AMQP-Messaging-Broker-Java-Book/pdf/AMQP-Messaging-Broker-Java-Book.pdf"
- name="AMQP Messaging Broker (Java implemementation)">PDF</a> |
- <a href="books/0.10/AMQP-Messaging-Broker-Java-Book/html/index.html">HTML</a></p></li>
- <li><p>Programming in Apache Qpid: Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python</p>
- <p>
- <a href="books/0.10/Programming-In-Apache-Qpid/pdf/Programming-In-Apache-Qpid.pdf"
- name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">PDF</a> |
- <a href="books/0.10/Programming-In-Apache-Qpid/html/index.html"
- name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">HTML</a></p></li>
- <li><p>For programming examples and documentation for Qpid,
- see the <a href="getting_started.html">Getting Started</a>
- page.</p></li>
- <li><p>API Reference Documentation</p>
- <p>C++: <a href="apis/0.10/cpp/html/index.html">HTML</a> | <a href="apis/0.10/cpp/qpid-cpp-doxygen-0.10.html.tar.gz">qpid-cpp-doxygen-0.10.html.tar.gz</a></p>
- <p>Python: <a href="apis/0.10/python/html/index.html">HTML</a> | <a href="apis/0.10/python/qpid-python-epydoc-0.10.html.tar.gz">qpid-python-epydoc-0.10.html.tar.gz</a></p></li>
- </ul>
-
-
- <h2 id="doc-trunk">Documentation for Qpid development trunk</h2>
- <ul>
- <li><a href="getting_started.html">Getting Started</a></li>
- <li><p>AMQP Messaging Broker (C++ implementation for Linux, Windows, Solaris)</p>
- <p>
- <a href="books/trunk/AMQP-Messaging-Broker-CPP-Book/pdf/AMQP-Messaging-Broker-CPP-Book.pdf"
- name="AMQP Messaging Broker (C++ implemementation)">PDF</a> |
- <a href="books/trunk/AMQP-Messaging-Broker-CPP-Book/html/index.html">HTML</a></p></li>
- <li><p>AMQP Messaging Broker (Java implemementation)</p>
- <p><a href="books/trunk/AMQP-Messaging-Broker-Java-Book/pdf/AMQP-Messaging-Broker-Java-Book.pdf"
- name="AMQP Messaging Broker (Java implemementation)">PDF</a> |
- <a href="books/trunk/AMQP-Messaging-Broker-Java-Book/html/index.html">HTML</a></p></li>
- <li><p>Programming in Apache Qpid: Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python</p>
- <p>
- <a href="books/trunk/Programming-In-Apache-Qpid/pdf/Programming-In-Apache-Qpid.pdf"
- name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">PDF</a> |
- <a href="books/trunk/Programming-In-Apache-Qpid/html/index.html"
- name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">HTML</a></p></li>
- </ul>
-
-
-
- <h2 id="doc-archives">Documentation Archives</h2>
-
- <ul>
- <li><p>Qpid Wiki converted to PDF format on 26 May 2010</p>
- <a href="archives/qpid-2010-05-26.html.zip">HTML</a> |
- <a href="archives/qpid-2010-05-26.pdf">PDF</a></li>
- </ul>
-
- <h2 id="qpid-wiki">Qpid Wiki</h2>
-
- <ul>
- <li><p><a href="https://cwiki.apache.org/qpid/">Qpid Wiki</a></p></li>
- </ul>
-
-</div>
diff --git a/qpid/doc/website/content/download.cgi b/qpid/doc/website/content/download.cgi
deleted file mode 100644
index c4e25082c8..0000000000
--- a/qpid/doc/website/content/download.cgi
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# Wrapper script around mirrors.cgi script
-# (we must change to that directory in order for python to pick up the
-# python includes correctly)
-cd /www/www.apache.org/dyn/mirrors
-/www/www.apache.org/dyn/mirrors/mirrors.cgi $*
-
diff --git a/qpid/doc/website/content/download.html b/qpid/doc/website/content/download.html
deleted file mode 100644
index 477e7aa0cf..0000000000
--- a/qpid/doc/website/content/download.html
+++ /dev/null
@@ -1,304 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>Downloads</h1>
-
- <h2>Production Releases</h2>
-
- <p>These releases are well tested and appropriate for production use, use the links below to download them from one of our mirrors. Older versions can be found in the <a href="http://archive.apache.org/dist/qpid/">archive</a></p>
-
- <p>Qpid supports the latest version of AMQP 0-10, and some components also the earlier AMQP 0-8 and 0-9 versions. The Java Broker and Client provide protocol negotiation. For details on cross component compatibility among releases, see: <a href="./compatibility.html">AMQP Release Compatibility for Qpid</a></p>
-
- <p>If you have any questions about these releases, please email the <a href="mailto:users@qpid.apache.org">user list</a></p>
-
- <h2>Mirrors</h2>
-
- <p>[if-any logo]
-<a href="[link]"><img align="right" src="[logo]" border="0" /></a>[end]
-The currently selected mirror is <b>[preferred]</b>. If you encounter a problem with this mirror, please select another. If all mirrors are failing, there are <i>backup</i> mirrors (at the end of the list) that should be available, or you may also consult the <a href="http://www.apache.org/mirrors/">complete list</a> of mirrors.</p>
-
-<form action="[location]" method="get" id="SelectMirror">
-<p>
-Other mirrors: <select name="Preferred">
-[if-any http]
- [for http]<option value="[http]">[http]</option>[end]
-[end]
-[if-any ftp]
- [for ftp]<option value="[ftp]">[ftp]</option>[end]
-[end]
-[if-any backup]
- [for backup]<option value="[backup]">[backup] (backup)</option>[end]
-[end]
-</select>
-<input type="submit" value="Change" />
-</p>
-</form>
-
- <p> It is good practice to <a href="#Download-Verify">verify</a> the integrity of the downloaded files using signatures downloaded from our <a href="http://www.apache.org/dist/qpid/">main distribution directory</a>.</p>
-
- <h2>Latest Release: 0.10</h2>
-
- <p>Individual PGP signatures are provided below, and the sha1sum output for each artefact is listed here: <a href="http://www.apache.org/dist/qpid/0.10/SHA1SUM">SHA1SUM</a>.</p>
-
- <h3>Multiple Component Packages</h3>
-
- <div>
- <table class="download_table"><tbody>
- <tr>
- <th class="download_table_col_1"> Component </th>
-
- <th> Download </th>
- <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
- <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
- </tr>
- <tr>
- <td class="download_table_col_1"> Full source release</td>
- <td> <a href="[preferred]/qpid/0.10/qpid-0.10.tar.gz">qpid-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-0.10.tar.gz.asc">PGP</a>] </td>
-
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col"> Y </td>
- </tr>
- <tr>
- <td class="download_table_col_1"> C+&#43; broker &amp; client </td>
- <td> <a href="[preferred]/qpid/0.10/qpid-cpp-0.10.tar.gz">qpid-cpp-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-cpp-0.10.tar.gz.asc">PGP</a>] </td>
-
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col">&nbsp;</td>
- </tr>
- <tr>
- <td class="download_table_col_1"> Java broker, client &amp; tools </td>
- <td> <a href="[preferred]/qpid/0.10/qpid-java-0.10.tar.gz">qpid-java-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-java-0.10.tar.gz.asc">PGP</a>] </td>
- <td class="download_table_amqp_col"> Y </td>
-
- <td class="download_table_amqp_col"> Y </td>
- </tr>
- <tr>
- <td class="download_table_col_1"> All released artefacts</td>
- <td> <a href="[preferred]/qpid/0.10/">/qpid/0.10/</a> </td>
-
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col"> Y </td>
- </tr>
- </tbody></table>
- </div>
-
- <h3><a name="Download-SingleComponentPackage"></a>Single Component Packages</h3>
-
- <p><b>Broker</b></p>
- <div>
- <table class="download_table"><tbody>
- <tr>
- <th class="download_table_col_1"> Language </th>
-
- <th> Download </th>
- <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
- <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
- </tr>
- <tr>
- <td class="download_table_col_1"> Java </td>
- <td> <a href="[preferred]/qpid/0.10/qpid-java-broker-0.10.tar.gz">qpid-java-broker-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-java-broker-0.10.tar.gz.asc">PGP</a>] </td>
-
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col"> Y </td>
- </tr>
- </tbody></table>
- </div>
-
- <p><b>Client</b></p>
- <div>
- <table class="download_table"><tbody>
- <tr>
- <th class="download_table_col_1"> Language </th>
-
- <th> Download </th>
- <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
- <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
- </tr>
- <tr>
- <td class="download_table_col_1"> C# (.NET, WCF) WCF channel (C+&#43; Broker Compatible) </td>
- <td> <a href="[preferred]/qpid/0.10/qpid-wcf-0.10.zip">qpid-wcf-0.10.zip</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-wcf-0.10.zip.asc">PGP</a>] </td>
-
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col">&nbsp;</td>
- </tr>
- <tr>
- <td class="download_table_col_1"> Java </td>
-
- <td> <a href="[preferred]/qpid/0.10/qpid-java-client-0.10.tar.gz">qpid-java-client-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-java-client-0.10.tar.gz.asc">PGP</a>] </td>
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col"> Y </td>
- </tr>
- <tr>
- <td class="download_table_col_1"> Python </td>
- <td> <a href="[preferred]/qpid/0.10/qpid-python-0.10.tar.gz">qpid-python-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-python-0.10.tar.gz.asc">PGP</a>] </td>
-
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col"> Y </td>
- </tr>
- </tbody></table>
- </div>
-
- <p><b>Management tools</b></p>
-
- <p>C+&#43; broker management</p>
- <div>
- <table class="download_table"><tbody>
-
- <tr>
- <th class="download_table_col_1"> Component </th>
- <th> Download </th>
- <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
- <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
- </tr>
- <tr>
- <td class="download_table_col_1">Command-line tools</td>
- <td> <a href="[preferred]/qpid/0.10/qpid-tools-0.10.tar.gz">qpid-tools-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-tools-0.10.tar.gz.asc">PGP</a>] </td>
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col">&nbsp;</td>
- </tr>
- <tr>
- <td class="download_table_col_1">QMF APIs</td>
- <td> <a href="[preferred]/qpid/0.10/qpid-qmf-0.10.tar.gz">qpid-qmf-0.10.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-qmf-0.10.tar.gz.asc">PGP</a>] </td>
- <td class="download_table_amqp_col"> Y </td>
- <td class="download_table_amqp_col">&nbsp;</td>
- </tr>
- </tbody></table>
-
- </div>
-
- <p>Java broker management</p>
- <div>
- <table class="download_table"><tbody>
- <tr>
- <th class="download_table_col_1"> Component </th>
- <th> Download </th>
- </tr>
- <tr>
- <td class="download_table_col_1"> JMX Management Console <br /> </td>
-
- <td> <a href="[preferred]/qpid/0.10/qpid-jmx-management-console-0.10-linux-gtk-x86.tar.gz">Linux x86</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-jmx-management-console-0.10-linux-gtk-x86.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.10/qpid-jmx-management-console-0.10-linux-gtk-x86_64.tar.gz">Linux x86_64</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-jmx-management-console-0.10-linux-gtk-x86_64.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.10/qpid-jmx-management-console-0.10-macosx.zip">Mac OS X</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-jmx-management-console-0.10-macosx.zip.asc">PGP</a>] | <a href="[preferred]/qpid/0.10/qpid-jmx-management-console-0.10-solaris-gtk-sparc.tar.gz">Solaris 10 Sparc</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-jmx-management-console-0.10-solaris-gtk-sparc.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.10/qpid-jmx-management-console-0.10-win32-win32-x86.zip">Windows x86</a> [<a href="http://www.apache.org/dist/qpid/0.10/qpid-jmx-management-console-0.10-win32-win32-x86.zip.asc">PGP</a>] </td>
- </tr>
- </tbody></table>
- </div>
-
- <h3><a name="Download-Maven"></a>Maven artifacts</h3>
- <p>The Java client is also available via the Maven central repository. To use the client in your Maven build you should add the following dependency to your POM:</p>
- <code>
-&lt;dependency&gt;<br />
-&nbsp;&nbsp;&lt;groupId&gt;org.apache.qpid&lt;/groupId&gt;<br />
-&nbsp;&nbsp;&lt;artifactId&gt;qpid-client&lt;/artifactId&gt;<br />
-&nbsp;&nbsp;&lt;version&gt;0.10&lt;/version&gt;<br />
-&lt;/dependency&gt;
- </code>
-
- <p>Additionally, you must provide the JMS API if it is not already available in your compilation and/or runtime environment, an example dependency for this would be:</p>
- <code>
-&lt;dependency&gt;<br />
-&nbsp;&nbsp;&lt;groupId&gt;org.apache.geronimo.specs&lt;/groupId&gt;<br />
-&nbsp;&nbsp;&lt;artifactId&gt;geronimo-jms_1.1_spec&lt;/artifactId&gt;<br />
-&nbsp;&nbsp;&lt;version&gt;1.0&lt;/version&gt;<br />
-&lt;/dependency&gt;
- </code>
-
- <h2><a name="Download-PreviousRelease"></a>Previous Releases</h2>
-
- <p>Previous releases are available from <a href="http://archive.apache.org/dist/qpid/">http://archive.apache.org/dist/qpid/
-</a>.</p>
-
- <h2><a name="Download-QpidComponents.org"></a>QpidComponents.org </h2>
-
- <p><a href="http://QpidComponents.org">QpidComponents.org</a> provides further components for Apache Qpid, including both persistence and management tools. These components are open source, but are not developed as part of the Apache Qpid project due to licensing or other restrictions.</p>
-
- <h2><a name="Download-ContributedC%5CPackages"></a>Contributed C+&#43; Packages</h2>
-
- <h3><a name="Download-WindowsInstaller"></a>Windows Installer</h3>
-
- <p>The Windows installer is available from <a href="http://www.riverace.com/qpid/downloads.htm">http://www.riverace.com/qpid/downloads.htm</a>. It is built from the C+&#43; broker &amp; client and C# WCF Channel source distributions listed above. It has been tested for Windows XP SP3 and above.</p>
-
- <h3><a name="Download-PrebuiltLinuxPackages"></a>Pre-built Linux Packages</h3>
-
- <h4><a name="Download-Fedora"></a>Fedora </h4>
-
- <p>On Fedora, Qpid can be installed using yum. Because Java RPMs are not yet available in Fedora repos, the Java client is not in these distributions.</p>
-
- <p>To install the server:</p>
- <div><div>
- <pre>
-# yum install qpidd
- </pre>
- </div></div>
-
- <p>To install C+&#43; and Python clients:</p>
- <div><div>
- <pre>
-# yum install qpidc-devel
- </pre>
- </div></div>
- <div><div>
- <pre>
-# yum install amqp python-qpid
- </pre>
- </div></div>
- <p>To install documentation:</p>
- <div><div>
-
- <pre>
-# yum install rhm-docs
- </pre>
- </div></div>
- <p>To install persistence using an external store module:</p>
- <div><div>
- <pre>
-# yum install rhm
- </pre>
- </div></div>
-
- <h2><a name="Download-SourceCodeRepository"></a>Source Code Repository</h2>
-
- <p>The latest version of the code is always available in the <a href="source_repository.html" title="Source Repository">source repository</a>.</p>
-
-
- <h2><a name="Download-Verify"></a>Verify the integrity of the files</h2>
-
- <p>It is essential that you verify the integrity of the downloaded files using the PGP signatures or SHA1 checksums.</p>
-
- <p>The PGP signatures can be verified using PGP or GPG. First download the <a href="http://www.apache.org/dist/qpid/KEYS">KEYS</a> file as well as the <code>.asc</code> PGP signature file for the relevant artefact. Make sure you get these files from the relevant subdirectory of the <a href="http://www.apache.org/dist/qpid/">main distribution directory</a>, rather than from a mirror. Then verify the signatures using:</p>
-
- <p>
- <code>
-% pgpk -a KEYS<br />
-% pgpv qpid-0.10.tar.gz.asc<br />
- </code>
- <em>or</em><br />
- <code>
-% pgp -ka KEYS<br />
-% pgp qpid-0.10.tar.gz.asc<br />
- </code>
- <em>or</em><br />
- <code>
-% gpg --import KEYS<br />
-% gpg --verify qpid-0.10.tar.gz.asc
- </code>
- </p>
-
-<p>Alternatively, you can verify the SHA1 checksum of the files. A unix program called <code>sha1</code> or <code>sha1sum</code> is included in many unix distributions. It is also available as part of <a href="http://www.gnu.org/software/textutils/textutils.html">GNU Textutils</a>. For windows users, <a href="http://www.slavasoft.com/fsum/">fsum</a> supports SHA1. Ensure your generated checksum string matches the string published in the SHA1SUM file included with each release. Again, make sure you get this file from the relevant subdirectory of the <a href="http://www.apache.org/dist/qpid/">main distribution directory</a>, rather than from a mirror</p>
-
-</div>
diff --git a/qpid/doc/website/content/getting_involved.html b/qpid/doc/website/content/getting_involved.html
deleted file mode 100644
index 033abdc443..0000000000
--- a/qpid/doc/website/content/getting_involved.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
-
-<h1>Getting Involved</h1>
-
-<h2><a name="GettingInvolved-TherearemanywaysyoucangetinvolvedinQpid%3A"></a>Join in</h2>
-
-<ol>
- <li>Participate on the <a href="mailing_lists.html" title="Mailing Lists">Mailing Lists</a>.</li>
- <li>Contibute via <a href="http://issues.apache.org/jira/browse/qpid">JIRA issues</a>. Remember that all patches must be attached to a JIRA with the ASL usage granted or we can't use it!</li>
- <li>Review the current code.</li>
- <li>Help write user documentation.</li>
- <li>Help write user examples.</li>
- <li>Most definitely add more tests.</li>
-</ol>
-
-<p>Please be sure to take a look at the coding guidelines for the section of the project that you contribute to:</p>
-
-<ul>
- <li><a href="https://cwiki.apache.org/qpid/java-coding-standards.html">Java Coding Standards</a></li>
- <li><a href="https://cwiki.apache.org/qpid/cppstyleguide.html">C++ Coding Standards</a></li>
-
- <li><a href="https://cwiki.apache.org/qpid/cpptips.html">C++ Tips</a></li>
- <li><a href="https://cwiki.apache.org/qpid/osvc.html">OS version considerations</a></li>
-</ul>
-
-<h2><a name="GettingInvolved-ProjectEtiquette"></a>Project Etiquette</h2>
-
-<p>Please read and digest our <a href="qpid_project_etiquette_guide.html" title="Qpid Project Etiquette Guide">Qpid Project Etiquette Guide</a>. This is a key guide for new contributers and required reading.</p>
-
-<h2><a name="GettingInvolved-Becomingacommitter%3A"></a>Becoming a Committer</h2>
-
-<p>Qpid uses the following guidelines for voting in new committers. First off we would like new committers to have provided meaningful contribution to the project. By contributions we include development (tests, features, examples) or documentation through patches and interactions with the project through lists and JIRA. It should be noted that as we send our JIRA to the dev list, thus some people filter the JIRA's to limit traffic. It is thus good to cross post something to the dev list every now and again, if the discussion is being held primarily on JIRA.</p>
-
-<p>The key question is what does the Qpid project consider to be a meaningful contribution to be come a committer. As this bar is set for all new commiters Qpid will be conservative in general with adding new committers.</p>
-
-<p>The Qpid project will look to see if someone consistently provides quality contributions and interactions with the project over a period of several weeks. Based on that the PMC will vote the new committers onto the project. </p>
-
-<p>If you have any question please mail <a href="mailto:dev@qpid.apache.org">dev@qpid.apache.org</a> or <a href="mailto:private@qpid.apache.org">private@qpid.apache.org</a> </p>
-
-<p>Many thanks for you interest,<br />
-
-The Qpid Team.</p>
-
-<h2><a name="GettingInvolved-JoiningthePMC"></a>Joining the PMC</h2>
-
-<p>Nominations for Qpid PMC membership will be voted on by the Qpid PMC.</p>
-
-</div>
-
diff --git a/qpid/doc/website/content/getting_started.html b/qpid/doc/website/content/getting_started.html
deleted file mode 100644
index 5706d77781..0000000000
--- a/qpid/doc/website/content/getting_started.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body" >
- <h1>Getting Started with Apache Qpid</h1>
- <p>To get started with Apache Qpid, follow the steps below.</p>
-
- <ol>
- <li>Download the software:
- <ul>
- <li><a href="download.cgi" title="Download page">Download page</a></li>
- </ul>
- </li>
- <li>Start a broker:
- <ul>
- <li>Instructions for <a href="https://cwiki.apache.org/qpid/getting-started-guide.html" title="Getting Started Guide">running a Qpid Java broker (AMQP 0-8, 0-9) </a></li>
- <li>Instructions for <a href="http://qpid.apache.org/books/trunk/AMQP-Messaging-Broker-CPP-Book/html/ch01.html#section-Running-a-Qpid-CPP-Broker" title="RASC">running a Qpid C++ broker (AMQP 0-10) </a></li>
-
- <li><a href="https://cwiki.apache.org/qpid/mgmtc.html" title="MgmtC++">Management tools </a> (AMQP 0-10, works with the Qpid C++ broker)</li>
- </ul>
- </li>
- <li>Run an example program from the downloaded software, or from the following URLs (these are Subversion URLs, which you can use to browse the examples or check them out):
- <ul>
- <li>C++ (AMQP 0-10):
- <ul>
- <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/ </a></li>
- <li><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/README.txt">Running the C++ Examples </a></li>
- </ul>
- </li>
- <li>Java JMS (AMQP 0-10):
- <ul>
- <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/ </a></li>
- <li><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/runSample.sh">Script for Running the Java JMS Examples </a></li>
- </ul>
- </li>
- <li>Python (AMQP 0-10):
- <ul>
- <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/ </a></li>
- <li><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/README">Running the Python Examples </a></li>
- </ul>
- </li>
- </ul>
- </li>
- <li>Read the API Guides and Documentation:
- <ul>
- <li><a href="documentation.html">API Guides and Documentation</a></li>
- </ul>
- </li>
- <li>Get your questions answered:
- <ul>
- <li>Read the <a href="https://cwiki.apache.org/qpid/faq.html" title="FAQ">FAQ</a></li>
- <li>Ask a question on the user list <a href="mailto:users-subscribe@qpid.apache.org">users-subscribe@qpid.apache.org</a></li>
- </ul>
- </li>
- </ol>
-</div>
diff --git a/qpid/doc/website/content/images/README.txt b/qpid/doc/website/content/images/README.txt
deleted file mode 100644
index c53909bfd2..0000000000
--- a/qpid/doc/website/content/images/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-This directory is for images associated with content, not the images used in page templates.
diff --git a/qpid/doc/website/content/images/jprofiler.png b/qpid/doc/website/content/images/jprofiler.png
deleted file mode 100644
index 7c5da2cf94..0000000000
--- a/qpid/doc/website/content/images/jprofiler.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/content/images/structure101.jpg b/qpid/doc/website/content/images/structure101.jpg
deleted file mode 100644
index 9242ea9176..0000000000
--- a/qpid/doc/website/content/images/structure101.jpg
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/content/index.html b/qpid/doc/website/content/index.html
deleted file mode 100644
index 16e96ebc7a..0000000000
--- a/qpid/doc/website/content/index.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>Introduction</h1>
-
- <p>Apache Qpid&#8482; is a cross-platform Enterprise
- Messaging system which implements the Advanced Message Queuing Protocol
- (AMQP), providing message brokers written in C++ and
- Java, along with clients for C++, Java JMS, .Net, Python, and Ruby.</p>
-
- <p>Enterprise Messaging systems let programs communicate by
- exchanging messages, much as people communicate by
- exchanging email. Unlike email, enterprise messaging systems
- provide guaranteed delivery, speed, security, and freedom
- from spam. Until recently, there was no open standard for
- Enterprise Messaging systems, so programmers either wrote
- their own, or used expensive proprietary systems.</p>
-
- <p><a href="http://www.amqp.org/">AMQP</a> is the first open standard for
- Enterprise Messaging. It is designed to support messaging
- for just about any distributed or business
- application. Routing can be configured flexibly, easily
- supporting common messaging paradigms like point-to-point,
- fanout, publish-subscribe, and request-response.</p>
-
- <p>Apache Qpid implements the latest AMQP specification, providing
- transaction management, queuing, distribution, security,
- management, clustering, federation and heterogeneous
- multi-platform support and a lot more. And Apache Qpid is
- extremely fast. Apache Qpid <a href="compatibility.html"
- title="AMQP compatibility">aims to be 100% AMQP Compliant</a>.</p>
-
- <p>This is a project of the <a href="http://www.apache.org/">Apache Software Foundation.</a></p>
-
- <div class="feature_box">
- <div class="feature_box_column1">
- <h3>AMQP Brokers</h3>
- <ul>
- <li><p>Java Implementation</p>
- </li>
- <li><p>C++ Implementation</p>
- </li>
- </ul>
- <br/>
- <br/>
- </div> <!-- end of feature_box_column -->
-
- <div class="feature_box_column2">
- <h3>AMQP Client APIs</h3>
- <ul>
- <li>Java (JMS 1.1 compliant)</li>
- <li>C++ (Linux/Windows)</li>
- <li>C# .NET</li>
- <li>WCF Adapter (Windows Only)</li>
- <li>Python</li>
- <li>Ruby</li>
- </ul>
- </div> <!-- end of feature_box_column -->
-
- <div class="feature_box_column3">
- <h3>Qpid Management</h3>
- <ul>
- <li>QMF Python API</li>
- <li>QMF C++ API </li>
- <li>Python tools</li>
- <li>JMX</li>
- </ul>
- </div> <!-- end of feature_box_column -->
-
- </div> <!-- end of feature_box -->
-
-</div> <!-- end of main_text_area_body -->
-
diff --git a/qpid/doc/website/content/mailing_lists.html b/qpid/doc/website/content/mailing_lists.html
deleted file mode 100644
index b1c5266e40..0000000000
--- a/qpid/doc/website/content/mailing_lists.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>Qpid Mailing lists</h1>
-
- <p>There are a number of lists listed below. Note when sening subscription emails it is best to have a value in the subjsct and body even if it is only 'subscribe'. This will help the ensure the email get past the spam filters.</p>
-
- <h2>Qpid User List</h2>
-
- <p>The user's list is for discussions that relate to use or questions
- on Qpid. If you have questions about how a feature works, suggestions
- on additional requirements, or general questions about Qpid please use
- this list.</p>
-
- <ul>
- <li>To subscribe to the user's list send an e-mail with subject 'subscribe' to:<br />
- <a href="mailto:users-subscribe@qpid.apache.org">users-subscribe@qpid.apache.org</a></li>
-
- <li>To remove yourself from the user's list send an e-mail with subject 'unsubscribe' to:<br />
- <a href="mailto:users-unsubscribe@qpid.apache.org">users-unsubscribe@qpid.apache.org</a></li>
- <li>The user's mailing list is archived. You can view the archive at:
- <ul>
- <li>Apache archive: <a href="http://mail-archives.apache.org/mod_mbox/qpid-users/">http://mail-archives.apache.org/mod_mbox/qpid-users/</a><br/></li>
- <li>Nabble archive: <a href="http://n2.nabble.com/Apache-Qpid-users-f2158936.html">http://n2.nabble.com/Apache-Qpid-users-f2158936.html</a></li>
- </ul>
- </li>
- </ul>
-
-
- <h2><a name="MailingLists-QpidDeveloperList"></a>Qpid Developer List</h2>
-
- <p>The developer's list is for discussions that relate to the on going development of Qpid. If you have questions about how a feature is being developed, suggestions on how to implement a new feature, or requests for a new feature this is the list to use.</p>
-
- <ul>
- <li>To subscribe to the developer's list send an e-mail with subject 'subscribe' to:<br />
- <a href="mailto:dev-subscribe@qpid.apache.org">dev-subscribe@qpid.apache.org</a></li>
- <li>To remove yourself from the developer's list send an e-mail with subject 'unsubscribe' to:
- <a href="mailto:dev-unsubscribe@qpid.apache.org">dev-unsubscribe@qpid.apache.org</a></li>
- <li>The developer's mailing list is archived. You can view the archive at:
- <ul>
- <li>Apache archive: <a href="http://mail-archives.apache.org/mod_mbox/qpid-dev/">http://mail-archives.apache.org/mod_mbox/qpid-dev/</a></li>
- <li>Nabble archive: <a href="http://www.nabble.com/Qpid-Developers-f16694.html">http://www.nabble.com/Qpid-Developers-f16694.html</a><br/>
- and <a href="http://n2.nabble.com/Apache-Qpid-developers-f2158895.html">http://n2.nabble.com/Apache-Qpid-developers-f2158895.html</a></li>
- </ul>
- </li>
- </ul>
-
-
- <h2><a name="MailingLists-QpidCommitsList"></a>Qpid Commits List</h2>
-
- <p>The commits list is for recieving notifications about code being committed to the Qpid repository. The trafic on this list is automatically generated by Subversion. You should not post messages to this list.</p>
-
- <ul>
- <li>To subscribe to the commits list send an e-mail with subject 'subscribe' to:<br />
- <a href="mailto:commits-subscribe@qpid.apache.org">commits-subscribe@qpid.apache.org</a></li>
- <li>To remove yourself from the commits list send an e-mail with subject 'unsubscribe' to:<br />
- <a href="mailto:commits-unsubscribe@qpid.apache.org">commits-unsubscribe@qpid.apache.org</a></li>
- <li>The commits mailing list is archived. You can view the archive at:
- <ul>
- <li>Apache archive: <a href="http://mail-archives.apache.org/mod_mbox/qpid-commits/">http://mail-archives.apache.org/mod_mbox/qpid-commits/</a></li>
- </ul>
- </li>
- </ul>
-</div>
diff --git a/qpid/doc/website/content/people.html b/qpid/doc/website/content/people.html
deleted file mode 100644
index 23cafa2b53..0000000000
--- a/qpid/doc/website/content/people.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>People</h1>
-
- <p>This page lists some of the people who have contributed to Qpid.</p>
-
- <h2>Committers</h2>
- <p>The people listed below have made significant contributions to
- Qpid by working long and hard to make quality software for the rest
- of the world to use.</p>
-
- <p>In addition to providing us contribuions, or being commmitters
- some of the following people are also members of the Project
- Management Committee (PMC). Refer to the How the ASF works for
- details on meritocracy.</p>
-
- <p>If you would like to contribute to Qpid please look at the Get
- Involved page to see how you can contribute.</p>
-
- <ul>
- <li>Aidan Skinner</li>
- <li>Alan Conway</li>
- <li>Andrea Gazzarini</li>
- <li>Andrew Kennedy</li>
- <li>Andrew Stitcher</li>
- <li>Arnaud Simon</li>
- <li>Carl Trieloff</li>
- <li>Chuck Rolke</li>
- <li>Cliff Jansen</li>
- <li>Gordon Sim</li>
- <li>Jim Meyering</li>
- <li>John O'Hara</li>
- <li>Jonathan Robie</li>
- <li>Justin Ross</li>
- <li>Ken Giusti</li>
- <li>Kim van der Riet</li>
- <li>Lahiru Gunathilake</li>
- <li>Manuel Teira</li>
- <li>Marnie McCormack</li>
- <li>Martin Ritchie</li>
- <li>Michael Goulish</li>
- <li>Nuno Santos</li>
- <li>Paul Fremantle</li>
- <li>Rafael Schloming</li>
- <li>Rajith Attapattu</li>
- <li>Robbie Gemmell</li>
- <li>Robert Godfrey</li>
- <li>Robert Greig</li>
- <li>Rupert Smith</li>
- <li>Steve Huston</li>
- <li>Ted Ross</li>
- <li>Yoav Shapira</li>
- </ul>
-
- <h2>Contributors</h2>
-
-
- <p>Many thanks to the following people for providing contributions:</p>
-
- <ul>
- <li>Colin Crist</li>
- <li>Bhupendra Bhardwaj</li>
- <li>Kevin Smith</li>
- <li>Steve Vinoski</li>
- <li>Steven Shaw</li>
- <li>Tomas Restrepo</li>
- </ul>
-
- <h2>Mentors</h2>
-
- <p>And many thanks to our project's mentors:</p>
-
- <ul>
- <li>Cliff Schmidt</li>
- <li>Craig Russell</li>
- <li>Paul Fremantle</li>
- <li>Yoav Shapira</li>
- <li>Scott Deboy</li>
- </ul>
-</div>
diff --git a/qpid/doc/website/content/qpid_integrated_with.html b/qpid/doc/website/content/qpid_integrated_with.html
deleted file mode 100644
index a2b53209c7..0000000000
--- a/qpid/doc/website/content/qpid_integrated_with.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
-
- <h1><a name="QpidIntegrations-AMQPintegrations"></a>AMQP integrations </h1>
-
- <ul>
- <li><a href="http://qpid.apache.org/archives/wiki/hermesjms.html" title="HermesJMS">HermesJMS</a> - The integration of Hermes JMS with Qpid</li>
- <li>Twisted AMQP - <a href="https://launchpad.net/txamqp" class="external-link" rel="nofollow">https://launchpad.net/txamqp</a></li>
- <li>Apache Camel - <a href="http://activemq.apache.org/camel/amqp.html" class="external-link" rel="nofollow">http://activemq.apache.org/camel/amqp.html</a></li>
- <li>Apache Axis2 Java - <a href="http://wso2.org/library/3663" class="external-link" rel="nofollow">http://wso2.org/library/3663</a></li>
-
- <li>Apache Axis2 C - <a href="http://ws.apache.org/axis2/c/docs/axis2c_manual.html#amqptrans" class="external-link" rel="nofollow">http://ws.apache.org/axis2/c/docs/axis2c_manual.html#amqptrans</a></li>
- <li>Apache Synapse</li>
- <li>libvirt - <a href="http://libvirt.org/" class="external-link" rel="nofollow">http://libvirt.org/</a> Provides QMF access to visualization</li>
- <li>Ovirt - <a href="http://ovirt.org/" class="external-link" rel="nofollow">http://ovirt.org/</a> QMFC - used to build management tools</li>
-
- <li>Python web plugin - Plug-in for AMQP support from web browser</li>
- <li>Red Hat MRG - <a href="http://redhat.com/mrg" class="external-link" rel="nofollow">http://redhat.com/mrg</a> Distro of Qpid with added management console and persistence</li>
- <li>Condor - <a href="http://www.cs.wisc.edu/condor/" class="external-link" rel="nofollow">http://www.cs.wisc.edu/condor/</a> QMF Agents and AMQP job routing</li>
- </ul>
-</div>
diff --git a/qpid/doc/website/content/qpid_project_etiquette_guide.html b/qpid/doc/website/content/qpid_project_etiquette_guide.html
deleted file mode 100644
index 7ce69c327a..0000000000
--- a/qpid/doc/website/content/qpid_project_etiquette_guide.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
-
-<h1>Qpid Project Etiquette Guide</h1>
-
-<h2><a name="QpidProjectEtiquetteGuide-Purpose"></a>Purpose</h2>
-
-<p>This guide, written by Rafael Schloming, gives both Qpid committers and submitters a useful introduction to project etiquette, shedding light on how we do things &amp; why. Following this etiquette makes the path to righteousness less long and winding !</p>
-
-<h2><a name="QpidProjectEtiquetteGuide-Maintainers"></a>Maintainers</h2>
-
-<p>The Qpid project consists of a number of major components spread across almost as many different languages. Thus it is rare for qpid committers to be experts in every single area of the project.</p>
-
-<p>As such it is expected that qpid committers make some effort to reach out to their teammates before directly modifying components that are outside their chosen areas. </p>
-
-<p>You should use the dev list to reach out to Qpid developers and comment on any JIRAs you're progressing.</p>
-
-<h2><a name="QpidProjectEtiquetteGuide-PatchSubmission"></a>Patch Submission</h2>
-
-<p>As a committer it can be difficult to decide whether/how to provide feedback when someone submits a patch. Often it is tempting to just fix up the patch and avoid the slower and sometimes awkward process of telling someone that they got some part of it wrong. </p>
-
-<p>However, it is necessary to ensure that those who submit patches get to learn what they need to know in order to become a valued qpid committer.</p>
-
-<p>In that spirit, here are a few guidelines for contributing patch submissions and how we handle them:</p>
-
-<ul>
- <li>Submitters should produce the final patch(s) as applied to the tree. Producing a patch that needs little or no rework is a key skill for a qpid committer.</li>
-
- <li>Maintainers may make requests for 'trivial' updates to the patch. Such requests are vital to ensuring that contributers get familiar with subtle yet important aspects of the code, stylistic conventions, etc.</li>
-
- <li>Make sure the submitter is familiar with project etiquette so they understand why we make seemingly trivial requests. We'll ask new contributers to read this etiquette info for that reason !</li>
-
- <li>A one-time patch from someone passing through may need nothing more than a polite thank you regardless of the content. If a submitter does aim for committership, best to make it plain you're planning to stay around on the project.</li>
-
- <li>Break up unrelated changes. It wouldn't be considered correct for a committer to glom together too many unrelated changes within a single commit, and so we won't commit this kind of patch from submitters.</li>
-
- <li>You need a JIRA for any patch to be attached to, which should accurately describe the change.</li>
-</ul>
-
-
-<h2><a name="QpidProjectEtiquetteGuide-BigIdeas"></a>Big Ideas</h2>
-
-<p>Every so often someone has a Big Idea that they get excited about and want to go do. They generally mail the list about it to give people the opportunity to comment, and then when nobody says anything they go off and do it.</p>
-
-<p>Fast forward six months later they commit/merge/enable/publish the result of their Big Idea, and suddenly everyone understands the full implications, and not everyone is happy. </p>
-
-<h3><a name="QpidProjectEtiquetteGuide-Guidelines"></a>Guidelines</h3>
-
-<p>So, here are a few guidelines for making sure this doesn't happen, starting with how to write a good proposal for a Big Idea:</p>
-
-<ul>
- <li>Make sure your proposal is recognizable as a proposal. An easy way to avoid ambiguity is to start a new thread for your proposal and stick &quot;proposal&quot; somewhere in the subject.</li>
-
- <li>Understand who and what your proposal effects, and make this clear. If you think X's implementation of Y doesn't deserve to live and you're going to rewrite the whole thing from scratch then make this very clear so X can object sooner rather than later.</li>
-
- <li>Make sure you call out loudly that you intend to kill feature A, even if you think no-one on earth should care.</li>
-
- <li>Even if you're going to write an Atari emulator, and you're 100% sure that it won't overlap with anything in the rest of the project, make sure you understand how and why it relates to the rest of the project in general, and make that clear.</li>
-
- <li>Be concrete. Often a proposal of the form &quot;hey, I did a little of this, here is a proof-of-concept, I'd like to do it for real now&quot; is far more effective than a proposal of the form &quot;hey, I have this vague idea about this, I'm going to vaguely suggest it would be good if someone did it&quot;.</li>
-
- <li>Talk about the long term implications of your proposal. If it's code then someone needs to maintain it, and committers will expect this to be you. Make clear your intentions.</li>
-
- <li>Never assume silence implies complicity, more likely it means people didn't understand the implications of your proposal, or didn't have time to figure out why they didn't like it. Ask again !</li>
-
- <li>The bigger your idea is, the more time and effort you should spend on the proposal, and ensuring that you get positive responses and deal with the comments and feedback provided in your actual implementation.</li>
-</ul>
-
-
-<h3><a name="QpidProjectEtiquetteGuide-Talkearly%2Ctalkoften"></a>Talk early, talk often</h3>
-
-<p>No matter how incredibly excellent your proposal is, there is going to need to be some discussion before the result of your Big Idea is blessed. Here are some things you can do to help that discussion go smoothly:</p>
-
-<ul>
- <li>Make frequent progress reports. Every hour/day/week/month you spend working without telling people what you're doing is an hour/day/week/month of your time that you risk wasting.</li>
-
- <li>Define milestones and make them visible to the rest of the project. Just like a concrete proof-of-concept can help a proposal, it helps to give people a concrete look at what you're doing while it's in progress. This can go a long way towards avoiding surprises.</li>
-</ul>
-
-<h3><a name="QpidProjectEtiquetteGuide-Andfinally....."></a>And finally .....</h3>
-
-<p>When the time does come to commit/merge/enable/publish your Big Idea, it really shouldn't be a surprise to anyone if you've followed the steps up until now, but make sure you let people know in advance by making note in your final few progress reports of when you expect to be finished, and sending a note to the dev list a day or so before you flip the big switch.</p>
-
-</div>
-
diff --git a/qpid/doc/website/content/release_notes_0.10.html b/qpid/doc/website/content/release_notes_0.10.html
deleted file mode 100644
index 5a93082b87..0000000000
--- a/qpid/doc/website/content/release_notes_0.10.html
+++ /dev/null
@@ -1,379 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>0.10 Release Notes</h1>
-
-<h3>Changes Requiring User Attention</h3>
-
-<ul>
- <li>The C++ broker now enables producer flow control by default. It is controlled via the default-flow-stop-threshold and default-flow-resume-threshold broker configuration parameters. See <a href="https://issues.apache.org/jira/browse/QPID-2935">QPID-2935</a>.</li>
- <li>In the C++ broker, when declaring an exchange with an unknown type or canceling a message on an unknown subscription, an exception with code 404 is created. See <a href="https://issues.apache.org/jira/browse/QPID-2324">QPID-2324</a> and <a href="https://issues.apache.org/jira/browse/QPID-2326">QPID-2326</a>.</li>
- <li>The C++ broker now enables QMF version 1 and 2 event broadcasts by default. Previously only QMF version 1 events were enabled.</li>
- <li>In the C++ broker, invalid arguments now result in a rejected queue-declare where previously they were ignored. See <a href="https://issues.apache.org/jira/browse/QPID-3087">QPID-3087</a>.</li>
- <li>The C++ client now raises an exception if it is issued connection options that it doesn't recognize. Previously it silently ignored them. See <a href="https://issues.apache.org/jira/browse/QPID-3115">QPID-3115</a>.</li>
-</ul>
-
-<h3>Resolved Issues</h3>
-
-<p>The full list of changes in the Qpid 0.10 release incorporates both the issues worked on during the 0.9 development stream and any final touches made during the 0.10 release process. A list of these JIRA issues can be found below.</p>
-
-<h4>New Feature</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-529'>QPID-529</a>] - Support message priority
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1916'>QPID-1916</a>] - Maven artifacts for the client
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2777'>QPID-2777</a>] - Additional bindings for the C++ messaging API (Python, Ruby)
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2934'>QPID-2934</a>] - Feature to pass the authenticated userId to QMF agent method handlers for authorization
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2935'>QPID-2935</a>] - Support &quot;best effort&quot; producer flow control within the AMQP 0.10 implementation.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3002'>QPID-3002</a>] - Configurable queue depth alerts
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3009'>QPID-3009</a>] - Perl binding to Qpid messaging
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3015'>QPID-3015</a>] - object creation and deletion via management
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3031'>QPID-3031</a>] - Allow C++ messaging client to specify SSL cert-name in connection
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3046'>QPID-3046</a>] - QMFv2 Completion and Cleanup
-</li>
-</ul>
-
-
-<h4>Bug</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1608'>QPID-1608</a>] - getCurrent method in FailoverPolicy returns null even when a FailoverMethod is present
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1670'>QPID-1670</a>] - Errors thrown from onMessage can kill the dispatcher
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1672'>QPID-1672</a>] - Inter-broker links need full SASL support
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2324'>QPID-2324</a>] - message_cancel should throw 404 not-found exception if subscription does not exist
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2326'>QPID-2326</a>] - exchange.declare should throw a 404 - not found exception if the exchange type is unknown
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2486'>QPID-2486</a>] - cannot move messages onto a durable subscription backing queue using the JMX Management Console
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2499'>QPID-2499</a>] - Stale federation routes remain after route deletion.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2546'>QPID-2546</a>] - QMF: ruby and python bindings need event support
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2900'>QPID-2900</a>] - CommitRollbackTest#testGetThenRollback and CommitRollbackTest#testSend2ThenRollback fail on java.0.10 profile
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2902'>QPID-2902</a>] - LargeMessageTest fails on java.0.10 test profiles
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2930'>QPID-2930</a>] - JMS msg.getPropertyNames() method should not return x-amqp-0-10.routing-key
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2933'>QPID-2933</a>] - Messaging .NET binding has several assembly properties misnamed
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2944'>QPID-2944</a>] - QMan readme is not included in the release package and contains incorrect URL.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2949'>QPID-2949</a>] - broker prompts console interactively for password when --auth=no
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2951'>QPID-2951</a>] - QMF: C++ example agent needs to be properly integrated into the release distribution.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2952'>QPID-2952</a>] - Qpid Cpp Messaging .NET Binding - Address constructor mishandles Name and Type fields
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2954'>QPID-2954</a>] - Dummy queue naming error for transcation test
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2956'>QPID-2956</a>] - cluster broker exits with &quot;error deliveryRecord no update message.&quot;
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2957'>QPID-2957</a>] - Management methods on the broker don&#39;t work on newly created objects
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2959'>QPID-2959</a>] - Java client null pointer exception thrown when there is no exchange set for ReplyTo
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2963'>QPID-2963</a>] - doxygen-generated C++ docs lost CSS references
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2977'>QPID-2977</a>] - Updated pom files for slf4j
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2979'>QPID-2979</a>] - The following SASL mechanisms [PLAIN] specified by the client are not supported by the broker
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2982'>QPID-2982</a>] - Inconsistent management messages in a cluster with federation routes
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2989'>QPID-2989</a>] - .NET Cpp Messaging Binding - Example program file is misnamed
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2991'>QPID-2991</a>] - Add message counts for both directions to connection stats
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2994'>QPID-2994</a>] - transactions atomicity violated by &#39;transparent&#39; failover
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2996'>QPID-2996</a>] - qmf/SchemaMethod.cpp fails to compile on s390
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2997'>QPID-2997</a>] - C++ broker creates duplicate management objects under rapid create/delete/create scenarios.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2998'>QPID-2998</a>] - Spurious declarations in qpid::messaging::Session
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2999'>QPID-2999</a>] - isRedelivered is not set on messages replayed by sender
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3001'>QPID-3001</a>] - Add const declaration to Connection::isOpen()
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3006'>QPID-3006</a>] - Broken acl check on link close
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3007'>QPID-3007</a>] - Inconsistent management messages in a cluster, test fails sporadically
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3010'>QPID-3010</a>] - broker uses the MINA PooledByteBufferAllocator instead of the SimpleByteBufferAllocator
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3011'>QPID-3011</a>] - NPE thrown when using a custom exchange in a replyTo address.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3014'>QPID-3014</a>] - an inbalance in use of the CurrentActor stack holds 0-10 connections in memory after they are closed
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3016'>QPID-3016</a>] - Java JMS client ReplyTo memory leak
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3019'>QPID-3019</a>] - Exception not reported properly when creating a Producer with an invalid destination
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3020'>QPID-3020</a>] - an inbalance in use of the CurrentActor stack holds 0-10 subscriptions in memory after they are closed
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3021'>QPID-3021</a>] - the Session and Connector actors should be set for events occurring on 0-10 connections
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3022'>QPID-3022</a>] - status logging tests are disabled and/or failing on Java 0-10 test profile
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3028'>QPID-3028</a>] - Java broker uses excessive amounts of memory to service 0-10 connections
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3029'>QPID-3029</a>] - Java broker claims to support 2^16 channels per connection when it doesn&#39;t
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3030'>QPID-3030</a>] - C++ buffer encoding allows overflow on write.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3033'>QPID-3033</a>] - Bug 674183 - Segmentation fault while processing session.attach
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3035'>QPID-3035</a>] - Removing a sequence number from a SequenceSet can corrupt the sequence.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3040'>QPID-3040</a>] - Closed Receivers Do Not Delete Queues and Do Not Reroute Acquired Messages to Alternate Exchange
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3042'>QPID-3042</a>] - Session.attach could be sent before the connection is open.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3043'>QPID-3043</a>] - If a new session is created during failover, but before &#39;resume&#39; is completed, the new session gets reattached again.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3045'>QPID-3045</a>] - Sporadic failure of cluster_tests.ShortTests.test_route_update
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3047'>QPID-3047</a>] - The QueueDepthWithSelectorTest fails on 0-10 profiles
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3048'>QPID-3048</a>] - InternalBrokerBasecase not removing all log actors
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3049'>QPID-3049</a>] - qpid-send --durable does not send durable messages.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3050'>QPID-3050</a>] - JMS client producer option -Dsync_publish=persistent has no effect
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3051'>QPID-3051</a>] - Reject can fail to restore message credit
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3053'>QPID-3053</a>] - QMFv2 events disabled by default
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3058'>QPID-3058</a>] - Windows installer doesn&#39;t package qpidtypes, qpidmessaging, or dotnet bindings
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3060'>QPID-3060</a>] - QMF Console (console.py) uses the wrong user-id to annotate messages sent
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3063'>QPID-3063</a>] - Python Client messaging/endpoints.py Connection Class: def check_closed(self): method crashes when called.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3065'>QPID-3065</a>] - Send header and frame data as single buffer
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3068'>QPID-3068</a>] - Some Windows-related files not packaged in release
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3069'>QPID-3069</a>] - C++ cmake build assumes presence of dotnet binding source
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3072'>QPID-3072</a>] - Producer flow control does not work properly in a clustered broker configuration.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3077'>QPID-3077</a>] - cpp INSTALL-WINDOWS errors, inconsistencies, improvements
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3078'>QPID-3078</a>] - qpid-receive&#39;s use of the &quot;-t&quot; option is ambiguous and will cause the command to fail.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3082'>QPID-3082</a>] - Add qmf-tool to the qpid/tools/setup.py distribution file.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3084'>QPID-3084</a>] - Cluster may hang during update if asynchronous completion is pending.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3087'>QPID-3087</a>] - Bad handling of invalid queue arguments
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3090'>QPID-3090</a>] - JMX ObjectName name may not match the underlying managed object
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3091'>QPID-3091</a>] - Can&#39;t specify arbitrary arguments for queue-declare in qpid-config
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3092'>QPID-3092</a>] - JMX Management Console does not expose VirtualHost attributes
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3094'>QPID-3094</a>] - unable to delete durable subscription backing queues using the JMX Management Console
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3099'>QPID-3099</a>] - Java qpid-client ignores hostnames containing underscores
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3100'>QPID-3100</a>] - Excessive memory use per-connection
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3101'>QPID-3101</a>] - qpid-tool does not allow maps to be passed as arguments
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3102'>QPID-3102</a>] - messaging API produces messages with ttl=0 by default
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3103'>QPID-3103</a>] - qpid-config doesn&#39;t handle null arguments for queues/exchanges
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3105'>QPID-3105</a>] - Alternate-Exchange configuration not communicated between nodes in a cluster
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3106'>QPID-3106</a>] - QueueReceiver and TopicSubscriber does not work with new addressing
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3107'>QPID-3107</a>] - Messages following a queue&#39;s Alternate-Exchange do not follow the exchange&#39;s Alternate-Exchange
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3108'>QPID-3108</a>] - QueueSender incorrectly checks for null queue
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3110'>QPID-3110</a>] - JMX Management console does not show aggregate virtual host notifications
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3116'>QPID-3116</a>] - rubygen with ruby 1.9
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3118'>QPID-3118</a>] - cpp/examples/CMakeLists.txt tries to install non-existant files
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3120'>QPID-3120</a>] - Queue reroute doesn&#39;t honor alternate exchange
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3121'>QPID-3121</a>] - Cluster management inconsistency when using persistent store.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3122'>QPID-3122</a>] - backward compatibility problem with 0.9 agents
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3127'>QPID-3127</a>] - Accept mode should be NONE for 0-10 NO_ACKNOWLEDGE subscriptions
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3130'>QPID-3130</a>] - slow codec
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3132'>QPID-3132</a>] - Threshold alert on a queue used to receive alerts causes broker crash
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3135'>QPID-3135</a>] - cpp/bld-winsdk.ps1 tries to install non-existant files
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3137'>QPID-3137</a>] - old examples are installed incorrectly
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3144'>QPID-3144</a>] - qpidd --check does not work with info logging and --log-to-stdout=yes
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3147'>QPID-3147</a>] - Misconfigured tracing/logging can lead to hung threads in logging stack
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3150'>QPID-3150</a>] - sasl_fed test fails to specify client&#39;s sasl mechanism
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3152'>QPID-3152</a>] - non-clustered sasl_fed_ex_* tests load cluster.so
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3154'>QPID-3154</a>] - Fix qpidd late/overran warnings.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3169'>QPID-3169</a>] - qpid-route tool should output usage info if bad/unknown command entered.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3174'>QPID-3174</a>] - broker crash using rdma+sasl
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3176'>QPID-3176</a>] - 0.10 RC2 cpp dist missing examples/old_api/CMakeLists.txt
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3177'>QPID-3177</a>] - JMS Failover Not Working
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3185'>QPID-3185</a>] - Wrong help text for qpid-config
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3192'>QPID-3192</a>] - .NET Binding for Messaging classes are missing intrinsic copy contructors
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3197'>QPID-3197</a>] - C++ Broker crashes on persistence-based stress tests.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3199'>QPID-3199</a>] - Severe but difficult to diagnose lock error in qpid::sys::StateMonitor
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3221'>QPID-3221</a>] - Fix bug in Cluster::timerDrop - calling wrong function
-</li>
-</ul>
-
-
-<h4>Improvement</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2104'>QPID-2104</a>] - Improved LVQ implementation
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2505'>QPID-2505</a>] - WCF project needs to encode/decode all AMQP data types
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2921'>QPID-2921</a>] - c++ broker: Improvements to asynchronos completion
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2939'>QPID-2939</a>] - Qpid .NET Messaging Binding has stray references and using statements
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2958'>QPID-2958</a>] - Qpid Cpp Messaging .NET Binding library should use Framework v2.0 and not v3.5
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2966'>QPID-2966</a>] - Provide mechanism to alter brokers logging level at runtime
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3000'>QPID-3000</a>] - Support optional timeout before auto-deleting queues
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3032'>QPID-3032</a>] - QMFv2 - Allow endpoints to be directly addressed via a topic exchange
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3039'>QPID-3039</a>] - explicitly define the included debug info instead of relying on defaults which can differ between compilers
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3057'>QPID-3057</a>] - New Visual Studio solution to build org.apache.qpid.messaging.sessionreceiver separately
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3067'>QPID-3067</a>] - Example structure is misleading (c++ examples)
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3073'>QPID-3073</a>] - Producer flow control need performance tuning.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3081'>QPID-3081</a>] - Maintain a per-queue counter for flow control state change
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3089'>QPID-3089</a>] - add method/function to get a descriptive string for VariantType enumeration
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3097'>QPID-3097</a>] - Adapt installer to rearranged C++ examples
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3098'>QPID-3098</a>] - Java client does not support java.util.UUID in a Map message
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3109'>QPID-3109</a>] - Java client needs to implement the Delete option in address string
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3115'>QPID-3115</a>] - Differences in connection options between c++ and python clients
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3124'>QPID-3124</a>] - Update release script for new build artifacts
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3128'>QPID-3128</a>] - Update CPP broker documentation with producer flow control user api.
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3136'>QPID-3136</a>] - Add option to disable defaults for queue threshold alerts
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3151'>QPID-3151</a>] - Remove dotnet and ruby from the --all release artifacts
-</li>
-</ul>
-
-
-<h4>Wish</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1688'>QPID-1688</a>] - Need more powerful search functionality
-</li>
-</ul>
-
-
-<h4>Sub-task</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2680'>QPID-2680</a>] - Provide user documentation for configuring SCD
-</li>
-</ul>
-
-
-<h4>Task</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3017'>QPID-3017</a>] - Add unit tests and improve error handling for classes within org.apache.qpid.server.txn
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3054'>QPID-3054</a>] - Remove unused old tests from java/systests/src/old_test
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3056'>QPID-3056</a>] - remove unused SSL cert in java/common/src/main/resources
-</li>
-</ul>
-
-
-<h4>Test</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3012'>QPID-3012</a>] - ConnectionCloseTest creates an extreme number of connections
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3013'>QPID-3013</a>] - ConnectionCloseTest fails on machines with increased processor counts
-</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3023'>QPID-3023</a>] - logging tests unnecessarily use an InternalBrokerBaseCase to load configuration for test comparison
-</li>
-</ul>
-
-<h3>Known Issues</h3>
-
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3182'>QPID-3182</a>] - Node bindings not established correctly when address used for producer
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3214'>QPID-3214</a>]* - Deadlock between the failover mutex (in AMQConnection.java) and the current_exception_lock (in AMQSession.java)
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-3216'>QPID-3216</a>]* - Deadlock between "_lock" (in AMQSession#DisptcherThread) and "_messageDeliveryLock" (in AMQSession.java)
-</ul>
-
-<p>*Although these deadlocks are present in the release, the changes
-that are known to trigger them were committed post-release. Therefore
-the likelihood of these deadlocks appearing in the 0.10 release is
-slim.</p>
-
-</div>
diff --git a/qpid/doc/website/content/release_notes_0.8.html b/qpid/doc/website/content/release_notes_0.8.html
deleted file mode 100644
index 2e0bb1fd7a..0000000000
--- a/qpid/doc/website/content/release_notes_0.8.html
+++ /dev/null
@@ -1,437 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>0.8 Release Notes</h1>
-
-<p>The full list of changes in the Qpid 0.8 release incorporates both the issues worked on during the 0.7 development stream and any final touches made during the 0.8 release process. A list of these JIRA issues can be found below.</p>
-
-<h3>JIRA Issues</h3>
-
-<h4>New Feature</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-664'>QPID-664</a>] - High-level C++ client API.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1403'>QPID-1403</a>] - Add SSL support for C++ Windows broker/client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1940'>QPID-1940</a>] - QMF Feature Request - Structured exceptions for method failure</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2321'>QPID-2321</a>] - [Java Broker] Add "conflation queue" to Java Broker</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2363'>QPID-2363</a>] - JMS Map Message Should Support AMQP 0-10 Encoded Map As Message Body</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2365'>QPID-2365</a>] - Reroute messages on a queue - remove messages from a queue and send them to an exchange</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2412'>QPID-2412</a>] - Support for SASL EXTERNAL when using SSL</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2500'>QPID-2500</a>] - Transport security for the WCF channel</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2555'>QPID-2555</a>] - Qpid Info OSGI plugin</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2581'>QPID-2581</a>] - Create a ConfigurationManager to allow plugins to provide configuration handling classes</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2589'>QPID-2589</a>] - Add a .NET binding to QPID Messaging API</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2614'>QPID-2614</a>] - QueueConfiguration requires to configurations to be provided on construction</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2646'>QPID-2646</a>] - Qpid Messaging address support for WCF Channel</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2700'>QPID-2700</a>] - Ability to remove queue binding in QPID</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2807'>QPID-2807</a>] - More flexible acknowledgement</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2867'>QPID-2867</a>] - enable the JMX management console to remove bindings from direct/topic exchanges</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2909'>QPID-2909</a>] - Hybrid SQL-CLFS persistence store for C++ broker on Windows</li>
-</ul>
-
-<h4>Bug</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1662'>QPID-1662</a>] - TimeToLiveTest.testPassive occasionally receives more messages.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1879'>QPID-1879</a>] - The client library uses a new thread for every connection</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1904'>QPID-1904</a>] - Timestamps are incorrect</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2137'>QPID-2137</a>] - StringIndexOutOfBounds when formating Connection Message during failed systest run.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2165'>QPID-2165</a>] - MINANetworkDriverTest fails to socket already in use</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2173'>QPID-2173</a>] - Java client should set the process ID in the client properties during Connection open</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2174'>QPID-2174</a>] - When kerberos auth is used, Java client should use the kerberos userid &amp; domain when setting the userid in messages</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2186'>QPID-2186</a>] - Windows - "vector iterator not dereferencable"</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2262'>QPID-2262</a>] - Random test failures in SimpleACLTest</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2265'>QPID-2265</a>] - Ruby Rakfile References an old file</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2297'>QPID-2297</a>] - ACL policy won't allow "." in the realm for users added to a group</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2298'>QPID-2298</a>] - CMake-based install based on released sources tries to include generated headers from build tree</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2299'>QPID-2299</a>] - C++ Messaging drain and spout examples need vcproj files</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2300'>QPID-2300</a>] - C++ packaging directory not included in release</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2301'>QPID-2301</a>] - C++ examples changed at r880718; obsolete vcproj files not removed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2302'>QPID-2302</a>] - Missing header.html, footer.html in C++ docs/api distribution</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2306'>QPID-2306</a>] - C++ uninstaller does not uninstall some header files.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2318'>QPID-2318</a>] - qpid-tool does not seem to issue session acknowledgements </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2320'>QPID-2320</a>] - Failed acquire on LVQ causes broker crash</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2323'>QPID-2323</a>] - Add uuid to variant</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2325'>QPID-2325</a>] - [Java Broker] SASL PLAIN authentication does not work when both an authentication and authorization id are supplied</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2328'>QPID-2328</a>] - Querying for 500 objects causes C++ based ruby console to hang</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2336'>QPID-2336</a>] - Cannot disable heatbeats in JMS client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2338'>QPID-2338</a>] - [C++ Broker] Ring queue does not properly implement byte size limits</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2339'>QPID-2339</a>] - JMS (0-10 client) does not verify if it supports the SASL mechanisms sent by the broker.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2340'>QPID-2340</a>] - [Java] ProducerFlowControlTest failing due to race condition in test</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2344'>QPID-2344</a>] - qpid/messaging/uuid.h r899657 breaks Windows build...</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2347'>QPID-2347</a>] - Subscribers are never notified if queue is deleted from under them</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2355'>QPID-2355</a>] - QMF bindings build conflicts with installed qmf headers</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2360'>QPID-2360</a>] - declaring virtualhost level firewall configuration in virtualhosts.xml leads to NPE on startup</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2361'>QPID-2361</a>] - exchange configuration attributes are ignored when configuration is placed in virtualhosts.xml</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2366'>QPID-2366</a>] - Windows C++ broker port written to stdout at startup is wrong</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2370'>QPID-2370</a>] - TTR-Qpid-07-NA failed due to channel error 504 during tear down</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2372'>QPID-2372</a>] - PeriodicTimerImpl addition broker Windows build</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2374'>QPID-2374</a>] - qpidd: --require-encryption with "--auth no" will reject SSL connections as being "un-encrypted" </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2376'>QPID-2376</a>] - C++ broker build broken at 20:00 Thurs Jan 28, 2010</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2378'>QPID-2378</a>] - WCF/C++ Client subtree lacks Apache licensing files</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2387'>QPID-2387</a>] - qpidd does not replicate management agent lists, causes brokers to exit. </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2388'>QPID-2388</a>] - user-defined signals can cause process terminate</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2392'>QPID-2392</a>] - Powershell scripts not included in release source kits</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2395'>QPID-2395</a>] - fd leak in Connection</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2398'>QPID-2398</a>] - C++ examples' Visual Studio projects need BOOST_ALL_DYN_LINK to build against installed kit</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2406'>QPID-2406</a>] - Consistent approach to durations in qpid::messaging api</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2407'>QPID-2407</a>] - C++ SSL session can get bad buffer management</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2413'>QPID-2413</a>] - ACL - error handling/bounds checking</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2418'>QPID-2418</a>] - Existing durable subscription with selector is not unsubscribed during change to new subscription</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2420'>QPID-2420</a>] - Windows SQL-based persistence loses prepared two-phase transactions on broker restart</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2422'>QPID-2422</a>] - DerbyStore does not persist queue exclusivity or arguments</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2426'>QPID-2426</a>] - Better error message and logging when receving/sending from/to empty address</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2427'>QPID-2427</a>] - Modify browse option in-line with path chosen for python client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2428'>QPID-2428</a>] - qpid.subject should be set on outgoing messages if the address specifies a suject</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2429'>QPID-2429</a>] - headers exchange does not match correctly on a map entry with a null value</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2430'>QPID-2430</a>] - Java broker emits NPE following qpid-tool being connected</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2431'>QPID-2431</a>] - .NET csproj files missing Apache license text</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2433'>QPID-2433</a>] - qpid-server.bat fails if the path contains a space character</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2434'>QPID-2434</a>] - make clean in qpid/cpp/src/tests/testagent breaks build</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2435'>QPID-2435</a>] - Deadlock can occur during the registration of a qmf agent</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2437'>QPID-2437</a>] - Define exceptions for messaging API</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2438'>QPID-2438</a>] - Performance tests do not correctly populate the message with the given MessageSize</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2439'>QPID-2439</a>] - CMake builds broken 08-Mar-2010</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2441'>QPID-2441</a>] - make check fails because of wrong sorting</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2444'>QPID-2444</a>] - JMS client does not verify that the hostname connected to matches that specified in the servers certificate</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2445'>QPID-2445</a>] - JMS Client needs to extract the user ID from the external auth mechanism when SASL EXTERNAL is used</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2452'>QPID-2452</a>] - Inconsistent handling on strings between C++ and Python messaging APIs</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2463'>QPID-2463</a>] - C++ install step puts api docs in wrong place on Windows</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2465'>QPID-2465</a>] - Ant 1.8.x javac task prints warning message during builds</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2467'>QPID-2467</a>] - Windows install doesn't include qpidxarm.dll or broker plugins</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2468'>QPID-2468</a>] - WCF client samples can't resolve the DLLs when installed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2471'>QPID-2471</a>] - Java client releases messages in an unpredictable order on recover</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2472'>QPID-2472</a>] - QpidCompositeRollingAppender log4j configuration is misleading</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2474'>QPID-2474</a>] - ACL file reader can trip vector iter validity checking</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2475'>QPID-2475</a>] - qpid/messaging/Session.h r928855 breaks Windows build - macro conflict</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2481'>QPID-2481</a>] - Deadlock in Qpid 0.6</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2482'>QPID-2482</a>] - Topic Exchange can duplicate messages.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2484'>QPID-2484</a>] - Interoperability tests fail due to attempts to print out contents of JMS Message objects, and do not parse command line properies</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2487'>QPID-2487</a>] - Tearing down one dynamic route may delete other independent routes in the federation.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2488'>QPID-2488</a>] - ACL - error handling/bounds checking</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2493'>QPID-2493</a>] - AMQPEncodedMapMessage does not support nested maps and lists</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2497'>QPID-2497</a>] - messaging api silently ignores unrecognised/invalid address options</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2502'>QPID-2502</a>] - securityTracker open() call is made on exchangeTracker instance instead</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2503'>QPID-2503</a>] - CommandLineParser does not print '-' when showing options</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2506'>QPID-2506</a>] - QMF: fix encoding/decoding of map and list method call arguments</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2507'>QPID-2507</a>] - C++ broker can deadlock when processing a bind.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2511'>QPID-2511</a>] - ConnectionImpl instance may be deleted before IO threads are finished with the underllying DispatchHandle</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2515'>QPID-2515</a>] - Need to be able to set flow control in Java on a per destination level</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2520'>QPID-2520</a>] - Broken POM generation on Windows</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2521'>QPID-2521</a>] - ACL module core dumps if management is disabled</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2523'>QPID-2523</a>] - When reloading a large acl file while acl lookup is in progress, the broker core dumps</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2526'>QPID-2526</a>] - Ant build fails if the path contains a space character</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2553'>QPID-2553</a>] - CMakeLists wrong file name </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2558'>QPID-2558</a>] - client connection.open to a non-broker on qpid 0.6 windows segfaults with: access violation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2561'>QPID-2561</a>] - Download page does not follow ASF standards</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2562'>QPID-2562</a>] - website does not have any links to the Issue tracker</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2563'>QPID-2563</a>] - Website does not have required ASF elements</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2564'>QPID-2564</a>] - Wcf functional test source file is absent</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2570'>QPID-2570</a>] - Broker uses NotAllowedException for ACL violations, should use UnauthorisedAccessException</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2587'>QPID-2587</a>] - PollableCondition test fails on Windows</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2600'>QPID-2600</a>] - ACL policy doesn't permit certain characters in usernames added to groups</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2605'>QPID-2605</a>] - Recovered messages larger than 65523 bytes result in framing violation ()</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2607'>QPID-2607</a>] - Package name typo for CRAMMD5HexInitialiserTest.java</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2608'>QPID-2608</a>] - AMQPException messages contain duplicate AMQConstant text</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2609'>QPID-2609</a>] - MockAMQQueue does not implement getName</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2610'>QPID-2610</a>] - AMQConstant Map usage is not correct</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2611'>QPID-2611</a>] - AMQConnectionFailureException does not record reason for underlying cause if it is an AMQPException</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2612'>QPID-2612</a>] - Recent DLL qpidtypes breaks the build on Windows</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2613'>QPID-2613</a>] - message data is not commited to the persistent store on 0-8/0-9 codepath</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2615'>QPID-2615</a>] - JMX Management Console fails to connect to 0.5 and below brokers if run in a Java5 VM</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2626'>QPID-2626</a>] - Typo in ServerConnectionDelegate</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2631'>QPID-2631</a>] - Race in qpid::client::Bounds causes (rare) deadlock</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2634'>QPID-2634</a>] - CRLF line endings in the shell scripts</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2635'>QPID-2635</a>] - Ant tests fail with OutOfMemoryError due to PermGen space exhaustion</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2636'>QPID-2636</a>] - disconnect() callback on broker results in leaked connections</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2637'>QPID-2637</a>] - connection.start() hangs if the connection is not accepted</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2640'>QPID-2640</a>] - options string for connection does not work for some types</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2641'>QPID-2641</a>] - The bitwise AND operator used instead of logical AND in QpidLog4JConfigurator.java</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2642'>QPID-2642</a>] - The bitwise AND operator used instead of logical AND in QpidLog4JConfigurator.java</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2644'>QPID-2644</a>] - Console examples sometimes fail due to not waiting for the broker connection to complete</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2647'>QPID-2647</a>] - Typo in str8-latin type definition for 0-10</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2649'>QPID-2649</a>] - Segfault on shutting down qpidd</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2650'>QPID-2650</a>] - DerbyStore only ever uses auto-commit connections</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2653'>QPID-2653</a>] - Double checked locking in org.apache.qpid.server.transport.ThreadPoolFilter</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2654'>QPID-2654</a>] - Access control plugin should use Actor logging</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2657'>QPID-2657</a>] - Verify/correct error handling on client 0-10 codepath</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2658'>QPID-2658</a>] - Update Java 0-10 profile excludes</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2661'>QPID-2661</a>] - The 0-8 BasicGetMethodHandler should return NOT_IMPLEMENTED for 0-10 messages</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2662'>QPID-2662</a>] - The FirewallPlugin should accept a ServerSocket, not the string representation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2665'>QPID-2665</a>] - Remove BROKER from object types for plugins</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2668'>QPID-2668</a>] - PlainPasswordPrincipalDatabase - code improvement </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2670'>QPID-2670</a>] - Concurrent tagging of message with trace id while message is delivered from another queue causes segfault</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2673'>QPID-2673</a>] - retained 0-10 ImplicitAcceptDispositionChangeListener objects can lead to connection closure timeout and broker OOM</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2674'>QPID-2674</a>] - heartbeats can cause seg faults under tcp on linux</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2677'>QPID-2677</a>] - QMF: console.py sends agent locate request before it has enabled receiving data indications.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2686'>QPID-2686</a>] - Update Ant doc task with better configuration</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2687'>QPID-2687</a>] - The PluginManager does not auto-deploy bundles properly</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2688'>QPID-2688</a>] - Exclusive queues deleted before unacked messages are requeued; unacked messages not routed to alternate-exchange as a result.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2691'>QPID-2691</a>] - ttl is lost for federation routes where trace id is added</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2694'>QPID-2694</a>] - Memory leak in 0-8/0-9 AMQSessions on channel close</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2695'>QPID-2695</a>] - VirtualHostConfigRecoveryHandler can NPE or bind to the wrong exchange on binding recovery</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2696'>QPID-2696</a>] - Addressing strings in the jndi properties file is interpreted as binding urls</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2697'>QPID-2697</a>] - AMQConnectionURL options do not appear in the toString representation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2698'>QPID-2698</a>] - Certain amqp 0-10 message properties are not exposed through messaging apis message class</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2702'>QPID-2702</a>] - --max-connections not work when using cluster</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2704'>QPID-2704</a>] - Provide scavenge() for SimpleQueueEntryList - TRUNK MERGE</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2706'>QPID-2706</a>] - Visual Basic example includes a directory whose name contains a space</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2707'>QPID-2707</a>] - Cmake build doesn't output all needed settings to build a valid shared library name for loading</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2716'>QPID-2716</a>] - QMF: c++ agent does not set the agent name attribute in an object id during addObject() call.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2718'>QPID-2718</a>] - Update the common.bnd to match client.bnd, release version</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2719'>QPID-2719</a>] - Some SSL errors do not get reported up the stack or in the log file.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2722'>QPID-2722</a>] - The JMS 0-10 client does not make use of the subject specified via "qpid.subject" in the application properties.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2723'>QPID-2723</a>] - NullPointerException thrown when you pass an address based destination to the setJMSReplyTo() in a Message.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2724'>QPID-2724</a>] - Docbook generation is fixed on xsl-stylesheets-1.75.2 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2727'>QPID-2727</a>] - ./src/qpidd --load-module ./src/.libs/cluster.so --cluster-name blah --known-hosts-url amqpx:blah segfaults</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2728'>QPID-2728</a>] - Windows icon/version additions broke nightly builds</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2734'>QPID-2734</a>] - testAuthenticatedUsername fails on cmake builds</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2735'>QPID-2735</a>] - If no subject is specified and if the exchange type is topic, "#" should be used as the default. </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2741'>QPID-2741</a>] - DerbyMessageStore is not shut down when told to close</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2742'>QPID-2742</a>] - DerbyMessageStore createExchange() method does not function</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2744'>QPID-2744</a>] - FieldTable throws a NullPointerException in setObjectProperty rather than expected AMQPInvalidClassException</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2749'>QPID-2749</a>] - [Java Broker] Add -XX:+ExplicitGCInvokesConcurrent to qpid-server[.bat]</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2752'>QPID-2752</a>] - Cannot create LVQ's using the JMS client.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2754'>QPID-2754</a>] - C++ broker crashes due to management object database corruption</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2755'>QPID-2755</a>] - Windows SDK has no README</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2757'>QPID-2757</a>] - Remove double-checked-locking in ThreadPoolFilter</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2758'>QPID-2758</a>] - Remove call to Thread.run() in FirewallPlugin</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2760'>QPID-2760</a>] - Only client 0-10 session sync should throw any exceptions</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2764'>QPID-2764</a>] - WinSdk cpp examples do not compile</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2766'>QPID-2766</a>] - string to double conversion results in questionable precision</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2769'>QPID-2769</a>] - UnexpectedMethodException is serializable but does not implement serialVersionUID</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2774'>QPID-2774</a>] - Incorrect logic when querying for existance of an exchange while parsing an address string.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2781'>QPID-2781</a>] - QPBRKR process name tag should be declared in qpid-server script, not qpid-run</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2785'>QPID-2785</a>] - QpidTypes.pdb is not installed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2786'>QPID-2786</a>] - Cannot create a durable subscription using a destination created with an addressing string</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2788'>QPID-2788</a>] - jmx management console can throw ConcurrentModificationException whilst connected to (older) brokers with MBeans actively (un)registering</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2791'>QPID-2791</a>] - QMF: c++ agent publishes all data object updates in a single message.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2797'>QPID-2797</a>] - Add an extra boolean to 0-10 session to indicate closing</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2798'>QPID-2798</a>] - C++ Messaging Client .NET binding fails to clone managed objects correctly</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2799'>QPID-2799</a>] - Temporary queue names should be more meaningful</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2805'>QPID-2805</a>] - The windows resource version for qmfengine dll is hard coded to an unusable value</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2806'>QPID-2806</a>] - QMF: python console will incorrectly delete agents if the session is configured with rcvHeartbeats=False</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2810'>QPID-2810</a>] - QMF: python console does not properly shutdown broker thread in some error cases.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2817'>QPID-2817</a>] - Connection::close() may hang if broker is suspended</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2828'>QPID-2828</a>] - jmx management console can NPE when adding a queue to the navigation tree after its MBean has just been unregistered but before the view is refreshed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2842'>QPID-2842</a>] - references to other objects in qpid-tool use id that doesn't match anything else</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2844'>QPID-2844</a>] - JMS client should use the exchange given in the address if the exchange name is not explicitly given in x-bindings </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2845'>QPID-2845</a>] - JMS client should allow arbitary arguments map in the x-bindings section</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2846'>QPID-2846</a>] - QMF: python console crashes on race condition when deleting an agent.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2851'>QPID-2851</a>] - Programming with Apache Qpid doc confusing over confirmations</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2854'>QPID-2854</a>] - [Java Broker] 0-10 Queue Exclusive behaviour not correctly implemented</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2855'>QPID-2855</a>] - [Java Broker] 0-10 Transport should not block on awaiting for close confirmation from client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2856'>QPID-2856</a>] - [Java Broker] Should send 530 not-allowed exception onattempt to delete a defautl exchange (e.g. amq.direct, amq.topic)</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2857'>QPID-2857</a>] - [Java] Running FindBugs against Java codebase reveals room for improvement</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2860'>QPID-2860</a>] - C++ hello_xml example receives all message content, not just what's wanted</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2861'>QPID-2861</a>] - JMS client needs to handle duplicate commands replayed after failover</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2868'>QPID-2868</a>] - throw exception users when attempt is made to move/copy messages to a non-existent queue</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2869'>QPID-2869</a>] - prevent specifying the souce queue as destination when moving/copying messages</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2870'>QPID-2870</a>] - an unauthorised attempt to delete a queue will prevent all further deletion attempts</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2872'>QPID-2872</a>] - Java broker incorrectly indicates it supports sending 0-10 heartbeats when it currently does not</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2875'>QPID-2875</a>] - Federation route propagation tests fail occassionally.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2876'>QPID-2876</a>] - Design issues in Java client failover</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2877'>QPID-2877</a>] - QPID_JAVA_MEM usage in windows qpid-server.bat fails and prevents startup</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2879'>QPID-2879</a>] - The 0-10 Java Client is sending null arguments on messageSubscribe</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2880'>QPID-2880</a>] - QMF: C++ agent does not accept method calls with map/list arguments that contain booleans</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2883'>QPID-2883</a>] - QMF: python console does not pass V2-style events to the console callback</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2885'>QPID-2885</a>] - C++ qmf console shows memory leaks under valgrind.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2886'>QPID-2886</a>] - Address the issues outlined by findbugs on 0.5.x-dev branch</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2888'>QPID-2888</a>] - QMF: C++ agent does not re-publish all management data on reconnect to the broker.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2892'>QPID-2892</a>] - IBM JVM throws different exception when signal handler fails, stopping broker execution</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2896'>QPID-2896</a>] - Incorrect detection of data types in address parameters - C++ client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2898'>QPID-2898</a>] - broker is unable to evaulate "JMSMessageID IS NULL" correctly when using 0-10</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2910'>QPID-2910</a>] - Small fix for python timeout tests</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2914'>QPID-2914</a>] - address parser doesn't recognize None</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2915'>QPID-2915</a>] - Qpid Cpp Messaging .NET Binding does not properly handle Qpid type VAR_VOID</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2916'>QPID-2916</a>] - C++ broker &amp; Python client will silently truncate strings whose length is greater than the max length supported by the type.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2918'>QPID-2918</a>] - Assembly mis-named in csharp.example.declare_queues</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2919'>QPID-2919</a>] - hello_world, hello_xml examples left out of CMakeLists.txt</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2922'>QPID-2922</a>] - Qpid Cpp Messaging .NET Binding does not implement FailoverUpdate class</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2923'>QPID-2923</a>] - Qpid Messaging .NET Binding fails to translate exceptions from C++ to .NET</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2925'>QPID-2925</a>] - MSSQL-based message store throws uncaught exception if db recovery throws an error</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2926'>QPID-2926</a>] - Simple example code does not link under Windows</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2927'>QPID-2927</a>] - JMX Shutdown plugin throws InstanceNotFoundException during broker shutdown</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2928'>QPID-2928</a>] - Java client always create exclusive lock for the queue when use with the new addressing scheme</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2929'>QPID-2929</a>] - the broker-plugins jars are not incorporated into the broker release binary when using 'ant release-bin'</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2931'>QPID-2931</a>] - nulling the MessageReference handle on the Message during QueueEntry disposal can result in NPE</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2940'>QPID-2940</a>] - message-accept records are not cleaned up unless getUnsettledAcks() is called</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2941'>QPID-2941</a>] - CLFS store recovery can encounter invalid C++ iterator</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2948'>QPID-2948</a>] - Generated API docs have extraneous macro names in method signatures</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2950'>QPID-2950</a>] - DerbyMessageStore incorrectly logs an error for an expected exception indicating successfull database shutdown</li>
-</ul>
-
-<h4>Improvement</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1308'>QPID-1308</a>] - JMS Temprory Queue naming</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1447'>QPID-1447</a>] - Broker does not handle with slow consumers effectively</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1825'>QPID-1825</a>] - Improve TimeToLiveTest.testActive to prevent spurious failures</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1831'>QPID-1831</a>] - Improve JMS Destination abstraction to better support AMQP and Qpid specific features</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2213'>QPID-2213</a>] - qpid/framing/BodyHolder.* still needed?</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2251'>QPID-2251</a>] - Provide portable signal mechanism for the C++ QMF agent API</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2283'>QPID-2283</a>] - java Testkit scripts should have sensible defaults when setting up the environment</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2313'>QPID-2313</a>] - Release notes for the WCF/C++ client </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2322'>QPID-2322</a>] - remove redundant "version" key property from the ObjectName of the JMX MBeans</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2327'>QPID-2327</a>] - Enhance qpid-config to deal with xml and headers brokers</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2348'>QPID-2348</a>] - [C++] The HeadersExchange does not support federation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2351'>QPID-2351</a>] - Allow the following config properties to be set in the ConnectionURL</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2371'>QPID-2371</a>] - Missing includes for MSVC 2005 compiler</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2380'>QPID-2380</a>] - define and implement reliability options for senders and receivers</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2415'>QPID-2415</a>] - Update doc for new SSL support in Windows broker and client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2421'>QPID-2421</a>] - Augment performance tests to allow pre-filling broker, fill and consume only runs.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2423'>QPID-2423</a>] - Add Constructors to set initial value of content for MapContent and ListContent</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2424'>QPID-2424</a>] - Augment CPU/GC processing scripts to provide additional stats.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2425'>QPID-2425</a>] - Augment TKTestRunner to provide latency data for throughput tests.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2446'>QPID-2446</a>] - JMS Client should allow a trust/key store per connection rather than one per JVM</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2447'>QPID-2447</a>] - JMS Client should allow multiple connections, each with it's own SSL certificate from the same JVM</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2466'>QPID-2466</a>] - Replace WeakReference use with SoftReference for enhanced message caching</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2477'>QPID-2477</a>] - std::cout in agent not used anymore</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2479'>QPID-2479</a>] - Log in debug aevery time the housekeeping thread runs</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2483'>QPID-2483</a>] - Can't build samples from Windows installer</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2489'>QPID-2489</a>] - Remove references to boost:: and qpid::framing:: from QMF-generated cpp files</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2492'>QPID-2492</a>] - Changes to brokertest.py to better manage Windows brokers</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2496'>QPID-2496</a>] - The following changes needs to be done for JMS Client to support the changes made in addressing</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2501'>QPID-2501</a>] - WCF Binding Configuration parameters</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2508'>QPID-2508</a>] - Replace org.apache.qpid.util.concurrent.Condition with a CountDownLatch</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2512'>QPID-2512</a>] - Change Default Destination Syntax to ADDR (addressing)</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2513'>QPID-2513</a>] - Expose the ServerConfiguration as an OSGI service for use in plugins</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2516'>QPID-2516</a>] - New sample to show how to specify WCF bindings in config files</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2522'>QPID-2522</a>] - Remove the dependency on Commons Lang for the Java client</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2525'>QPID-2525</a>] - Update QueueInformation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2529'>QPID-2529</a>] - Update the Felix OSGI framework to a recent release</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2530'>QPID-2530</a>] - Refactor the broker-plugins directory setup to allow adding new modules </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2533'>QPID-2533</a>] - Modify config.xml to have ${QPID_HOME}/lib/plugins as the standard OSGI plugin directory</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2534'>QPID-2534</a>] - Add org.apache.qpid.protocol and org.apache.junit.extensions.util to the packages exported by the PluginManager </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2547'>QPID-2547</a>] - Improve PluginTest.java in order to test new OSGI plugins</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2557'>QPID-2557</a>] - Hello World example</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2569'>QPID-2569</a>] - Implement the SimpleXML as an OSGI plugin</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2573'>QPID-2573</a>] - Implement the Firewall functionality as an OSGI plugin</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2575'>QPID-2575</a>] - Create a Connection and Session model to abstract protocol versions</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2579'>QPID-2579</a>] - InternalBrokerBaseCase can fail to test tearDown</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2580'>QPID-2580</a>] - Update build path to allow plugins to use systests</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2582'>QPID-2582</a>] - Update QTC to print stack traces from AppRegistry during InVM startup</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2585'>QPID-2585</a>] - Upgrade Felix to 2.0.5</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2590'>QPID-2590</a>] - Update install notes for transactions</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2594'>QPID-2594</a>] - Exception chaining for JMSExceptions</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2595'>QPID-2595</a>] - WCF programming guide documentation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2599'>QPID-2599</a>] - Allow Qpid users to configure the Java client logging using an sl4j binding of their choice, instead of Qpid shipping a defualt binding.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2618'>QPID-2618</a>] - Add org.apache.common to the PluginManager exported packages</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2619'>QPID-2619</a>] - Capture the PID for the qpid broker on unix platforms</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2628'>QPID-2628</a>] - c++ messaging API dotnet binding needs received message callback</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2629'>QPID-2629</a>] - Remove Java client dependency on commons-collection.jar</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2651'>QPID-2651</a>] - replace the deprecated Derby 10.3.2.1 (data corruption bug) with a newer version</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2663'>QPID-2663</a>] - QMF: Improvement the behavior of the python console implementation based on scale testing. </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2667'>QPID-2667</a>] - Cpp INSTALL-WINDOWS build instructions are out of date</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2669'>QPID-2669</a>] - Base64MD5PasswordFilePrincipalDatabase - code improvement</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2671'>QPID-2671</a>] - Doc Book Programming-In-Apache-Qpid needs update for Messaging .NET binding</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2678'>QPID-2678</a>] - Qpid Shutdown OSGI plugin</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2689'>QPID-2689</a>] - Cpp build on Windows does not produce debug symbol PDB file</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2710'>QPID-2710</a>] - C++ Messaging Client .NET binding is not compiled in SDK</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2711'>QPID-2711</a>] - Add version and icon resources to Windows C++ exe/dll files</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2717'>QPID-2717</a>] - Update the bnd tool to version 0.0.384</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2731'>QPID-2731</a>] - enable getting/setting queue exclusivity property via the JMX management interface</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2736'>QPID-2736</a>] - Allow session.createQueue and session.createTopic methods to accept an address string</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2737'>QPID-2737</a>] - Add support in the JMS client for x-subscribe props defined in the new addressing format</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2738'>QPID-2738</a>] - Add support in the JMS client for "mode" option defined in the new addressing format</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2761'>QPID-2761</a>] - Add tests 4 and 5 to the .NET client (0.8)</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2765'>QPID-2765</a>] - WinSdk does not .NET Binding examples</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2771'>QPID-2771</a>] - Use plugins rather than plugin in package naming</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2772'>QPID-2772</a>] - Add fully qualified path to Regex class on default.build</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2775'>QPID-2775</a>] - use JMX to reload the security configuration for FirewallConfigTest</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2780'>QPID-2780</a>] - Improve the operational logging for 0-10 code path</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2782'>QPID-2782</a>] - QMF: improve the console api for selective filtering of unsolicited V2 indications.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2783'>QPID-2783</a>] - Eliminate the UnknownMessageTypeException from o.a.q.server.protocol package</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2801'>QPID-2801</a>] - Implement LogSubject Interface in 0-10 Subscription/ServerConnection/ServerSession Objects</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2802'>QPID-2802</a>] - Implement selective operational logging via log4j.xml configuration</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2803'>QPID-2803</a>] - Abbreviate the log messages and optimize the log string operations for speed and size</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2809'>QPID-2809</a>] - Once an AMQDestination object resolves an address, it should not try to resolve it again when used in subsequent operations. </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2820'>QPID-2820</a>] - Remove the ManagedChannel interface from broker code</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2822'>QPID-2822</a>] - Move the documentation from o.a.q.server.logging.messages.*_logmessages.properties into qpid docbook documentation</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2824'>QPID-2824</a>] - Use toLogString rather than toString on LogSubject(s)</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2825'>QPID-2825</a>] - The class o.a.q.transport.Sink is not used and can be safely removed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2826'>QPID-2826</a>] - The class o.a.q.transport.Result is not used and can be safely removed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2827'>QPID-2827</a>] - QPID Cpp WinSDK does not contain 64-bit libraries</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2829'>QPID-2829</a>] - The o.a.q.transport.Echo class is not used and can be safely removed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2831'>QPID-2831</a>] - Use slf4j as the logging mechanism across all code paths</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2832'>QPID-2832</a>] - Collate all the LogSubject formatting strings in a static class</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2833'>QPID-2833</a>] - Add a Generic Actor for 0-10 Logging</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2834'>QPID-2834</a>] - Implement subscriptions (SUB) operational logging on 0-10 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2835'>QPID-2835</a>] - Implement connections (CON) operational logging on 0-10</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2837'>QPID-2837</a>] - The o.a.q.server.transport.ThreadPoolFilter class is not used and can be safely removed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2838'>QPID-2838</a>] - reduce code duplication in logging tests</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2839'>QPID-2839</a>] - Implement Channel (CHN) operational logging on 0-10 protocol </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2840'>QPID-2840</a>] - Use a configurable message prefix on the AbstractActor class</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2841'>QPID-2841</a>] - QMF: set TTL on agent heartbeat messages</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2843'>QPID-2843</a>] - remove redundant/duplicated logging</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2853'>QPID-2853</a>] - ReadMe for WinSDK is unclear about Visual Studio version support.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2858'>QPID-2858</a>] - Implement FilterManager for 0-10 subscriptions</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2859'>QPID-2859</a>] - QMF: C++ agent should store its configured name in the config file if available.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2862'>QPID-2862</a>] - QMF: python console should abort any pending transactions when the broker is deleted.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2863'>QPID-2863</a>] - Propagate WinSDK Build Version numbers to the Messaging .NET Binding</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2865'>QPID-2865</a>] - Cpp messaging examples compile problems for x64</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2866'>QPID-2866</a>] - Remove unneeded build files and directory</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2884'>QPID-2884</a>] - Add the method arguments to Subscription_0_10 </li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2887'>QPID-2887</a>] - Remove the System.out.println statements from SlowConsumerDetectionConfiguration</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2897'>QPID-2897</a>] - C++ broker: improve scale and speed of route matching algorithm for topic exchanges.</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2906'>QPID-2906</a>] - Qpid WinSDK .NET Binding does not support Release configuration</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2907'>QPID-2907</a>] - Developing Qpid Cpp Messaging .NET Binding requires setup help</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2911'>QPID-2911</a>] - Remove the class printing from the log4j layout as the (%F:%L) provides sufficient debug information</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2913'>QPID-2913</a>] - QPID Cpp Messaging Libraries for WinSDK Are Not Signed</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2924'>QPID-2924</a>] - Refactor WinSDK to create separate debug and release /bin directories</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2942'>QPID-2942</a>] - enable the Java broker convenience binary release package to be run out-of-the-box</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2943'>QPID-2943</a>] - add the examples to the Java client binary convenience release package</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2947'>QPID-2947</a>] - use a newer sl4j-api release to allow the Java client binary convenience package to be used out-of-the-box</li>
-</ul>
-
-<h4>Test</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2359'>QPID-2359</a>] - Need functional tests for the transactional AMQP WCF channel</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2419'>QPID-2419</a>] - DurableSubscriptionTest is not thorough enough</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2510'>QPID-2510</a>] - Python messaging SetupTests.testConnectError false fail on Windows</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2532'>QPID-2532</a>] - stale lock file</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2787'>QPID-2787</a>] - enhance the MessageStoreTest</li>
-</ul>
-
-<h4>Sub-task</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-1811'>QPID-1811</a>] - Unable to compile qpid on FreeBSD</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2284'>QPID-2284</a>] - Add new qpidxarm dll to the Windows installer build</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2539'>QPID-2539</a>] - Update ACL file syntax to be clearer and add extra operations</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2540'>QPID-2540</a>] - Create parser and implementation of C++ style ACL files for Java broker</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2542'>QPID-2542</a>] - Implement ACL checking as OSGi plugin</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2659'>QPID-2659</a>] - Change message stores to throw exceptions with internal error code 541</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2660'>QPID-2660</a>] - FieldTable does not throw AMQFrameDecodingException</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2675'>QPID-2675</a>] - Remove obsolete QpidException</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2679'>QPID-2679</a>] - Cache Queues during bind and remove from cache on queue.close()</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2680'>QPID-2680</a>] - Provide user documentation for configuring SCD</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2681'>QPID-2681</a>] - Process topic configuration section</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2682'>QPID-2682</a>] - Move SCD Plugin to part of the Core Broker</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2715'>QPID-2715</a>] - Document new SecurityPlugin design and implementation</li>
-</ul>
-
-<h4>Task</h4>
-<ul>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2315'>QPID-2315</a>] - remove unused client package jar dependencies</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2417'>QPID-2417</a>] - Enhance topic test coverage</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2527'>QPID-2527</a>] - Remove Thread::id() dependency</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2709'>QPID-2709</a>] - Replace the remaining references to the incubator</li>
-<li>[<a href='https://issues.apache.org/jira/browse/QPID-2946'>QPID-2946</a>] - remove QMan binary convenience package from the 0.8 release</li>
-</ul>
-
-</div>
diff --git a/qpid/doc/website/content/source_repository.html b/qpid/doc/website/content/source_repository.html
deleted file mode 100644
index 147669991e..0000000000
--- a/qpid/doc/website/content/source_repository.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
--->
-<div class="main_text_area_body">
- <h1>Source Code Repositories</h1>
- <h2>Web Browsing of SVN</h2>
-
- <p>To browse via the web use the ViewVC interface:</p>
-
- <p><a href="http://svn.apache.org/viewvc/qpid/trunk/qpid">http://svn.apache.org/viewvc/qpid/trunk/qpid</a></p>
-
- <p>Or to browse the source tree directly:</p>
-
- <p><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid">https://svn.apache.org/repos/asf/qpid/trunk/qpid</a></p>
-
- <h2>Checking out from SVN</h2>
-
- <p>The source code can be checked out anonymous over HTTP:</p>
-
- <pre>
-svn co http://svn.apache.org/repos/asf/qpid/trunk
- </pre>
-
-
- <p>Committers can check out the code using HTTPS:</p>
-
- <pre>
-svn co https://svn.apache.org/repos/asf/qpid/trunk
- </pre>
-
- <h2>Read only GIT repo</h2>
-
- <p>A read only GIT repo is available:</p>
-
- <p>It can be cloned with</p>
- <pre>
-git clone git://git.apache.org/qpid.git qpid
- </pre>
-
- <p>or</p>
-
-<pre>
-git clone http://git.apache.org/qpid.git qpid
-</pre>
-
- <p>and then git pull will fetch updates.</p>
-
- <p>If you have commit access it is also possible to commit back with git svn dcommit by following the instructions on the <a href="http://wiki.apache.org/general/GitAtApache">GitAtApache</a> page.</p>
-
- <h2>Setting up your subversion client</h2>
-
- <p>When adding files to subversion, it's important that your subversion client is properly setup to the appropriate subversion properties are set. The client can do it automatically by modifying the auto-props section of the subversion config file. Use the contents of:</p>
-
-<pre>
-http://svn.apache.org/repos/asf/qpid/trunk/etc/svn-auto-props
-</pre>
-</div>
diff --git a/qpid/doc/website/example/images/asf-logo.png b/qpid/doc/website/example/images/asf-logo.png
deleted file mode 100644
index d824fab768..0000000000
--- a/qpid/doc/website/example/images/asf-logo.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/asf_logo.gif b/qpid/doc/website/example/images/asf_logo.gif
deleted file mode 100644
index 22eb9d7358..0000000000
--- a/qpid/doc/website/example/images/asf_logo.gif
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/header.png b/qpid/doc/website/example/images/header.png
deleted file mode 100644
index 9cd149fb29..0000000000
--- a/qpid/doc/website/example/images/header.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/main_body.png b/qpid/doc/website/example/images/main_body.png
deleted file mode 100644
index a29bdeecd6..0000000000
--- a/qpid/doc/website/example/images/main_body.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/main_bottom.png b/qpid/doc/website/example/images/main_bottom.png
deleted file mode 100644
index 319288a717..0000000000
--- a/qpid/doc/website/example/images/main_bottom.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/main_top.png b/qpid/doc/website/example/images/main_top.png
deleted file mode 100644
index ffefe05a8d..0000000000
--- a/qpid/doc/website/example/images/main_top.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/menu_body.png b/qpid/doc/website/example/images/menu_body.png
deleted file mode 100644
index 39b2e22205..0000000000
--- a/qpid/doc/website/example/images/menu_body.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/menu_bottom.png b/qpid/doc/website/example/images/menu_bottom.png
deleted file mode 100644
index 21bd16aeba..0000000000
--- a/qpid/doc/website/example/images/menu_bottom.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/menu_top.png b/qpid/doc/website/example/images/menu_top.png
deleted file mode 100644
index dea7164ef0..0000000000
--- a/qpid/doc/website/example/images/menu_top.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/qpid-logo-900x480.png b/qpid/doc/website/example/images/qpid-logo-900x480.png
deleted file mode 100644
index 3e12816142..0000000000
--- a/qpid/doc/website/example/images/qpid-logo-900x480.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/images/qpid-logo.png b/qpid/doc/website/example/images/qpid-logo.png
deleted file mode 100644
index f6d4bfdbad..0000000000
--- a/qpid/doc/website/example/images/qpid-logo.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/example/index.html b/qpid/doc/website/example/index.html
deleted file mode 100644
index 308ac94765..0000000000
--- a/qpid/doc/website/example/index.html
+++ /dev/null
@@ -1,185 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
- -
- - 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.
- -
--->
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Apache Qpid: Open Source AMQP Messaging</title>
- <link href="style.css" rel="stylesheet" type="text/css"/>
- </head>
-
- <body>
- <div id="container">
- <div id="header">
- <div id="logo">
- <h1>Apache Qpid</h1>
- <h2>Open Source AMQP Messaging</h2>
- </div>
- </div> <!-- end of header -->
-
- <div id="menu_box">
- <div id="menu_box_top"></div>
- <div id="menu_box_body">
- <h3>Apache Qpid</h3>
- <ul>
- <li><a href="#">Home</a></li>
- <li><a href="#">Download</a></li>
- <li><a href="#">Getting Started</a></li>
- <li><a href="#">Roadmap</a></li>
- <li><a href="#">License</a></li>
- <li><a href="#">FAQ</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div id="menu_box_bottom"></div>
-
- <div id="menu_box_top"></div>
- <div id="menu_box_body">
- <h3>Documentation</h3>
- <ul>
- <li><a href="#">Version 0.6</a></li>
- <li><a href="#">Version 0.5</a></li>
- <li><a href="#">Archive</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div id="menu_box_bottom"></div>
-
- <div id="menu_box_top"></div>
- <div id="menu_box_body">
- <h3>Community</h3>
- <ul>
- <li><a href="#">Getting Involved</a></li>
- <li><a href="#">Source Repository</a></li>
- <li><a href="#">Mailing Lists</a></li>
- <li><a href="#">Wiki</a></li>
- <li><a href="#">Issue Reporting</a></li>
- <li><a href="#">People</a></li>
- <li><a href="#">Project Status</a></li>
- <li><a href="#">Acknowledgements</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div id="menu_box_bottom"></div>
-
- <div id="menu_box_top"></div>
- <div id="menu_box_body">
- <h3>Developers</h3>
- <ul>
- <li><a href="#">Building Qpid</a></li>
- <li><a href="#">Developer Pages</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div id="menu_box_bottom"></div>
-
- <div id="menu_box_top"></div>
- <div id="menu_box_body">
- <h3>About AMQP</h3>
- <ul>
- <li><a href="#">What is AMQP?</a></li>
- <li><a href="#">Specification</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div id="menu_box_bottom"></div>
-
- </div> <!-- end of menu_box -->
-
- <div id="main_text_area">
- <div id="main_text_area_top"></div>
-
-<div id="main_text_area_body" xmlns="http://www.w3.org/1999/xhtml">
- <h1>Introduction</h1>
- <p>Enterprise Messaging systems let programs communicate by
- exchanging messages, much as people communicate by
- exchanging email. Unlike email, enterprise messaging systems
- provide guaranteed delivery, speed, security, and freedom
- from spam. Until recently, there was no open standard for
- Enterprise Messaging systems, so programmers either wrote
- their own, or used expensive proprietary systems.</p>
-
- <p>AMQP <a href="http://www.amqp.org/">Advanced Message
- Queuing Protocol</a> is the first open standard for
- Enterprise Messaging. It is designed to support messaging
- for just about any distributed or business
- application. Routing can be configured flexibly, easily
- supporting common messaging paradigms like point-to-point,
- fanout, publish-subscribe, and request-response.</p>
-
- <p>Apache Qpid implements the latest AMQP specification, providing
- transaction management, queuing, distribution, security,
- management, clustering, federation and heterogeneous
- multi-platform support and a lot more. And Apache Qpid is
- extremely fast. Apache Qpid <a href="amqp-compatibility.html"
- title="AMQP compatibility">aims to be 100% AMQP Compliant</a>.</p>
-
- <div id="feature_box">
- <div id="feature_box_column1">
- <h3>AMQP Brokers</h3>
- <ul>
- <li><a href="#">Java Broker</a>
- <ul>
- <li><a href="#">Feature Guide</a></li>
- </ul>
- </li>
- <li><a href="#">C++ Broker (Linux/Windows)</a>
- <ul>
- <li><a href="#">Feature Guide</a></li>
- </ul>
- </li>
- </ul>
- <br/>
- <br/>
- </div> <!-- end of feature_box_column -->
-
- <div id="feature_box_column2">
- <h3>AMQP Client APIs</h3>
- <ul>
- <li><a href="#">Java (JMS 1.1 compliant)</a></li>
- <li><a href="#">C++ (Linux/Windows)</a></li>
- <li><a href="#">C# .NET</a></li>
- <li><a href="#">WCF Adapter (Windows Only)</a></li>
- <li><a href="#">Python</a></li>
- <li><a href="#">Ruby</a></li>
- </ul>
- </div> <!-- end of feature_box_column -->
-
- <div id="feature_box_column3">
- <h3>Qpid Management</h3>
- <ul>
- <li><a href="#">QMF Python API</a></li>
- <li><a href="#">QMF C++ API</a> </li>
- <li><a href="#">Python tools</a></li>
- <li><a href="#">QMan (QMF&lt;=>JMX)</a></li>
- </ul>
- </div> <!-- end of feature_box_column -->
-
- </div> <!-- end of feature_box -->
-
-</div> <!-- end of main_text_area_body -->
-
-
- <div id="main_text_area_bottom"></div>
- </div> <!-- end of main_text_area -->
-
- <div id="footer">
- Apache Qpid, Enterprise AMQP Messaging &#xA9; 2004-2010 The Apache Software Foundation.
- </div>
-
- </div>
- </body>
-</html>
diff --git a/qpid/doc/website/example/style.css b/qpid/doc/website/example/style.css
deleted file mode 100644
index 1e05052a03..0000000000
--- a/qpid/doc/website/example/style.css
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-ul {
- list-style-type:square;
-}
-
-th {
- text-align: left;
- font-weight: bold;
-}
-
-
-#body {
- margin:0;
- background:#FFFFFF;
- font-family:"Verdana", sans-serif;
-}
-
-#container {
- width:950px;
- margin:0 auto;
-}
-
-#header {
- height:100px;
- width:950px;
- background:url(images/header.png)
-}
-
-#logo {
- text-align:center;
- font-weight:600;
- padding:0 0 0 0;
- font-size:14px;
- font-family:"Verdana", cursive;
-}
-
-#logo a {
- color:#000000;
- text-decoration:none;
-}
-
-#main_text_area {
- margin-left:200px;
-}
-
-#main_text_area_top {
- height:14px;
- font-size:1px;
-}
-
-#main_text_area_bottom {
- height:14px;
- font-size:1px;
- margin-bottom:4px;
-}
-
-#main_text_area_body {
- padding:5px 24px;
-}
-
-#main_text_area_body p {
- text-align:justify;
-}
-
-#main_text_area br {
- line-height:10px;
-}
-
-#main_text_area h1 {
- font-size:28px;
- font-weight:600;
- margin:0 0 24px 0;
- color:#0c3b82;
- font-family:"Verdana", Times, serif;
-}
-
-#main_text_area h2 {
- font-size:24px;
- font-weight:600;
- margin:24px 0 8px 0;
- color:#0c3b82;
- font-family:"Verdana",Times, serif;
-}
-
-#main_text_area ol, #main_text_area ul {
- padding:0;
- margin:10px 0;
- margin-left:20px;
-}
-
-#main_text_area li {
-/* margin-left:40px; */
-}
-
-#main_text_area, #menu_box {
- font-size:13px;
- line-height:17px;
- color:#000000;
-}
-
-#main_text_area {
- font-size:15px;
-}
-
-#main_text_area a {
- color:#000000;
-}
-
-#main_text_area a:hover {
- color:#000000;
-}
-
-#menu_box {
- width:196px;
- float:left;
- margin-left:4px;
-}
-
-#menu_box_top {
- background:url(images/menu_top.png) no-repeat;
- height:14px;
- font-size:1px;
-}
-
-#menu_box_body {
- background:url(images/menu_body.png) repeat-y;
- padding:5px 24px 5px 24px;
-}
-
-#menu_box_bottom {
- background:url(images/menu_bottom.png) no-repeat;
- height:14px;
- font-size:1px;
- margin-bottom:1px;
-}
-
-#menu_box h3 {
- font-size:20px;
- font-weight:500;
- margin:0 0 8px 0;
- color:#0c3b82;
- font-family:"Verdana",Times, serif;
-}
-
-#menu_box ul {
- margin:12px;
- padding:0px;
-}
-
-#menu_box li {
- list-style:square;
-}
-
-#menu_box a {
- color:#000000;
- text-decoration:none;
-}
-
-#menu_box a:hover {
- color:#000000;
- text-decoration:underline;
-}
-
-#feature_box {
- width:698px;
- overflow:hidden;
-}
-
-#feature_box h3 {
- font-size:18px;
- font-weight:600;
- margin:0 0 8px 0;
- color:#0c3b82;
- font-family:"Verdana", Times, serif;
-}
-
-#feature_box_column1 {
- width:196px;
- float:left;
- padding:10px 15px 10px 15px;
- margin-left:0px;
-}
-
-#feature_box_column2 {
- width:196px;
- float:left;
- padding:10px 15px 10px 15px;
- margin-left:0px;
-}
-
-#feature_box_column3 {
- width:196px;
- float:left;
- padding:10px 15px 10px 15px;
- margin-left:0px;
-}
-
-#feature_box ul {
- margin:.8em .4em;
- padding-left:1.2em;
- padding:0;
- list-style-type: square;
-}
-
-#feature_box ul li {
- font-family:"Verdana",sans-serif;
- font-size:14px;
- color:#000;
- margin:.4em 0;
-}
-
-#feature_box ul li ul {
- padding-left:1.2em;
- margin-left:2em;
-}
-
-#feature_box a {
- color:#000000;
- text-decoration:none;
-}
-
-#feature_box a:hover {
- color:#000000;
- text-decoration:underline;
-}
-
-#footer {
- color:#000000;
- clear:both;
- text-align:center;
- font-size:11px;
- line-height:17px;
- height:45px;
- padding-top:18px;
-}
-
-#footer a {
- color:#000000;
-}
-
-#footer a:hover {
- color:#000000;
-}
-
diff --git a/qpid/doc/website/template/images/asf-logo.png b/qpid/doc/website/template/images/asf-logo.png
deleted file mode 100644
index d824fab768..0000000000
--- a/qpid/doc/website/template/images/asf-logo.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/asf_logo.gif b/qpid/doc/website/template/images/asf_logo.gif
deleted file mode 100644
index 22eb9d7358..0000000000
--- a/qpid/doc/website/template/images/asf_logo.gif
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/header.png b/qpid/doc/website/template/images/header.png
deleted file mode 100644
index 66e35d7e37..0000000000
--- a/qpid/doc/website/template/images/header.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/main_body.png b/qpid/doc/website/template/images/main_body.png
deleted file mode 100644
index a29bdeecd6..0000000000
--- a/qpid/doc/website/template/images/main_body.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/main_bottom.png b/qpid/doc/website/template/images/main_bottom.png
deleted file mode 100644
index 319288a717..0000000000
--- a/qpid/doc/website/template/images/main_bottom.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/main_top.png b/qpid/doc/website/template/images/main_top.png
deleted file mode 100644
index ffefe05a8d..0000000000
--- a/qpid/doc/website/template/images/main_top.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/menu_body.png b/qpid/doc/website/template/images/menu_body.png
deleted file mode 100644
index 39b2e22205..0000000000
--- a/qpid/doc/website/template/images/menu_body.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/menu_bottom.png b/qpid/doc/website/template/images/menu_bottom.png
deleted file mode 100644
index 21bd16aeba..0000000000
--- a/qpid/doc/website/template/images/menu_bottom.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/menu_top.png b/qpid/doc/website/template/images/menu_top.png
deleted file mode 100644
index dea7164ef0..0000000000
--- a/qpid/doc/website/template/images/menu_top.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/qpid-logo-900x480.png b/qpid/doc/website/template/images/qpid-logo-900x480.png
deleted file mode 100644
index 3e12816142..0000000000
--- a/qpid/doc/website/template/images/qpid-logo-900x480.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/images/qpid-logo.png b/qpid/doc/website/template/images/qpid-logo.png
deleted file mode 100644
index 95d49ea469..0000000000
--- a/qpid/doc/website/template/images/qpid-logo.png
+++ /dev/null
Binary files differ
diff --git a/qpid/doc/website/template/style.css b/qpid/doc/website/template/style.css
deleted file mode 100644
index 57dc571425..0000000000
--- a/qpid/doc/website/template/style.css
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-ul {
- list-style-type:square;
-}
-
-th {
- text-align: left;
- font-weight: bold;
-}
-
-body {
- margin:0;
- background:#FFFFFF;
- font-family:"Verdana", sans-serif;
-}
-
-.container {
- width:950px;
- margin:0 auto;
-}
-
-.header {
- height:100px;
- width:950px;
- background:url(images/header.png)
-}
-
-.logo {
- text-align:center;
- font-weight:600;
- padding:0 0 0 0;
- font-size:14px;
- font-family:"Verdana", cursive;
-}
-
-.logo a {
- color:#000000;
- text-decoration:none;
-}
-
-.main_text_area {
- margin-left:200px;
-}
-
-.main_text_area_top {
- height:14px;
- font-size:1px;
-}
-
-.main_text_area_bottom {
- height:14px;
- font-size:1px;
- margin-bottom:4px;
-}
-
-.main_text_area_body {
- padding:5px 24px;
-}
-
-.main_text_area_body p {
- text-align:justify;
-}
-
-.main_text_area br {
- line-height:10px;
-}
-
-.main_text_area h1 {
- font-size:28px;
- font-weight:600;
- margin:0 0 24px 0;
- color:#0c3b82;
- font-family:"Verdana", Times, serif;
-}
-
-.main_text_area h2 {
- font-size:24px;
- font-weight:600;
- margin:24px 0 8px 0;
- color:#0c3b82;
- font-family:"Verdana",Times, serif;
-}
-
-.main_text_area ol, .main_text_area ul {
- padding:0;
- margin:10px 0;
- margin-left:20px;
-}
-
-.main_text_area li {
-/* margin-left:40px; */
-}
-
-.main_text_area, .menu_box {
- font-size:13px;
- line-height:17px;
- color:#000000;
-}
-
-.main_text_area {
- font-size:15px;
-}
-
-.main_text_area a {
- color:#000000;
-}
-
-.main_text_area a:hover {
- color:#000000;
-}
-
-.menu_box {
- width:196px;
- float:left;
- margin-left:4px;
-}
-
-.menu_box_top {
- background:url(images/menu_top.png) no-repeat;
- height:14px;
- font-size:1px;
-}
-
-.menu_box_body {
- background:url(images/menu_body.png) repeat-y;
- padding:5px 24px 5px 24px;
-}
-
-.menu_box_bottom {
- background:url(images/menu_bottom.png) no-repeat;
- height:14px;
- font-size:1px;
- margin-bottom:1px;
-}
-
-.menu_box h3 {
- font-size:20px;
- font-weight:500;
- margin:0 0 8px 0;
- color:#0c3b82;
- font-family:"Verdana",Times, serif;
-}
-
-.menu_box ul {
- margin:12px;
- padding:0px;
-}
-
-.menu_box li {
- list-style:square;
-}
-
-.menu_box a {
- color:#000000;
- text-decoration:none;
-}
-
-.menu_box a:hover {
- color:#000000;
- text-decoration:underline;
-}
-
-.feature_box {
- width:698px;
- overflow:hidden;
-}
-
-.feature_box h3 {
- font-size:18px;
- font-weight:600;
- margin:0 0 8px 0;
- color:#0c3b82;
- font-family:"Verdana", Times, serif;
-}
-
-.feature_box_column1 {
- width:196px;
- float:left;
- padding:10px 15px 10px 15px;
- margin-left:0px;
-}
-
-.feature_box_column2 {
- width:196px;
- float:left;
- padding:10px 15px 10px 15px;
- margin-left:0px;
-}
-
-.feature_box_column3 {
- width:196px;
- float:left;
- padding:10px 15px 10px 15px;
- margin-left:0px;
-}
-
-
-.feature_box ul {
- margin:.8em .4em;
- padding-left:1.2em;
- padding:0;
- list-style-type: square;
-}
-
-.feature_box ul li {
- font-family:"Verdana",sans-serif;
- font-size:14px;
- color:#000;
- margin:.4em 0;
-}
-
-.feature_box ul li ul {
- padding-left:1.2em;
- margin-left:2em;
-}
-
-.feature_box a {
- color:#000000;
- text-decoration:none;
-}
-
-.feature_box a:hover {
- color:#000000;
- text-decoration:underline;
-}
-
-.footer {
- color:#000000;
- clear:both;
- text-align:center;
- font-size:11px;
- line-height:17px;
- height:45px;
- padding-top:18px;
-}
-
-.footer a {
- color:#000000;
-}
-
-.footer a:hover {
- color:#000000;
-}
-
-.download_table {
- width:100%;
-}
-
-.download_table_col_1 {
- width:240px;
-}
-
-.download_table_amqp_col {
- text-align:center;
- width:80px;
-}
-
diff --git a/qpid/doc/website/template/template.html b/qpid/doc/website/template/template.html
deleted file mode 100644
index fab61a4ffa..0000000000
--- a/qpid/doc/website/template/template.html
+++ /dev/null
@@ -1,126 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
- -
- - 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.
- -
--->
-
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Apache Qpid&#8482;: Open Source AMQP Messaging</title>
- <link href="style.css" rel="stylesheet" type="text/css"/>
- </head>
-
- <body>
- <div class="container">
- <div class="header">
- <div class="logo">
- <h1>Apache Qpid&#8482;</h1>
- <h2>Open Source AMQP Messaging</h2>
- </div>
- </div> <!-- end of header -->
-
- <div class="menu_box">
- <div class="menu_box_top"></div>
- <div class="menu_box_body">
- <h3>Apache Qpid</h3>
- <ul>
- <li><a href="index.html">Home</a></li>
- <li><a href="download.cgi">Download</a></li>
- <li><a href="getting_started.html">Getting Started</a></li>
- <li><a href="http://www.apache.org/licenses/">License</a></li>
- <li><a href="https://cwiki.apache.org/qpid/faq.html">FAQ</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div class="menu_box_bottom"></div>
-
- <div class="menu_box_top"></div>
- <div class="menu_box_body">
- <h3>Documentation</h3>
- <ul>
- <li><a href="documentation.html#doc-release">0.10 Release</a></li>
- <li><a href="documentation.html#doc-trunk">Trunk</a></li>
- <li><a href="documentation.html#doc-archives">Archive</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div class="menu_box_bottom"></div>
-
- <div class="menu_box_top"></div>
- <div class="menu_box_body">
- <h3>Community</h3>
- <ul>
- <li><a href="getting_involved.html">Getting Involved</a></li>
- <li><a href="source_repository.html">Source Repository</a></li>
- <li><a href="mailing_lists.html">Mailing Lists</a></li>
- <li><a href="https://cwiki.apache.org/qpid/">Wiki</a></li>
- <li><a href="https://issues.apache.org/jira/browse/qpid">Issue Reporting</a></li>
- <li><a href="people.html">People</a></li>
- <li><a href="acknowledgements.html">Acknowledgements</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div class="menu_box_bottom"></div>
-
- <div class="menu_box_top"></div>
- <div class="menu_box_body">
- <h3>Developers</h3>
- <ul>
- <li><a href="https://cwiki.apache.org/qpid/building.html">Building Qpid</a></li>
- <li><a href="https://cwiki.apache.org/qpid/developer-pages.html">Developer Pages</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div class="menu_box_bottom"></div>
-
- <div class="menu_box_top"></div>
- <div class="menu_box_body">
- <h3>About AMQP</h3>
- <ul>
- <li><a href="amqp.html">What is AMQP?</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div class="menu_box_bottom"></div>
-
- <div class="menu_box_top"></div>
- <div class="menu_box_body">
- <h3>About Apache</h3>
- <ul>
- <li><a href="http://www.apache.org">Home</a></li>
- <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
- <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
- <li><a href="http://www.apache.org/security/">Security</a></li>
- </ul>
- </div> <!-- end of menu_box_body -->
- <div class="menu_box_bottom"></div>
- </div> <!-- end of menu_box -->
-
- <div class="main_text_area">
- <div class="main_text_area_top"></div>
-{.}
- </div>
-
- <div class="footer">
- <p>
- &#xA9; 2004-2011 The Apache Software Foundation.<br />
- Apache Qpid, Qpid, Apache, the Apache feather logo, and the Apache Qpid project logo are trademarks of The Apache Software Foundation.<br />
- All other marks mentioned may be trademarks or registered trademarks of their respective owners.
- </p>
- </div>
-
- </div>
- </body>
-</html>
diff --git a/qpid/doc/website/tools/generate b/qpid/doc/website/tools/generate
deleted file mode 100755
index a45e803793..0000000000
--- a/qpid/doc/website/tools/generate
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import os
-import sys
-
-if len(sys.argv) != 4:
- print "Usage: $ generate template/template.html contentDir outputDir"
- exit()
-
-else:
- try:
- srcDir = os.path.abspath(sys.argv[2])
- srcFiles = os.listdir(srcDir)
- targetDir = os.path.abspath(sys.argv[3])
- template = open(sys.argv[1], "r")
-
- for srcFile in srcFiles:
- if os.path.splitext(srcFile)[1] == ".html":
- content = open(os.path.join(srcDir,srcFile), "r")
- output = open(os.path.join(targetDir,srcFile),"w")
-
- template.seek(0)
-
- for t in template:
- if t.rstrip() == "{.}":
- for c in content:
- output.write( c )
- else:
- output.write( t )
-
- output.close()
- content.close()
-
- except:
- print "Ooops!"
- exit()
-
-template.close()
diff --git a/qpid/doc/website/tools/wrap b/qpid/doc/website/tools/wrap
deleted file mode 100755
index d756da7335..0000000000
--- a/qpid/doc/website/tools/wrap
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-#
-
-import sys
-
-if len(sys.argv) != 4:
- print "Usage: $ wrap template.html content.html output.html"
- exit()
-
-try:
- template = open(sys.argv[1], "r")
- content = open(sys.argv[2], "r")
- output = open(sys.argv[3], "w")
-
- for t in template:
- if t.rstrip() == "{.}":
- for c in content:
- output.write( c )
- else:
- output.write( t )
-except:
- print "Ooops!"
- exit()
-
-template.close()
-content.close()
-output.close()
diff --git a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
index a5d267282b..9bdd4b9d17 100644
--- a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
+++ b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
@@ -74,8 +74,6 @@ public class AppInfo
appInfoMap.put("port", sc.getPorts().toString());
appInfoMap.put("version", QpidProperties.getReleaseVersion());
appInfoMap.put("vhosts", "standalone");
- appInfoMap.put("JMXPrincipalDatabase", sc
- .getJMXPrincipalDatabase());
appInfoMap.put("KeystorePath", sc.getKeystorePath());
appInfoMap.put("PluginDirectory", sc.getPluginDirectory());
appInfoMap.put("CertType", sc.getCertType());
diff --git a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
index ebede414f4..c0cb4aedce 100644
--- a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
+++ b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
@@ -92,9 +92,6 @@ public class FirewallConfigurationTest extends InternalBrokerBaseCase
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
out.write("\t\t</principal-databases>\n");
- out.write("\t\t<jmx>\n");
- out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
- out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
out.write("\t\t</firewall>\n");
@@ -192,9 +189,6 @@ public class FirewallConfigurationTest extends InternalBrokerBaseCase
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
out.write("\t\t</principal-databases>\n");
- out.write("\t\t<jmx>\n");
- out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
- out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
out.write("\t\t</firewall>\n");
@@ -301,9 +295,6 @@ public class FirewallConfigurationTest extends InternalBrokerBaseCase
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
out.write("\t\t</principal-databases>\n");
- out.write("\t\t<jmx>\n");
- out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
- out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
diff --git a/qpid/java/broker/etc/config.xml b/qpid/java/broker/etc/config.xml
index ec386ab669..c0f9b4df61 100644
--- a/qpid/java/broker/etc/config.xml
+++ b/qpid/java/broker/etc/config.xml
@@ -86,10 +86,6 @@
<allow-all />
<msg-auth>false</msg-auth>
-
- <jmx>
- <principal-database>passwordfile</principal-database>
- </jmx>
</security>
<virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
index 5192d5be6f..f0f7678cd9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -1311,6 +1311,12 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.isShadow();
}
+
+ public Boolean getUserProxyAuth()
+ {
+ // TODO
+ return false;
+ }
}
private class SessionDelegate implements BrokerSchema.SessionDelegate
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index 297f7abdb8..f152865a27 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -214,6 +214,13 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
+ (_configFile == null ? "" : " Configuration file : " + _configFile);
throw new ConfigurationException(message);
}
+
+ if (getListValue("security.jmx.principal-database").size() > 0)
+ {
+ String message = "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml."
+ + (_configFile == null ? "" : " Configuration file : " + _configFile);
+ throw new ConfigurationException(message);
+ }
}
/*
@@ -533,11 +540,6 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getListValue(name);
}
- public List<String> getManagementPrincipalDBs()
- {
- return getListValue("security.jmx.principal-database");
- }
-
public int getFrameSize()
{
return getIntValue("advanced.framesize", DEFAULT_FRAME_SIZE);
@@ -568,11 +570,6 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getBooleanValue("security.msg-auth");
}
- public String getJMXPrincipalDatabase()
- {
- return getStringValue("security.jmx.principal-database");
- }
-
public String getManagementKeyStorePath()
{
return getStringValue("management.ssl.keyStorePath");
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
index 11fdeae2b1..9848f90ea9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
@@ -37,8 +37,8 @@ import org.apache.qpid.server.queue.Filterable;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static final int NON_PERSISTENT = 1;
- private static final int PERSISTENT = 2;
+ private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
+
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = org.apache.log4j.Logger.getLogger(PropertyExpression.class);
@@ -172,13 +172,14 @@ public class PropertyExpression implements Expression
{
public Object evaluate(Filterable message)
{
- int mode = message.isPersistent() ? PERSISTENT : NON_PERSISTENT;
+ JMSDeliveryMode mode = message.isPersistent() ? JMSDeliveryMode.PERSISTENT :
+ JMSDeliveryMode.NON_PERSISTENT;
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
- return mode;
+ return mode.toString();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
index d4b79134a2..79de0678f0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.handler;
+
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
@@ -68,7 +69,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
}
MethodRegistry methodRegistry = session.getMethodRegistry();
AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
- switch (authResult.status)
+ switch (authResult.getStatus())
{
case ERROR:
Exception cause = authResult.getCause();
@@ -96,13 +97,14 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ConnectionStartOkMethodHandler.getConfiguredFrameSize(),
ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
- session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
+ final UsernamePrincipal principal = UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject());
+ session.setAuthorizedID(principal);
disposeSaslServer(session);
break;
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
- ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
+ ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
session.writeFrame(secureBody.generateFrame(0));
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 4442f969c4..544bd62ed8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
@@ -88,7 +88,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
MethodRegistry methodRegistry = session.getMethodRegistry();
- switch (authResult.status)
+ switch (authResult.getStatus())
{
case ERROR:
Exception cause = authResult.getCause();
@@ -121,7 +121,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
- ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
+ ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
session.writeFrame(secureBody.generateFrame(0));
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
index 0334a856c1..6a34ff4a26 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
@@ -20,32 +20,6 @@
*/
package org.apache.qpid.server.management;
-import org.apache.commons.configuration.ConfigurationException;
-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.rmi.RMIPasswordAuthenticator;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-import javax.management.NotificationListener;
-import javax.management.NotificationFilterSupport;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.rmi.RMIConnectorServer;
-import javax.management.remote.rmi.RMIJRMPServerImpl;
-import javax.management.remote.rmi.RMIServerImpl;
-import javax.rmi.ssl.SslRMIClientSocketFactory;
-import javax.rmi.ssl.SslRMIServerSocketFactory;
-
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -64,7 +38,31 @@ import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
-import java.util.Map;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotificationFilterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.MBeanServerForwarder;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.management.remote.rmi.RMIJRMPServerImpl;
+import javax.management.remote.rmi.RMIServerImpl;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
/**
* This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
@@ -113,12 +111,6 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
int port = appRegistry.getConfiguration().getJMXManagementPort();
- //retrieve the Principal Database assigned to JMX authentication duties
- String jmxDatabaseName = appRegistry.getConfiguration().getJMXPrincipalDatabase();
- Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
- PrincipalDatabase db = map.get(jmxDatabaseName);
-
- HashMap<String,Object> env = new HashMap<String,Object>();
//Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
RMIClientSocketFactory csf;
@@ -200,7 +192,8 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
//add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
- rmipa.setPrincipalDatabase(db);
+ rmipa.setAuthenticationManager(appRegistry.getAuthenticationManager());
+ HashMap<String,Object> env = new HashMap<String,Object>();
env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
/*
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
index 380f51e308..ce6bd3ee33 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
@@ -27,7 +27,6 @@ import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Principal;
-import java.util.Properties;
import java.util.Set;
import javax.management.Attribute;
@@ -65,7 +64,6 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
public final static String READONLY = "readonly";
private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
private MBeanServer _mbs;
- private static Properties _userRoles = new Properties();
private static ManagementActor _logActor;
public static MBeanServerForwarder newProxyInstance()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
index b6e97e08fb..371ae0de50 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
@@ -60,7 +60,7 @@ public class AMQPriorityQueue extends SimpleAMQQueue
{
// check that all subscriptions are not in advance of the entry
SubscriptionList.SubscriptionNodeIterator subIter = _subscriptionList.iterator();
- while(subIter.advance() && !entry.isAcquired())
+ while(subIter.advance() && entry.isAvailable())
{
final Subscription subscription = subIter.getNode().getSubscription();
if(!subscription.isClosed())
@@ -70,7 +70,7 @@ public class AMQPriorityQueue extends SimpleAMQQueue
{
QueueEntry subnode = context._lastSeenEntry;
QueueEntry released = context._releasedEntry;
- while(subnode != null && entry.compareTo(subnode) < 0 && !entry.isAcquired() && (released == null || released.compareTo(entry) < 0))
+ while(subnode != null && entry.compareTo(subnode) < 0 && entry.isAvailable() && (released == null || released.compareTo(entry) < 0))
{
if(QueueContext._releasedUpdater.compareAndSet(context,released,entry))
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
index 79ede2694e..88349586c3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
@@ -52,6 +52,17 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
}
public abstract State getState();
+
+ /**
+ * Returns true if state is either DEQUEUED or DELETED.
+ *
+ * @return true if state is either DEQUEUED or DELETED.
+ */
+ public boolean isDispensed()
+ {
+ State currentState = getState();
+ return currentState == State.DEQUEUED || currentState == State.DELETED;
+ }
}
@@ -207,4 +218,18 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
void addStateChangeListener(StateChangeListener listener);
boolean removeStateChangeListener(StateChangeListener listener);
+
+ /**
+ * Returns true if entry is in DEQUEUED state, otherwise returns false.
+ *
+ * @return true if entry is in DEQUEUED state, otherwise returns false
+ */
+ boolean isDequeued();
+
+ /**
+ * Returns true if entry is either DEQUED or DELETED state.
+ *
+ * @return true if entry is either DEQUED or DELETED state
+ */
+ boolean isDispensed();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index 809ba3277e..bc452d2d72 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
@@ -499,7 +499,7 @@ public class QueueEntryImpl implements QueueEntry
{
QueueEntryImpl next = nextNode();
- while(next != null && next.isDeleted())
+ while(next != null && next.isDispensed() )
{
final QueueEntryImpl newNext = next.nextNode();
@@ -547,4 +547,16 @@ public class QueueEntryImpl implements QueueEntry
return _queueEntryList;
}
+ @Override
+ public boolean isDequeued()
+ {
+ return _state == DEQUEUED_STATE;
+ }
+
+ @Override
+ public boolean isDispensed()
+ {
+ return _state.isDispensed();
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index b02d03a1ad..274cb6714a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
@@ -629,7 +629,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// this catches the case where we *just* miss an update
int loops = 2;
- while (!(entry.isAcquired() || entry.isDeleted()) && loops != 0)
+ while (entry.isAvailable() && loops != 0)
{
if (nextNode == null)
{
@@ -648,7 +648,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- if (!(entry.isAcquired() || entry.isDeleted()))
+ if (entry.isAvailable())
{
checkSubscriptionsNotAheadOfDelivery(entry);
@@ -942,7 +942,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node != null && !node.isDeleted())
+ if (node != null && !node.isDispensed())
{
entryList.add(node);
}
@@ -1046,7 +1046,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance() && !filter.filterComplete())
{
QueueEntry node = queueListIterator.getNode();
- if (!node.isDeleted() && filter.accept(node))
+ if (!node.isDispensed() && filter.accept(node))
{
entryList.add(node);
}
@@ -1240,7 +1240,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if ((messageId >= fromMessageId)
&& (messageId <= toMessageId)
- && !node.isDeleted()
&& node.acquire())
{
dequeueEntry(node);
@@ -1270,7 +1269,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (noDeletes && queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (!node.isDeleted() && node.acquire())
+ if (node.acquire())
{
dequeueEntry(node);
noDeletes = false;
@@ -1300,7 +1299,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (!node.isDeleted() && node.acquire())
+ if (node.acquire())
{
dequeueEntry(node, txn);
if(++count == request)
@@ -1654,7 +1653,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = getNextAvailableEntry(sub);
- if (node != null && !(node.isAcquired() || node.isDeleted()))
+ if (node != null && node.isAvailable())
{
if (sub.hasInterest(node))
{
@@ -1715,7 +1714,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = (releasedNode != null && lastSeen.compareTo(releasedNode)>=0) ? releasedNode : _entries.next(lastSeen);
boolean expired = false;
- while (node != null && (node.isAcquired() || node.isDeleted() || (expired = node.expired()) || !sub.hasInterest(node)))
+ while (node != null && (!node.isAvailable() || (expired = node.expired()) || !sub.hasInterest(node)))
{
if (expired)
{
@@ -1884,8 +1883,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- // Only process nodes that are not currently deleted
- if (!node.isDeleted())
+ // Only process nodes that are not currently deleted and not dequeued
+ if (!node.isDispensed())
{
// If the node has exired then aquire it
if (node.expired() && node.acquire())
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
index b97c2c55c5..46baab8c85 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
@@ -1,6 +1,5 @@
package org.apache.qpid.server.queue;
-import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.ServerMessage;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -156,7 +155,7 @@ public class SimpleQueueEntryList implements QueueEntryList
if(!atTail())
{
QueueEntryImpl nextNode = _lastNode.nextNode();
- while(nextNode.isDeleted() && nextNode.nextNode() != null)
+ while(nextNode.isDispensed() && nextNode.nextNode() != null)
{
nextNode = nextNode.nextNode();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
index 62967ef7eb..8c2d60a660 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
@@ -20,42 +20,93 @@
*/
package org.apache.qpid.server.security.auth;
+import javax.security.auth.Subject;
+
+/**
+ * Encapsulates the result of an attempt to authenticate.
+ * <p>
+ * The authentication status describes the overall outcome.
+ * <p>
+ * <ol>
+ * <li>If authentication status is SUCCESS, the subject will be populated.
+ * </li>
+ * <li>If authentication status is CONTINUE, the authentication has failed because the user
+ * supplied incorrect credentials (etc). If the authentication requires it, the next challenge
+ * is made available.
+ * </li>
+ * <li>If authentication status is ERROR , the authentication decision could not be made due
+ * to a failure (such as an external system), the {@link AuthenticationResult#getCause()}
+ * will provide the underlying exception.
+ * </li>
+ * </ol>
+ *
+ */
public class AuthenticationResult
{
public enum AuthenticationStatus
{
- SUCCESS, CONTINUE, ERROR
+ /** Authentication successful */
+ SUCCESS,
+ /** Authentication not successful due to credentials problem etc */
+ CONTINUE,
+ /** Problem prevented the authentication from being made e.g. failure of an external system */
+ ERROR
}
- public AuthenticationStatus status;
- public byte[] challenge;
-
- private Exception cause;
+ public final AuthenticationStatus _status;
+ public final byte[] _challenge;
+ private final Exception _cause;
+ private final Subject _subject;
- public AuthenticationResult(AuthenticationStatus status)
+ public AuthenticationResult(final AuthenticationStatus status)
{
this(null, status, null);
}
- public AuthenticationResult(byte[] challenge, AuthenticationStatus status)
+ public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status)
{
this(challenge, status, null);
}
- public AuthenticationResult(AuthenticationStatus error, Exception cause)
+ public AuthenticationResult(final AuthenticationStatus error, final Exception cause)
{
this(null, error, cause);
}
- public AuthenticationResult(byte[] challenge, AuthenticationStatus status, Exception cause)
+ public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status, final Exception cause)
+ {
+ this._status = status;
+ this._challenge = challenge;
+ this._cause = cause;
+ this._subject = null;
+ }
+
+ public AuthenticationResult(final Subject subject)
{
- this.status = status;
- this.challenge = challenge;
- this.cause = cause;
+ this._status = AuthenticationStatus.SUCCESS;
+ this._challenge = null;
+ this._cause = null;
+ this._subject = subject;
}
public Exception getCause()
{
- return cause;
+ return _cause;
+ }
+
+ public AuthenticationStatus getStatus()
+ {
+ return _status;
+ }
+
+ public byte[] getChallenge()
+ {
+ return _challenge;
}
+
+ public Subject getSubject()
+ {
+ return _subject;
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
index e9276e1b0e..a22c66c73d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.security.auth.database;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Method;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -170,18 +171,13 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
{
AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
- List<String> principalDBs = config.getManagementPrincipalDBs();
- if (principalDBs.isEmpty())
- {
- throw new ConfigurationException("No principal-database specified for jmx security");
- }
- String databaseName = principalDBs.get(0);
- PrincipalDatabase database = getDatabases().get(databaseName);
- if (database == null)
+ final Collection<PrincipalDatabase> dbs = getDatabases().values();
+ if (dbs.size() == 0)
{
- throw new ConfigurationException("Principal-database '" + databaseName + "' not found");
+ throw new ConfigurationException("Principal-database not found");
}
+ final PrincipalDatabase database = dbs.iterator().next();
_mbean.setPrincipalDatabase(database);
_mbean.register();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index 39e1e07c57..c1ef4c8ff5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
@@ -32,9 +32,43 @@ import org.apache.qpid.server.security.auth.AuthenticationResult;
*/
public interface AuthenticationManager extends Closeable
{
+
+ /**
+ * Gets the SASL mechanisms known to this manager.
+ *
+ * @return SASL mechanism names, space separated.
+ */
String getMechanisms();
+ /**
+ * Creates a SASL server for the specified mechanism name for the given
+ * fully qualified domain name.
+ *
+ * @param mechanism mechanism name
+ * @param localFQDN domain name
+ *
+ * @return SASL server
+ * @throws SaslException
+ */
SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException;
+ /**
+ * Authenticates a user using SASL negotiation.
+ *
+ * @param server SASL server
+ * @param response SASL response to process
+ *
+ * @return authentication result
+ */
AuthenticationResult authenticate(SaslServer server, byte[] response);
+
+ /**
+ * Authenticates a user using their username and password.
+ *
+ * @param username username
+ * @param password password
+ *
+ * @return authentication result
+ */
+ AuthenticationResult authenticate(String username, String password);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index d10ad2c170..d36bbc4f46 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -23,12 +23,16 @@ package org.apache.qpid.server.security.auth.manager;
import org.apache.log4j.Logger;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.sasl.JCAProvider;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.AccountNotFoundException;
import javax.security.sasl.SaslServerFactory;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslException;
@@ -163,7 +167,9 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
if (server.isComplete())
{
- return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.SUCCESS);
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
+ return new AuthenticationResult(subject);
}
else
{
@@ -181,4 +187,31 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
_mechanisms = null;
Security.removeProvider(PROVIDER_NAME);
}
+
+ /**
+ * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(String, String)
+ */
+ @Override
+ public AuthenticationResult authenticate(final String username, final String password)
+ {
+ final PrincipalDatabase db = ApplicationRegistry.getInstance().getDatabaseManager().getDatabases().values().iterator().next();
+
+ try
+ {
+ if (db.verifyPassword(username, password.toCharArray()))
+ {
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new UsernamePrincipal(username));
+ return new AuthenticationResult(subject);
+ }
+ else
+ {
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+ }
+ catch (AccountNotFoundException e)
+ {
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index 0cbbccb3b8..b7985ad972 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -20,14 +20,13 @@
*/
package org.apache.qpid.server.security.auth.rmi;
-import java.util.Collections;
-
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-import javax.security.auth.login.AccountNotFoundException;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
public class RMIPasswordAuthenticator implements JMXAuthenticator
{
@@ -39,15 +38,15 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String CREDENTIALS_REQUIRED = "User details are required. " +
"Please ensure you are using an up to date management console to connect.";
- private PrincipalDatabase _db = null;
+ private AuthenticationManager _authenticationManager = null;
public RMIPasswordAuthenticator()
{
}
-
- public void setPrincipalDatabase(PrincipalDatabase pd)
+
+ public void setAuthenticationManager(final AuthenticationManager authenticationManager)
{
- this._db = pd;
+ _authenticationManager = authenticationManager;
}
public Subject authenticate(Object credentials) throws SecurityException
@@ -65,50 +64,39 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
}
- // Verify that required number of credential's.
+ // Verify that required number of credentials.
final String[] userCredentials = (String[]) credentials;
if (userCredentials.length != 2)
{
throw new SecurityException(SHOULD_HAVE_2_ELEMENTS);
}
- String username = (String) userCredentials[0];
- String password = (String) userCredentials[1];
+ final String username = (String) userCredentials[0];
+ final String password = (String) userCredentials[1];
- // Verify that all required credential's are actually present.
+ // Verify that all required credentials are actually present.
if (username == null || password == null)
{
throw new SecurityException(SHOULD_BE_NON_NULL);
}
- // Verify that a PD has been set.
- if (_db == null)
+ // Verify that an AuthenticationManager has been set.
+ if (_authenticationManager == null)
{
throw new SecurityException(UNABLE_TO_LOOKUP);
}
-
- boolean authenticated = false;
+ final AuthenticationResult result = _authenticationManager.authenticate(username, password);
- // Perform authentication
- try
+ if (AuthenticationStatus.ERROR.equals(result.getStatus()))
{
- if (_db.verifyPassword(username, password.toCharArray()))
- {
- authenticated = true;
- }
- }
- catch (AccountNotFoundException e)
- {
- throw new SecurityException(INVALID_CREDENTIALS); // XXX
+ throw new SecurityException("Authentication manager failed", result.getCause());
}
-
- if (authenticated)
+ else if (AuthenticationStatus.SUCCESS.equals(result.getStatus()))
{
- //credential's check out, return the appropriate JAAS Subject
- return new Subject(true,
- Collections.singleton(new JMXPrincipal(username)),
- Collections.EMPTY_SET,
- Collections.EMPTY_SET);
+ final Subject subject = result.getSubject();
+ subject.getPrincipals().add(new JMXPrincipal(username));
+ subject.setReadOnly();
+ return subject;
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
index d7c8383690..b4ee13fe6b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
@@ -21,14 +21,21 @@
package org.apache.qpid.server.security.auth.sasl;
import java.security.Principal;
+import java.util.Set;
+
+import javax.security.auth.Subject;
/** A principal that is just a wrapper for a simple username. */
public class UsernamePrincipal implements Principal
{
- private String _name;
+ private final String _name;
public UsernamePrincipal(String name)
{
+ if (name == null)
+ {
+ throw new IllegalArgumentException("name cannot be null");
+ }
_name = name;
}
@@ -41,4 +48,53 @@ public class UsernamePrincipal implements Principal
{
return _name;
}
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ return prime * _name.hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ else
+ {
+ if (obj instanceof UsernamePrincipal)
+ {
+ UsernamePrincipal other = (UsernamePrincipal) obj;
+ return _name.equals(other._name);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ public static UsernamePrincipal getUsernamePrincipalFromSubject(final Subject authSubject)
+ {
+ if (authSubject == null)
+ {
+ throw new IllegalArgumentException("No authenticated subject.");
+ }
+
+ final Set<UsernamePrincipal> principals = authSubject.getPrincipals(UsernamePrincipal.class);
+ if (principals.size() != 1)
+ {
+ throw new IllegalArgumentException("Can't find single UsernamePrincipal in authenticated subject");
+ }
+ return principals.iterator().next();
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index 43540c88a1..494003c8a0 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -23,24 +23,18 @@ package org.apache.qpid.server.configuration;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.RandomAccessFile;
import java.util.List;
import java.util.Locale;
-import junit.framework.TestCase;
-
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.protocol.AMQProtocolEngine;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.transport.TestNetworkDriver;
public class ServerConfigurationTest extends InternalBrokerBaseCase
{
@@ -320,20 +314,6 @@ public class ServerConfigurationTest extends InternalBrokerBaseCase
assertEquals(true, serverConfig.getMsgAuth());
}
- public void testGetJMXPrincipalDatabase() throws ConfigurationException
- {
- // Check default
- ServerConfiguration serverConfig = new ServerConfiguration(_config);
- serverConfig.initialise();
- assertEquals(null, serverConfig.getJMXPrincipalDatabase());
-
- // Check value we set
- _config.setProperty("security.jmx.principal-database", "a");
- serverConfig = new ServerConfiguration(_config);
- serverConfig.initialise();
- assertEquals("a", serverConfig.getJMXPrincipalDatabase());
- }
-
public void testGetManagementKeyStorePath() throws ConfigurationException
{
// Check default
@@ -831,9 +811,6 @@ public class ServerConfigurationTest extends InternalBrokerBaseCase
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
out.write("\t\t</principal-databases>\n");
- out.write("\t\t<jmx>\n");
- out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
- out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -881,9 +858,6 @@ public class ServerConfigurationTest extends InternalBrokerBaseCase
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
out.write("\t\t</principal-databases>\n");
- out.write("\t\t<jmx>\n");
- out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
- out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -986,9 +960,6 @@ public class ServerConfigurationTest extends InternalBrokerBaseCase
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
out.write("\t\t</principal-databases>\n");
- out.write("\t\t<jmx>\n");
- out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
- out.write("\t\t</jmx>\n");
out.write("\t\t<firewall>\n");
out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -1489,4 +1460,31 @@ public class ServerConfigurationTest extends InternalBrokerBaseCase
ce.getMessage());
}
}
+
+ /*
+ * Tests that the old element security.jmx.principal-databases (that used to define the
+ * principal database used for JMX authentication) is rejected.
+ */
+ public void testManagementPrincipalDatabaseRejected() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+
+ // Check value we set
+ _config.setProperty("security.jmx.principal-database(0)", "mydb");
+ serverConfig = new ServerConfiguration(_config);
+
+ try
+ {
+ serverConfig.initialise();
+ fail("Exception not thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals("Incorrect error message",
+ "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml.",
+ ce.getMessage());
+ }
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
index 9e831b2a8e..ae58a52046 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
@@ -482,6 +482,18 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
{
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
+
+ @Override
+ public boolean isDequeued()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isDispensed()
+ {
+ return false;
+ }
};
if(action != null)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
index 5bdbe2c68e..0ba8eb4792 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
@@ -231,4 +231,16 @@ public class MockQueueEntry implements QueueEntry
_message = msg;
}
+ @Override
+ public boolean isDequeued()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isDispensed()
+ {
+ return false;
+ }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
new file mode 100644
index 0000000000..0899f25cc5
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.queue;
+
+import java.lang.reflect.Field;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry.EntryState;
+import org.apache.qpid.server.subscription.MockSubscription;
+
+/**
+ * Tests for {@link QueueEntryImpl}
+ *
+ */
+public class QueueEntryImplTest extends TestCase
+{
+ // tested entry
+ private QueueEntryImpl _queueEntry;
+
+ public void setUp() throws Exception
+ {
+ AMQMessage message = new MockAMQMessage(1);
+ SimpleQueueEntryList queueEntryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
+ _queueEntry = new QueueEntryImpl(queueEntryList, message, 1);
+ }
+
+ public void testAquire()
+ {
+ assertTrue("Queue entry should be in AVAILABLE state before invoking of acquire method",
+ _queueEntry.isAvailable());
+ acquire();
+ }
+
+ public void testDequeue()
+ {
+ dequeue();
+ }
+
+ public void testDelete()
+ {
+ delete();
+ }
+
+ /**
+ * Tests release method for entry in acquired state.
+ * <p>
+ * Entry in state ACQUIRED should be released and its status should be
+ * changed to AVAILABLE.
+ */
+ public void testReleaseAquired()
+ {
+ acquire();
+ _queueEntry.release();
+ assertTrue("Queue entry should be in AVAILABLE state after invoking of release method",
+ _queueEntry.isAvailable());
+ }
+
+ /**
+ * Tests release method for entry in dequeued state.
+ * <p>
+ * Invoking release on dequeued entry should not have any effect on its
+ * state.
+ */
+ public void testReleaseDequeued()
+ {
+ dequeue();
+ _queueEntry.release();
+ EntryState state = getState();
+ assertEquals("Invoking of release on entry in DEQUEUED state should not have any effect",
+ QueueEntry.DEQUEUED_STATE, state);
+ }
+
+ /**
+ * Tests release method for entry in deleted state.
+ * <p>
+ * Invoking release on deleted entry should not have any effect on its
+ * state.
+ */
+ public void testReleaseDeleted()
+ {
+ delete();
+ _queueEntry.release();
+ assertTrue("Invoking of release on entry in DELETED state should not have any effect",
+ _queueEntry.isDeleted());
+ }
+
+ /**
+ * Tests if entries in DEQUQUED or DELETED state are not returned by getNext method.
+ */
+ public void testGetNext()
+ {
+ int numberOfEntries = 5;
+ QueueEntryImpl[] entries = new QueueEntryImpl[numberOfEntries];
+ SimpleQueueEntryList queueEntryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
+
+ // create test entries
+ for(int i = 0; i < numberOfEntries ; i++)
+ {
+ AMQMessage message = null;;
+ try
+ {
+ message = new MockAMQMessage(i);
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to create a mock message:" + e.getMessage());
+ }
+ QueueEntryImpl entry = (QueueEntryImpl)queueEntryList.add(message);
+ entries[i] = entry;
+ }
+
+ // test getNext for not acquired entries
+ for(int i = 0; i < numberOfEntries ; i++)
+ {
+ QueueEntryImpl queueEntry = entries[i];
+ QueueEntryImpl next = queueEntry.getNext();
+ if (i < numberOfEntries - 1)
+ {
+ assertEquals("Unexpected entry from QueueEntryImpl#getNext()", entries[i + 1], next);
+ }
+ else
+ {
+ assertNull("The next entry after the last should be null", next);
+ }
+ }
+
+ // delete second
+ entries[1].acquire();
+ entries[1].delete();
+
+ // dequeue third
+ entries[2].acquire();
+ entries[2].dequeue();
+
+ QueueEntryImpl next = entries[0].getNext();
+ assertEquals("expected forth entry",entries[3], next);
+ next = next.getNext();
+ assertEquals("expected fifth entry", entries[4], next);
+ next = next.getNext();
+ assertNull("The next entry after the last should be null", next);
+ }
+ /**
+ * A helper method to put tested object into deleted state and assert the state
+ */
+ private void delete()
+ {
+ _queueEntry.delete();
+ assertTrue("Queue entry should be in DELETED state after invoking of delete method",
+ _queueEntry.isDeleted());
+ }
+
+ /**
+ * A helper method to put tested entry into dequeue state and assert the sate
+ */
+ private void dequeue()
+ {
+ acquire();
+ _queueEntry.dequeue();
+ EntryState state = getState();
+ assertEquals("Queue entry should be in DEQUEUED state after invoking of dequeue method",
+ QueueEntry.DEQUEUED_STATE, state);
+ }
+
+ /**
+ * A helper method to put tested entry into acquired state and assert the sate
+ */
+ private void acquire()
+ {
+ _queueEntry.acquire(new MockSubscription());
+ assertTrue("Queue entry should be in ACQUIRED state after invoking of acquire method",
+ _queueEntry.isAcquired());
+ }
+
+ /**
+ * A helper method to get entry state
+ *
+ * @return entry state
+ */
+ private EntryState getState()
+ {
+ EntryState state = null;
+ try
+ {
+ Field f = QueueEntryImpl.class.getDeclaredField("_state");
+ f.setAccessible(true);
+ state = (EntryState) f.get(_queueEntry);
+ }
+ catch (Exception e)
+ {
+ fail("Failure to get a state field: " + e.getMessage());
+ }
+ return state;
+ }
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index abe2d1728f..4c21f38363 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
@@ -36,13 +36,16 @@ import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue.PostEnqueueAction;
+import org.apache.qpid.server.queue.SimpleAMQQueue.QueueEntryFilter;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.subscription.MockSubscription;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.AutoCommitTransaction;
+import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -51,6 +54,8 @@ import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
public class SimpleAMQQueueTest extends InternalBrokerBaseCase
{
@@ -735,6 +740,533 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
verifyRecievedMessages(msgListSub3, sub3.getMessages());
}
+ /**
+ * Tests that dequeued message is not present in the list returned form
+ * {@link SimpleAMQQueue#getMessagesOnTheQueue()}
+ */
+ public void testGetMessagesOnTheQueueWithDequeuedEntry()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+
+ // send test messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ // get messages on the queue
+ List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
+
+ // assert queue entries
+ assertEquals(messageNumber - 1, entries.size());
+ int expectedId = 0;
+ for (int i = 0; i < messageNumber - 1; i++)
+ {
+ Long id = ((AMQMessage) entries.get(i).getMessage()).getMessageId();
+ if (i == dequeueMessageIndex)
+ {
+ assertFalse("Message with id " + dequeueMessageIndex
+ + " was dequeued and should not be returned by method getMessagesOnTheQueue!",
+ new Long(expectedId).equals(id));
+ expectedId++;
+ }
+ assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
+ new Long(expectedId), id);
+ expectedId++;
+ }
+ }
+
+ /**
+ * Tests that dequeued message is not present in the list returned form
+ * {@link SimpleAMQQueue#getMessagesOnTheQueue(QueueEntryFilter)}
+ */
+ public void testGetMessagesOnTheQueueByQueueEntryFilterWithDequeuedEntry()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+
+ // send test messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ // get messages on the queue with filter accepting all available messages
+ List<QueueEntry> entries = _queue.getMessagesOnTheQueue(new QueueEntryFilter()
+ {
+
+ @Override
+ public boolean accept(QueueEntry entry)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean filterComplete()
+ {
+ return false;
+ }
+ });
+
+ // assert entries on the queue
+ assertEquals(messageNumber - 1, entries.size());
+ int expectedId = 0;
+ for (int i = 0; i < messageNumber - 1; i++)
+ {
+ Long id = ((AMQMessage) entries.get(i).getMessage()).getMessageId();
+ if (i == dequeueMessageIndex)
+ {
+ assertFalse("Message with id " + dequeueMessageIndex
+ + " was dequeued and should not be returned by method getMessagesOnTheQueue!",
+ new Long(expectedId).equals(id));
+ expectedId++;
+ }
+ assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
+ new Long(expectedId), id);
+ expectedId++;
+ }
+ }
+
+ /**
+ * Tests that dequeued message is not copied as part of invocation of
+ * {@link SimpleAMQQueue#copyMessagesToAnotherQueue(long, long, String, StoreContext)}
+ */
+ public void testCopyMessagesWithDequeuedEntry()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+ String anotherQueueName = "testQueue2";
+
+ // put test messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ // create another queue
+ SimpleAMQQueue queue = createQueue(anotherQueueName);
+
+ // create transaction
+ ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
+
+ // copy messages into another queue
+ _queue.copyMessagesToAnotherQueue(0, messageNumber, anotherQueueName, txn);
+
+ // commit transaction
+ txn.commit();
+
+ // get messages on another queue
+ List<QueueEntry> entries = queue.getMessagesOnTheQueue();
+
+ // assert another queue entries
+ assertEquals(messageNumber - 1, entries.size());
+ int expectedId = 0;
+ for (int i = 0; i < messageNumber - 1; i++)
+ {
+ Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
+ if (i == dequeueMessageIndex)
+ {
+ assertFalse("Message with id " + dequeueMessageIndex
+ + " was dequeued and should not been copied into another queue!",
+ new Long(expectedId).equals(id));
+ expectedId++;
+ }
+ assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
+ new Long(expectedId), id);
+ expectedId++;
+ }
+ }
+
+ /**
+ * Tests that dequeued message is not moved as part of invocation of
+ * {@link SimpleAMQQueue#moveMessagesToAnotherQueue(long, long, String, StoreContext)}
+ */
+ public void testMovedMessagesWithDequeuedEntry()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+ String anotherQueueName = "testQueue2";
+
+ // put messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ // create another queue
+ SimpleAMQQueue queue = createQueue(anotherQueueName);
+
+ // create transaction
+ ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
+
+ // move messages into another queue
+ _queue.moveMessagesToAnotherQueue(0, messageNumber, anotherQueueName, txn);
+
+ // commit transaction
+ txn.commit();
+
+ // get messages on another queue
+ List<QueueEntry> entries = queue.getMessagesOnTheQueue();
+
+ // assert another queue entries
+ assertEquals(messageNumber - 1, entries.size());
+ int expectedId = 0;
+ for (int i = 0; i < messageNumber - 1; i++)
+ {
+ Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
+ if (i == dequeueMessageIndex)
+ {
+ assertFalse("Message with id " + dequeueMessageIndex
+ + " was dequeued and should not been copied into another queue!",
+ new Long(expectedId).equals(id));
+ expectedId++;
+ }
+ assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
+ new Long(expectedId), id);
+ expectedId++;
+ }
+ }
+
+ /**
+ * Tests that messages in given range including dequeued one are deleted
+ * from the queue on invocation of
+ * {@link SimpleAMQQueue#removeMessagesFromQueue(long, long, StoreContext)}
+ */
+ public void testRemoveMessagesFromQueueWithDequeuedEntry()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+
+ // put messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ // remove messages
+ _queue.removeMessagesFromQueue(0, messageNumber);
+
+ // get queue entries
+ List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
+
+ // assert queue entries
+ assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
+ assertEquals("Queue should be empty", 0, entries.size());
+ }
+
+ /**
+ * Tests that dequeued message on the top is not accounted and next message
+ * is deleted from the queue on invocation of
+ * {@link SimpleAMQQueue#deleteMessageFromTop(StoreContext)}
+ */
+ public void testDeleteMessageFromTopWithDequeuedEntryOnTop()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 0;
+
+ // put messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message on top
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ //delete message from top
+ _queue.deleteMessageFromTop();
+
+ //get queue netries
+ List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
+
+ // assert queue entries
+ assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
+ assertEquals("Expected " + (messageNumber - 2) + " number of messages but recieved " + entries.size(),
+ messageNumber - 2, entries.size());
+ assertEquals("Expected first entry with id 2", new Long(2),
+ ((AMQMessage) entries.get(0).getMessage()).getMessageId());
+ }
+
+ /**
+ * Tests that all messages including dequeued one are deleted from the queue
+ * on invocation of {@link SimpleAMQQueue#clearQueue(StoreContext)}
+ */
+ public void testClearQueueWithDequeuedEntry()
+ {
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+
+ // put messages into a test queue
+ enqueueGivenNumberOfMessages(_queue, messageNumber);
+
+ // dequeue message on a test queue
+ dequeueMessage(_queue, dequeueMessageIndex);
+
+ // clean queue
+ try
+ {
+ _queue.clearQueue();
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to clear queue:" + e.getMessage());
+ }
+
+ // get queue entries
+ List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
+
+ // assert queue entries
+ assertNotNull(entries);
+ assertEquals(0, entries.size());
+ }
+
+ /**
+ * Tests whether dequeued entry is sent to subscriber in result of
+ * invocation of {@link SimpleAMQQueue#processQueue(QueueRunner)}
+ */
+ public void testProcessQueueWithDequeuedEntry()
+ {
+ // total number of messages to send
+ int messageNumber = 4;
+ int dequeueMessageIndex = 1;
+
+ // create queue with overridden method deliverAsync
+ SimpleAMQQueue testQueue = new SimpleAMQQueue(new AMQShortString("test"), false,
+ new AMQShortString("testOwner"), false, false, _virtualHost, null)
+ {
+ @Override
+ public void deliverAsync(Subscription sub)
+ {
+ // do nothing
+ }
+ };
+
+ // put messages
+ List<QueueEntry> entries = enqueueGivenNumberOfMessages(testQueue, messageNumber);
+
+ // dequeue message
+ dequeueMessage(testQueue, dequeueMessageIndex);
+
+ // latch to wait for message receipt
+ final CountDownLatch latch = new CountDownLatch(messageNumber -1);
+
+ // create a subscription
+ MockSubscription subscription = new MockSubscription()
+ {
+ /**
+ * Send a message and decrement latch
+ */
+ public void send(QueueEntry msg) throws AMQException
+ {
+ super.send(msg);
+ latch.countDown();
+ }
+ };
+
+ try
+ {
+ // subscribe
+ testQueue.registerSubscription(subscription, false);
+
+ // process queue
+ testQueue.processQueue(new QueueRunner(testQueue, 1)
+ {
+ public void run()
+ {
+ // do nothing
+ }
+ });
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to process queue:" + e.getMessage());
+ }
+ // wait up to 1 minute for message receipt
+ try
+ {
+ latch.await(1, TimeUnit.MINUTES);
+ }
+ catch (InterruptedException e1)
+ {
+ Thread.currentThread().interrupt();
+ }
+ List<QueueEntry> expected = createEntriesList(entries.get(0), entries.get(2), entries.get(3));
+ verifyRecievedMessages(expected, subscription.getMessages());
+ }
+
+ /**
+ * Tests that entry in dequeued state are not enqueued and not delivered to subscription
+ */
+ public void testEqueueDequeuedEntry()
+ {
+ // create a queue where each even entry is considered a dequeued
+ SimpleAMQQueue queue = new SimpleAMQQueue(new AMQShortString("test"), false, new AMQShortString("testOwner"),
+ false, false, _virtualHost, new QueueEntryListFactory()
+ {
+ public QueueEntryList createQueueEntryList(AMQQueue queue)
+ {
+ /**
+ * Override SimpleQueueEntryList to create a dequeued
+ * entries for messages with even id
+ */
+ return new SimpleQueueEntryList(queue)
+ {
+ /**
+ * Entries with even message id are considered
+ * dequeued!
+ */
+ protected QueueEntryImpl createQueueEntry(final ServerMessage message)
+ {
+ return new QueueEntryImpl(this, message)
+ {
+ public boolean isDequeued()
+ {
+ return (((AMQMessage) message).getMessageId().longValue() % 2 == 0);
+ }
+
+ public boolean isDispensed()
+ {
+ return (((AMQMessage) message).getMessageId().longValue() % 2 == 0);
+ }
+
+ public boolean isAvailable()
+ {
+ return !(((AMQMessage) message).getMessageId().longValue() % 2 == 0);
+ }
+ };
+ }
+ };
+ }
+ }, null);
+ // create a subscription
+ MockSubscription subscription = new MockSubscription();
+
+ // register subscription
+ try
+ {
+ queue.registerSubscription(subscription, false);
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to register subscription:" + e.getMessage());
+ }
+
+ // put test messages into a queue
+ putGivenNumberOfMessages(queue, 4);
+
+ // assert received messages
+ List<QueueEntry> messages = subscription.getMessages();
+ assertEquals("Only 2 messages should be returned", 2, messages.size());
+ assertEquals("ID of first message should be 1", new Long(1),
+ ((AMQMessage) messages.get(0).getMessage()).getMessageId());
+ assertEquals("ID of second message should be 3", new Long(3),
+ ((AMQMessage) messages.get(1).getMessage()).getMessageId());
+ }
+
+ /**
+ * A helper method to create a queue with given name
+ *
+ * @param name
+ * queue name
+ * @return queue
+ */
+ private SimpleAMQQueue createQueue(String name)
+ {
+ SimpleAMQQueue queue = null;
+ try
+ {
+ AMQShortString queueName = new AMQShortString(name);
+ AMQShortString ownerName = new AMQShortString(name + "Owner");
+ queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(queueName, false, ownerName, false, false,
+ _virtualHost, _arguments);
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to create a queue:" + e.getMessage());
+ }
+ assertNotNull("Queue was not created", queue);
+ return queue;
+ }
+
+ /**
+ * A helper method to put given number of messages into queue
+ * <p>
+ * All messages are asserted that they are present on queue
+ *
+ * @param queue
+ * queue to put messages into
+ * @param messageNumber
+ * number of messages to put into queue
+ */
+ private List<QueueEntry> enqueueGivenNumberOfMessages(AMQQueue queue, int messageNumber)
+ {
+ putGivenNumberOfMessages(queue, messageNumber);
+
+ // make sure that all enqueued messages are on the queue
+ List<QueueEntry> entries = queue.getMessagesOnTheQueue();
+ assertEquals(messageNumber, entries.size());
+ for (int i = 0; i < messageNumber; i++)
+ {
+ assertEquals(new Long(i), ((AMQMessage)entries.get(i).getMessage()).getMessageId());
+ }
+ return entries;
+ }
+
+ /**
+ * A helper method to put given number of messages into queue
+ * <p>
+ * Queue is not checked if messages are added into queue
+ *
+ * @param queue
+ * queue to put messages into
+ * @param messageNumber
+ * number of messages to put into queue
+ * @param queue
+ * @param messageNumber
+ */
+ private void putGivenNumberOfMessages(AMQQueue queue, int messageNumber)
+ {
+ for (int i = 0; i < messageNumber; i++)
+ {
+ // Create message
+ Long messageId = new Long(i);
+ AMQMessage message = null;
+ try
+ {
+ message = createMessage(messageId);
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to create a test message:" + e.getMessage());
+ }
+ // Put message on queue
+ try
+ {
+ queue.enqueue(message);
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to put message on queue:" + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * A helper method to dequeue an entry on queue with given index
+ *
+ * @param queue
+ * queue to dequeue message on
+ * @param dequeueMessageIndex
+ * entry index to dequeue.
+ */
+ private QueueEntry dequeueMessage(AMQQueue queue, int dequeueMessageIndex)
+ {
+ List<QueueEntry> entries = queue.getMessagesOnTheQueue();
+ QueueEntry entry = entries.get(dequeueMessageIndex);
+ entry.acquire();
+ entry.dequeue();
+ assertTrue(entry.isDequeued());
+ return entry;
+ }
+
private List<QueueEntry> createEntriesList(QueueEntry... entries)
{
ArrayList<QueueEntry> entriesList = new ArrayList<QueueEntry>();
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
index 320a75045a..7136f07ca5 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.queue;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import org.apache.qpid.AMQException;
import org.apache.qpid.server.message.AMQMessage;
import junit.framework.TestCase;
@@ -155,5 +156,55 @@ public class SimpleQueueEntryListTest extends TestCase
assertEquals("Count should have been equal",count,remainingMessages.size());
}
-
+
+ public void testDequedMessagedNotPresentInIterator()
+ {
+ int numberOfMessages = 10;
+ SimpleQueueEntryList entryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
+ QueueEntry[] entries = new QueueEntry[numberOfMessages];
+
+ for(int i = 0; i < numberOfMessages ; i++)
+ {
+ AMQMessage message = null;;
+ try
+ {
+ message = new MockAMQMessage(i);
+ }
+ catch (AMQException e)
+ {
+ fail("Failure to create a mock message:" + e.getMessage());
+ }
+ QueueEntry entry = entryList.add(message);
+ assertNotNull("QE should not be null", entry);
+ entries[i]= entry;
+ }
+
+ // dequeue all even messages
+ for (QueueEntry queueEntry : entries)
+ {
+ long i = ((AMQMessage)queueEntry.getMessage()).getMessageId().longValue();
+ if (i%2 == 0)
+ {
+ queueEntry.acquire();
+ queueEntry.dequeue();
+ }
+ }
+
+ // iterate and check that dequeued messages are not returned by iterator
+ QueueEntryIterator it = entryList.iterator();
+ int counter = 0;
+ int i = 1;
+ while (it.advance())
+ {
+ QueueEntry entry = it.getNode();
+ Long id = ((AMQMessage)entry.getMessage()).getMessageId();
+ assertEquals("Expected message with id " + i + " but got message with id "
+ + id, new Long(i), id);
+ counter++;
+ i += 2;
+ }
+ int expectedNumber = numberOfMessages / 2;
+ assertEquals("Expected " + expectedNumber + " number of entries in iterator but got " + counter,
+ expectedNumber, counter);
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
index f51ce0b6c6..5a9026cb64 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
@@ -23,11 +23,13 @@ package org.apache.qpid.server.security.auth.manager;
import java.security.Provider;
import java.security.Security;
+import javax.security.auth.Subject;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
/**
@@ -89,17 +91,18 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
}
/**
- *
* Tests that the authenticate method correctly interprets an
* authentication success.
*
*/
- public void testAuthenticationSuccess() throws Exception
+ public void testSaslAuthenticationSuccess() throws Exception
{
SaslServer testServer = createTestSaslServer(true, false);
AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertEquals(AuthenticationStatus.SUCCESS, result.status);
+ final Subject subject = result.getSubject();
+ assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
+ assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
}
/**
@@ -108,12 +111,13 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
* authentication not complete.
*
*/
- public void testAuthenticationNotCompleted() throws Exception
+ public void testSaslAuthenticationNotCompleted() throws Exception
{
SaslServer testServer = createTestSaslServer(false, false);
AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertEquals(AuthenticationStatus.CONTINUE, result.status);
+ assertNull(result.getSubject());
+ assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
}
/**
@@ -122,12 +126,39 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
* authentication error.
*
*/
- public void testAuthenticationError() throws Exception
+ public void testSaslAuthenticationError() throws Exception
{
SaslServer testServer = createTestSaslServer(false, true);
AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertEquals(AuthenticationStatus.ERROR, result.status);
+ assertNull(result.getSubject());
+ assertEquals(AuthenticationStatus.ERROR, result.getStatus());
+ }
+
+ /**
+ * Tests that the authenticate method correctly interprets an
+ * authentication success.
+ *
+ */
+ public void testNonSaslAuthenticationSuccess() throws Exception
+ {
+ AuthenticationResult result = _manager.authenticate("guest", "guest");
+ final Subject subject = result.getSubject();
+ assertFalse("Subject should not be set read-only", subject.isReadOnly());
+ assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
+ assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
+ }
+
+ /**
+ * Tests that the authenticate method correctly interprets an
+ * authentication success.
+ *
+ */
+ public void testNonSaslAuthenticationNotCompleted() throws Exception
+ {
+ AuthenticationResult result = _manager.authenticate("guest", "wrongpassword");
+ assertNull(result.getSubject());
+ assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
}
/**
@@ -179,7 +210,7 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
@Override
public String getAuthorizationID()
{
- return null;
+ return complete ? "guest" : null;
}
@Override
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
index e8c24da68d..eb713e3712 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
@@ -20,188 +20,124 @@
*/
package org.apache.qpid.server.security.auth.rmi;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
import java.util.Collections;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import junit.framework.TestCase;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+
+/**
+ * Tests the RMIPasswordAuthenticator and its collaboration with the AuthenticationManager.
+ *
+ */
public class RMIPasswordAuthenticatorTest extends TestCase
{
private final String USERNAME = "guest";
private final String PASSWORD = "guest";
- private final String B64_MD5HASHED_PASSWORD = "CE4DQ6BIb/BVMN9scFyLtA==";
private RMIPasswordAuthenticator _rmipa;
-
- private Base64MD5PasswordFilePrincipalDatabase _md5Pd;
- private File _md5PwdFile;
-
- private PlainPasswordFilePrincipalDatabase _plainPd;
- private File _plainPwdFile;
-
- private Subject testSubject;
+ private String[] _credentials;
protected void setUp() throws Exception
{
_rmipa = new RMIPasswordAuthenticator();
- _md5Pd = new Base64MD5PasswordFilePrincipalDatabase();
- _md5PwdFile = createTempPasswordFile(this.getClass().getName()+"md5pwd", USERNAME, B64_MD5HASHED_PASSWORD);
- _md5Pd.setPasswordFile(_md5PwdFile.getAbsolutePath());
-
- _plainPd = new PlainPasswordFilePrincipalDatabase();
- _plainPwdFile = createTempPasswordFile(this.getClass().getName()+"plainpwd", USERNAME, PASSWORD);
- _plainPd.setPasswordFile(_plainPwdFile.getAbsolutePath());
-
- testSubject = new Subject(true,
+ _credentials = new String[] {USERNAME, PASSWORD};
+ }
+
+ /**
+ * Tests a successful authentication. Ensures that a populated read-only subject it returned.
+ */
+ public void testAuthenticationSuccess()
+ {
+ final Subject expectedSubject = new Subject(true,
Collections.singleton(new JMXPrincipal(USERNAME)),
Collections.EMPTY_SET,
Collections.EMPTY_SET);
- }
-
- private File createTempPasswordFile(String filenamePrefix, String user, String password)
- {
- try
- {
- File testFile = File.createTempFile(filenamePrefix,"tmp");
- testFile.deleteOnExit();
- BufferedWriter writer = new BufferedWriter(new FileWriter(testFile));
+ _rmipa.setAuthenticationManager(createTestAuthenticationManager(true, null));
- writer.write(user + ":" + password);
- writer.newLine();
- writer.flush();
- writer.close();
-
- return testFile;
- }
- catch (IOException e)
- {
- fail("Unable to create temporary test password file." + e.getMessage());
- }
+ Subject newSubject = _rmipa.authenticate(_credentials);
+ assertTrue("Subject must be readonly", newSubject.isReadOnly());
+ assertTrue("Returned subject does not equal expected value",
+ newSubject.equals(expectedSubject));
- return null;
}
-
-
- //********** Test Methods *********//
-
- public void testAuthenticate()
+ /**
+ * Tests a unsuccessful authentication.
+ */
+ public void testUsernameOrPasswordInvalid()
{
- String[] credentials;
- Subject newSubject;
-
- // Test when no PD has been set
- try
- {
- credentials = new String[]{USERNAME, PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
- fail("SecurityException expected due to lack of principal database");
- }
- catch (SecurityException se)
- {
- assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
- }
-
- //The PrincipalDatabase's are tested primarily by their own tests, but
- //minimal tests are done here to exercise their usage in this area.
+ _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, null));
- // Test correct passwords are verified with an MD5 PD
try
{
- _rmipa.setPrincipalDatabase(_md5Pd);
- credentials = new String[]{USERNAME, PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
- assertTrue("Returned subject does not equal expected value",
- newSubject.equals(testSubject));
- }
- catch (Exception e)
- {
- fail("Unexpected Exception:" + e.getMessage());
- }
-
- // Test incorrect passwords are not verified with an MD5 PD
- try
- {
- credentials = new String[]{USERNAME, PASSWORD+"incorrect"};
- newSubject = _rmipa.authenticate(credentials);
- fail("SecurityException expected due to incorrect password");
+ _rmipa.authenticate(_credentials);
+ fail("Exception not thrown");
}
catch (SecurityException se)
{
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
- }
-
- // Test non-existent accounts are not verified with an MD5 PD
- try
- {
- credentials = new String[]{USERNAME+"invalid", PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
- fail("SecurityException expected due to non-existant account");
- }
- catch (SecurityException se)
- {
- assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
- }
- // Test correct passwords are verified with a Plain PD
- try
- {
- _rmipa.setPrincipalDatabase(_plainPd);
- credentials = new String[]{USERNAME, PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
- assertTrue("Returned subject does not equal expected value",
- newSubject.equals(testSubject));
- }
- catch (Exception e)
- {
- fail("Unexpected Exception");
}
+ }
+
+ /**
+ * Tests case where authentication system itself fails.
+ */
+ public void testAuthenticationFailure()
+ {
+ final Exception mockAuthException = new Exception("Mock Auth system failure");
+ _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, mockAuthException));
- // Test incorrect passwords are not verified with a Plain PD
try
{
- credentials = new String[]{USERNAME, PASSWORD+"incorrect"};
- newSubject = _rmipa.authenticate(credentials);
- fail("SecurityException expected due to incorrect password");
+ _rmipa.authenticate(_credentials);
+ fail("Exception not thrown");
}
catch (SecurityException se)
{
- assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ assertEquals("Initial cause not found", mockAuthException, se.getCause());
}
-
- // Test non-existent accounts are not verified with an Plain PD
+ }
+
+
+ /**
+ * Tests case where authentication manager is not set.
+ */
+ public void testNullAuthenticationManager()
+ {
try
{
- credentials = new String[]{USERNAME+"invalid", PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
- fail("SecurityException expected due to non existant account");
+ _rmipa.authenticate(_credentials);
+ fail("SecurityException expected due to lack of authentication manager");
}
catch (SecurityException se)
{
assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
}
+ }
+ /**
+ * Tests case where arguments are non-Strings..
+ */
+ public void testWithNonStringArrayArgument()
+ {
// Test handling of non-string credential's
+ final Object[] objCredentials = new Object[]{USERNAME, PASSWORD};
try
{
- Object[] objCredentials = new Object[]{USERNAME, PASSWORD};
- newSubject = _rmipa.authenticate(objCredentials);
+ _rmipa.authenticate(objCredentials);
fail("SecurityException expected due to non string[] credentials");
}
catch (SecurityException se)
@@ -209,12 +145,18 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.SHOULD_BE_STRING_ARRAY, se.getMessage());
}
-
- // Test handling of incorrect number of credential's
+ }
+
+ /**
+ * Tests case where there are too many, too few or null arguments.
+ */
+ public void testWithIllegalNumberOfArguments()
+ {
+ // Test handling of incorrect number of credentials
try
{
- credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
+ _credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
+ _rmipa.authenticate(_credentials);
fail("SecurityException expected due to supplying wrong number of credentials");
}
catch (SecurityException se)
@@ -223,12 +165,12 @@ public class RMIPasswordAuthenticatorTest extends TestCase
RMIPasswordAuthenticator.SHOULD_HAVE_2_ELEMENTS, se.getMessage());
}
- // Test handling of null credential's
+ // Test handling of null credentials
try
{
//send a null array
- credentials = null;
- newSubject = _rmipa.authenticate(credentials);
+ _credentials = null;
+ _rmipa.authenticate(_credentials);
fail("SecurityException expected due to not supplying an array of credentials");
}
catch (SecurityException se)
@@ -240,8 +182,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null password
- credentials = new String[]{USERNAME, null};
- newSubject = _rmipa.authenticate(credentials);
+ _credentials = new String[]{USERNAME, null};
+ _rmipa.authenticate(_credentials);
fail("SecurityException expected due to sending a null password");
}
catch (SecurityException se)
@@ -253,8 +195,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null username
- credentials = new String[]{null, PASSWORD};
- newSubject = _rmipa.authenticate(credentials);
+ _credentials = new String[]{null, PASSWORD};
+ _rmipa.authenticate(_credentials);
fail("SecurityException expected due to sending a null username");
}
catch (SecurityException se)
@@ -264,4 +206,50 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
}
+ private AuthenticationManager createTestAuthenticationManager(final boolean successfulAuth, final Exception exception)
+ {
+ return new AuthenticationManager()
+ {
+ @Override
+ public void close()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getMechanisms()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+ if (exception != null) {
+ return new AuthenticationResult(AuthenticationStatus.ERROR, exception);
+ }
+ else if (successfulAuth)
+ {
+ return new AuthenticationResult(new Subject());
+ }
+ else
+ {
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+ }
+ };
+ }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java
new file mode 100644
index 0000000000..8bff22115e
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java
@@ -0,0 +1,124 @@
+/*
+ *
+ * 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.security.auth.sasl;
+
+import java.security.Principal;
+import javax.security.auth.Subject;
+import junit.framework.TestCase;
+
+/**
+ * Tests the UsernamePrincipal.
+ *
+ */
+public class UsernamePrincipalTest extends TestCase
+{
+ public void testEqualitySameObject()
+ {
+ final UsernamePrincipal principal = new UsernamePrincipal("string");
+ assertTrue(principal.equals(principal));
+ }
+
+ public void testEqualitySameName()
+ {
+ final String string = "string";
+ final UsernamePrincipal principal1 = new UsernamePrincipal(string);
+ final UsernamePrincipal principal2 = new UsernamePrincipal(string);
+ assertTrue(principal1.equals(principal2));
+ }
+
+ public void testEqualityEqualName()
+ {
+ final UsernamePrincipal principal1 = new UsernamePrincipal(new String("string"));
+ final UsernamePrincipal principal2 = new UsernamePrincipal(new String("string"));
+ assertTrue(principal1.equals(principal2));
+ }
+
+ public void testInequalityDifferentUserPrincipals()
+ {
+ UsernamePrincipal principal1 = new UsernamePrincipal("string1");
+ UsernamePrincipal principal2 = new UsernamePrincipal("string2");
+ assertFalse(principal1.equals(principal2));
+ }
+
+ public void testInequalityNonUserPrincipal()
+ {
+ UsernamePrincipal principal = new UsernamePrincipal("string");
+ assertFalse(principal.equals(new String("string")));
+ }
+
+ public void testInequalityNull()
+ {
+ UsernamePrincipal principal = new UsernamePrincipal("string");
+ assertFalse(principal.equals(null));
+ }
+
+ public void testGetUsernamePrincipalFromSubject()
+ {
+ final UsernamePrincipal expected = new UsernamePrincipal("name");
+ final Principal other = new Principal()
+ {
+
+ @Override
+ public String getName()
+ {
+ return "otherprincipal";
+ }
+ };
+
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(expected);
+ subject.getPrincipals().add(other);
+
+ final UsernamePrincipal actual = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
+ assertSame(expected, actual);
+ }
+
+ public void testUsernamePrincipalNotInSubject()
+ {
+ try
+ {
+ UsernamePrincipal.getUsernamePrincipalFromSubject(new Subject());
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // PASS
+ }
+ }
+
+ public void testTooManyUsernamePrincipalInSubject()
+ {
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new UsernamePrincipal("name1"));
+ subject.getPrincipals().add(new UsernamePrincipal("name2"));
+ try
+ {
+
+ UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // PASS
+ }
+ }
+
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index ab59fee020..94a55ef52c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -111,7 +111,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/** Maps from session id (Integer) to AMQSession instance */
private final ChannelToSessionMap _sessions = new ChannelToSessionMap();
- private String _clientName;
+ private final String _clientName;
/** The user name to use for authentication */
private String _username;
@@ -126,7 +126,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
private ConnectionListener _connectionListener;
- private ConnectionURL _connectionURL;
+ private final ConnectionURL _connectionURL;
/**
* Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for message
@@ -257,6 +257,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
*/
public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
+ if (connectionURL == null)
+ {
+ throw new IllegalArgumentException("Connection must be specified");
+ }
+
// set this connection maxPrefetch
if (connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH) != null)
{
@@ -264,7 +269,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the defaul value set for all connections
+ // use the default value set for all connections
_maxPrefetch = Integer.parseInt(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME,
ClientProperties.MAX_PREFETCH_DEFAULT));
}
@@ -278,7 +283,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the defaul value set for all connections
+ // use the default value set for all connections
_syncPersistence = Boolean.getBoolean(ClientProperties.SYNC_PERSISTENT_PROP_NAME);
if (_syncPersistence)
{
@@ -293,7 +298,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the defaul value set for all connections
+ // use the default value set for all connections
_syncAck = Boolean.getBoolean(ClientProperties.SYNC_ACK_PROP_NAME);
}
@@ -346,11 +351,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
_sslConfiguration = sslConfig;
- if (connectionURL == null)
- {
- throw new IllegalArgumentException("Connection must be specified");
- }
-
_connectionURL = connectionURL;
_clientName = connectionURL.getClientName();
@@ -535,14 +535,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
- protected AMQConnection(String username, String password, String clientName, String virtualHost)
- {
- _clientName = clientName;
- _username = username;
- _password = password;
- setVirtualHost(virtualHost);
- }
-
private void setVirtualHost(String virtualHost)
{
if (virtualHost != null && virtualHost.startsWith("/"))
@@ -696,20 +688,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
- private void reopenChannel(int channelId, int prefetchHigh, int prefetchLow, boolean transacted)
- throws AMQException, FailoverException
- {
- try
- {
- createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
- }
- catch (AMQException e)
- {
- deregisterSession(channelId);
- throw new AMQException(null, "Error reopening channel " + channelId + " after failover: " + e, e);
- }
- }
-
public void setFailoverPolicy(FailoverPolicy policy)
{
_failoverPolicy = policy;
@@ -1372,6 +1350,20 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return buf.toString();
}
+ /**
+ * Returns connection url.
+ * @return connection url
+ */
+ public ConnectionURL getConnectionURL()
+ {
+ return _connectionURL;
+ }
+
+ /**
+ * Returns stringified connection url. This url is suitable only for display
+ * as {@link AMQConnectionURL#toString()} converts any password to asterisks.
+ * @return connection url
+ */
public String toURL()
{
return _connectionURL.toString();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
index eb9682a3cf..3ef32fb008 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
@@ -21,8 +21,6 @@
package org.apache.qpid.client;
import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
import javax.jms.Destination;
@@ -34,8 +32,6 @@ import javax.naming.StringRefAddr;
import org.apache.qpid.client.messaging.address.AddressHelper;
import org.apache.qpid.client.messaging.address.Link;
import org.apache.qpid.client.messaging.address.Node;
-import org.apache.qpid.client.messaging.address.QpidExchangeOptions;
-import org.apache.qpid.client.messaging.address.QpidQueueOptions;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -78,11 +74,6 @@ public abstract class AMQDestination implements Destination, Referenceable
private boolean _exchangeExistsChecked;
- private byte[] _byteEncoding;
- private static final int IS_DURABLE_MASK = 0x1;
- private static final int IS_EXCLUSIVE_MASK = 0x2;
- private static final int IS_AUTODELETE_MASK = 0x4;
-
public static final int QUEUE_TYPE = 1;
public static final int TOPIC_TYPE = 2;
public static final int UNKNOWN_TYPE = 3;
@@ -323,7 +314,11 @@ public abstract class AMQDestination implements Destination, Referenceable
{
if(_urlAsShortString == null)
{
- toURL();
+ if (_url == null)
+ {
+ toURL();
+ }
+ _urlAsShortString = new AMQShortString(_url);
}
return _urlAsShortString;
}
@@ -370,7 +365,6 @@ public abstract class AMQDestination implements Destination, Referenceable
// calculated URL now out of date
_url = null;
_urlAsShortString = null;
- _byteEncoding = null;
}
public AMQShortString getRoutingKey()
@@ -508,59 +502,10 @@ public abstract class AMQDestination implements Destination, Referenceable
sb.deleteCharAt(sb.length() - 1);
url = sb.toString();
_url = url;
- _urlAsShortString = new AMQShortString(url);
}
return url;
}
- public byte[] toByteEncoding()
- {
- byte[] encoding = _byteEncoding;
- if(encoding == null)
- {
- int size = _exchangeClass.length() + 1 +
- _exchangeName.length() + 1 +
- 0 + // in place of the destination name
- (_queueName == null ? 0 : _queueName.length()) + 1 +
- 1;
- encoding = new byte[size];
- int pos = 0;
-
- pos = _exchangeClass.writeToByteArray(encoding, pos);
- pos = _exchangeName.writeToByteArray(encoding, pos);
-
- encoding[pos++] = (byte)0;
-
- if(_queueName == null)
- {
- encoding[pos++] = (byte)0;
- }
- else
- {
- pos = _queueName.writeToByteArray(encoding,pos);
- }
- byte options = 0;
- if(_isDurable)
- {
- options |= IS_DURABLE_MASK;
- }
- if(_isExclusive)
- {
- options |= IS_EXCLUSIVE_MASK;
- }
- if(_isAutoDelete)
- {
- options |= IS_AUTODELETE_MASK;
- }
- encoding[pos] = options;
-
-
- _byteEncoding = encoding;
-
- }
- return encoding;
- }
-
public boolean equals(Object o)
{
if (this == o)
@@ -614,53 +559,6 @@ public abstract class AMQDestination implements Destination, Referenceable
null); // factory location
}
-
- public static Destination createDestination(byte[] byteEncodedDestination)
- {
- AMQShortString exchangeClass;
- AMQShortString exchangeName;
- AMQShortString routingKey;
- AMQShortString queueName;
- boolean isDurable;
- boolean isExclusive;
- boolean isAutoDelete;
-
- int pos = 0;
- exchangeClass = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
- pos+= exchangeClass.length() + 1;
- exchangeName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
- pos+= exchangeName.length() + 1;
- routingKey = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
- pos+= (routingKey == null ? 0 : routingKey.length()) + 1;
- queueName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
- pos+= (queueName == null ? 0 : queueName.length()) + 1;
- int options = byteEncodedDestination[pos];
- isDurable = (options & IS_DURABLE_MASK) != 0;
- isExclusive = (options & IS_EXCLUSIVE_MASK) != 0;
- isAutoDelete = (options & IS_AUTODELETE_MASK) != 0;
-
- if (exchangeClass.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
- {
- return new AMQQueue(exchangeName,routingKey,queueName,isExclusive,isAutoDelete,isDurable);
- }
- else if (exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
- {
- return new AMQTopic(exchangeName,routingKey,isAutoDelete,queueName,isDurable);
- }
- else if (exchangeClass.equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS))
- {
- return new AMQHeadersExchange(routingKey);
- }
- else
- {
- return new AMQAnyDestination(exchangeName,exchangeClass,
- routingKey,isExclusive,
- isAutoDelete,queueName,
- isDurable, new AMQShortString[0]);
- }
-
- }
-
public static Destination createDestination(BindingURL binding)
{
AMQShortString type = binding.getExchangeClass();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
index c81ad6422f..2b49bb8f81 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
@@ -226,7 +226,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co
{
Object instance = mechanismClass.newInstance();
AMQCallbackHandler cbh = (AMQCallbackHandler) instance;
- cbh.initialise(protocolSession);
+ cbh.initialise(protocolSession.getAMQConnection().getConnectionURL());
return cbh;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
index 7976760696..5b7d272506 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
@@ -148,16 +148,6 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
return getAMQConnection().getVirtualHost();
}
- public String getUsername()
- {
- return getAMQConnection().getUsername();
- }
-
- public String getPassword()
- {
- return getAMQConnection().getPassword();
- }
-
public SaslClient getSaslClient()
{
return _saslClient;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
index fbca444208..67dd1a58b6 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
@@ -22,9 +22,9 @@ package org.apache.qpid.client.security;
import javax.security.auth.callback.CallbackHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
+import org.apache.qpid.jms.ConnectionURL;
public interface AMQCallbackHandler extends CallbackHandler
{
- void initialise(AMQProtocolSession protocolSession);
+ void initialise(ConnectionURL connectionURL);
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
index 66176dac3c..6ec83f0a23 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
@@ -20,30 +20,29 @@
*/
package org.apache.qpid.client.security;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import org.apache.qpid.jms.ConnectionURL;
public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
{
- private static final Logger _logger = LoggerFactory.getLogger(UsernameHashedPasswordCallbackHandler.class);
+ private ConnectionURL _connectionURL;
- private AMQProtocolSession _protocolSession;
-
- public void initialise(AMQProtocolSession protocolSession)
+ /**
+ * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
+ */
+ @Override
+ public void initialise(ConnectionURL connectionURL)
{
- _protocolSession = protocolSession;
+ _connectionURL = connectionURL;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -53,13 +52,13 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback) cb).setName(_protocolSession.getUsername());
+ ((NameCallback) cb).setName(_connectionURL.getUsername());
}
else if (cb instanceof PasswordCallback)
{
try
{
- ((PasswordCallback) cb).setPassword(getHash(_protocolSession.getPassword()));
+ ((PasswordCallback) cb).setPassword(getHash(_connectionURL.getPassword()));
}
catch (NoSuchAlgorithmException e)
{
@@ -99,4 +98,5 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
return hash;
}
+
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
index c50c62710f..ad088722c8 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
@@ -27,15 +27,19 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
+import org.apache.qpid.jms.ConnectionURL;
public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
{
- private AMQProtocolSession _protocolSession;
+ private ConnectionURL _connectionURL;
- public void initialise(AMQProtocolSession protocolSession)
+ /**
+ * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
+ */
+ @Override
+ public void initialise(final ConnectionURL connectionURL)
{
- _protocolSession = protocolSession;
+ _connectionURL = connectionURL;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -45,11 +49,11 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback)cb).setName(_protocolSession.getUsername());
+ ((NameCallback)cb).setName(_connectionURL.getUsername());
}
else if (cb instanceof PasswordCallback)
{
- ((PasswordCallback)cb).setPassword(_protocolSession.getPassword().toCharArray());
+ ((PasswordCallback)cb).setPassword(_connectionURL.getPassword().toCharArray());
}
else
{
@@ -57,4 +61,5 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
}
}
}
+
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
index b7b6bd57bc..574a1b3888 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
@@ -19,6 +19,7 @@ package org.apache.qpid.filter;
import java.util.HashMap;
+import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import org.apache.qpid.AMQInternalException;
@@ -32,7 +33,7 @@ import org.slf4j.LoggerFactory;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static final int NON_PERSISTENT = 1;
+ private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class);
@@ -79,22 +80,24 @@ public class PropertyExpression implements Expression
{
public Object evaluate(AbstractJMSMessage message)
{
+
+ JMSDeliveryMode mode = JMSDeliveryMode.NON_PERSISTENT;
try
{
- int mode = message.getJMSDeliveryMode();
+ mode = message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ?
+ JMSDeliveryMode.PERSISTENT : JMSDeliveryMode.NON_PERSISTENT;
+
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
-
- return mode;
}
catch (JMSException e)
{
_logger.warn("Error evaluating property",e);
}
- return NON_PERSISTENT;
+ return mode.toString();
}
});
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
index da44822ec3..5972bf3fae 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
@@ -79,11 +79,6 @@ public class MockAMQConnection extends AMQConnection
super(connectionURL, sslConfig);
}
- protected MockAMQConnection(String username, String password, String clientName, String virtualHost)
- {
- super(username, password, clientName, virtualHost);
- }
-
@Override
public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException
{
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
new file mode 100644
index 0000000000..98fc09c25b
--- /dev/null
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
@@ -0,0 +1,99 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.security;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+/**
+ * Unit tests for the UsernameHashPasswordCallbackHandler. This callback handler is
+ * used by the CRAM-MD5-HASHED SASL mechanism.
+ *
+ */
+public class UsernameHashedPasswordCallbackHandlerTest extends TestCase
+{
+ private AMQCallbackHandler _callbackHandler = new UsernameHashedPasswordCallbackHandler(); // Class under test
+ private static final String PROMPT_UNUSED = "unused";
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ final String url = "amqp://username:password@client/test?brokerlist='vm://:1'";
+ _callbackHandler.initialise(new AMQConnectionURL(url));
+ }
+
+ /**
+ * Tests that the callback handler can correctly retrieve the username from the connection url.
+ */
+ public void testNameCallback() throws Exception
+ {
+ final String expectedName = "username";
+ NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
+
+ assertNull("Unexpected name before test", nameCallback.getName());
+ _callbackHandler.handle(new Callback[] {nameCallback});
+ assertEquals("Unexpected name", expectedName, nameCallback.getName());
+ }
+
+ /**
+ * Tests that the callback handler can correctly retrieve the password from the connection url
+ * and calculate a MD5.
+ */
+ public void testDigestedPasswordCallback() throws Exception
+ {
+ final char[] expectedPasswordDigested = getHashPassword("password");
+
+ PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
+ assertNull("Unexpected password before test", passwordCallback.getPassword());
+ _callbackHandler.handle(new Callback[] {passwordCallback});
+ assertTrue("Unexpected password", Arrays.equals(expectedPasswordDigested, passwordCallback.getPassword()));
+ }
+
+ private char[] getHashPassword(final String password) throws Exception
+ {
+ MessageDigest md5Digester = MessageDigest.getInstance("MD5");
+ final byte[] digest = md5Digester.digest(password.getBytes("UTF-8"));
+
+ char[] hash = new char[digest.length];
+
+ int index = 0;
+ for (byte b : digest)
+ {
+ hash[index++] = (char) b;
+ }
+
+ return hash;
+ }
+}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java
new file mode 100644
index 0000000000..05a60fbef7
--- /dev/null
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.security;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+/**
+ * Unit tests for the UsernamePasswordCallbackHandler.
+ *
+ */
+public class UsernamePasswordCallbackHandlerTest extends TestCase
+{
+ private AMQCallbackHandler _callbackHandler = new UsernamePasswordCallbackHandler(); // Class under test
+ private static final String PROMPT_UNUSED = "unused";
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ final String url = "amqp://username:password@client/test?brokerlist='vm://:1'";
+
+ _callbackHandler.initialise(new AMQConnectionURL(url));
+ }
+
+ /**
+ * Tests that the callback handler can correctly retrieve the username from the connection url.
+ */
+ public void testNameCallback() throws Exception
+ {
+ final String expectedName = "username";
+ NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
+
+ assertNull("Unexpected name before test", nameCallback.getName());
+ _callbackHandler.handle(new Callback[] {nameCallback});
+ assertEquals("Unexpected name", expectedName, nameCallback.getName());
+ }
+
+ /**
+ * Tests that the callback handler can correctly retrieve the password from the connection url.
+ */
+ public void testPasswordCallback() throws Exception
+ {
+ final String expectedPassword = "password";
+ PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
+ assertNull("Unexpected password before test", passwordCallback.getPassword());
+ _callbackHandler.handle(new Callback[] {passwordCallback});
+ assertEquals("Unexpected password", expectedPassword, new String(passwordCallback.getPassword()));
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
index ef9420ba87..2f6290b55a 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
@@ -54,6 +54,7 @@ public class AMQChannelException extends AMQException
public AMQFrame getCloseFrame(int channel)
{
MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor));
- return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode() == null ? AMQConstant.INTERNAL_ERROR.getCode() : getErrorCode().getCode(), new AMQShortString(getMessage()),_classId,_methodId));
+ return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode() == null ? AMQConstant.INTERNAL_ERROR.getCode() : getErrorCode().getCode(), getMessageAsShortString(),_classId,_methodId));
}
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
index 8ef6facef1..ca9c9f9dc4 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
@@ -62,9 +62,10 @@ public class AMQConnectionException extends AMQException
MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor));
return new AMQFrame(0,
reg.createConnectionCloseBody(getErrorCode().getCode(),
- new AMQShortString(getMessage()),
+ getMessageAsShortString(),
_classId,
_methodId));
}
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
index b0c6fccc9e..86d439d269 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
/**
@@ -121,4 +122,19 @@ public class AMQException extends Exception
return newAMQE;
}
+
+ /**
+ * Truncates the exception message to 255 characters if its length exceeds 255.
+ *
+ * @return exception message
+ */
+ public AMQShortString getMessageAsShortString()
+ {
+ String message = getMessage();
+ if (message != null && message.length() > AMQShortString.MAX_LENGTH)
+ {
+ message = message.substring(0, AMQShortString.MAX_LENGTH - 3) + "...";
+ }
+ return new AMQShortString(message);
+ }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index 39a9beb9e8..2b9e2ffaba 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -37,6 +37,10 @@ import java.lang.ref.WeakReference;
*/
public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
{
+ /**
+ * The maximum number of octets in AMQ short string as defined in AMQP specification
+ */
+ public static final int MAX_LENGTH = 255;
private static final byte MINUS = (byte)'-';
private static final byte ZERO = (byte) '0';
@@ -118,22 +122,19 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString(byte[] data)
{
-
+ if (data == null)
+ {
+ throw new NullPointerException("Cannot create AMQShortString with null data[]");
+ }
+ if (data.length > MAX_LENGTH)
+ {
+ throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
+ }
_data = data.clone();
_length = data.length;
_offset = 0;
}
- public AMQShortString(byte[] data, int pos)
- {
- final int size = data[pos++];
- final byte[] dataCopy = new byte[size];
- System.arraycopy(data,pos,dataCopy,0,size);
- _length = size;
- _data = dataCopy;
- _offset = 0;
- }
-
public AMQShortString(String data)
{
this((data == null) ? EMPTY_CHAR_ARRAY : data.toCharArray());
@@ -146,7 +147,12 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
{
throw new NullPointerException("Cannot create AMQShortString with null char[]");
}
-
+ // the current implementation of 0.8/0.9.x short string encoding
+ // supports only ASCII characters
+ if (data.length> MAX_LENGTH)
+ {
+ throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
+ }
final int length = data.length;
final byte[] stringBytes = new byte[length];
int hash = 0;
@@ -165,6 +171,17 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString(CharSequence charSequence)
{
+ if (charSequence == null)
+ {
+ // it should be possible to create short string for null data
+ charSequence = "";
+ }
+ // the current implementation of 0.8/0.9.x short string encoding
+ // supports only ASCII characters
+ if (charSequence.length() > MAX_LENGTH)
+ {
+ throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
+ }
final int length = charSequence.length();
final byte[] stringBytes = new byte[length];
int hash = 0;
@@ -184,6 +201,10 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString(ByteBuffer data, final int length)
{
+ if (length > MAX_LENGTH)
+ {
+ throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
+ }
if(data.isDirect() || data.isReadOnly())
{
byte[] dataBytes = new byte[length];
@@ -205,8 +226,17 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString(final byte[] data, final int from, final int to)
{
+ if (data == null)
+ {
+ throw new NullPointerException("Cannot create AMQShortString with null data[]");
+ }
+ int length = to - from;
+ if (length > MAX_LENGTH)
+ {
+ throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
+ }
_offset = from;
- _length = to - from;
+ _length = length;
_data = data;
}
@@ -245,29 +275,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
return new CharSubSequence(start, end);
}
- public int writeToByteArray(byte[] encoding, int pos)
- {
- final int size = length();
- encoding[pos++] = (byte) size;
- System.arraycopy(_data,_offset,encoding,pos,size);
- return pos+size;
- }
-
- public static AMQShortString readFromByteArray(byte[] byteEncodedDestination, int pos)
- {
-
-
- final AMQShortString shortString = new AMQShortString(byteEncodedDestination, pos);
- if(shortString.length() == 0)
- {
- return null;
- }
- else
- {
- return shortString;
- }
- }
-
public static AMQShortString readFromBuffer(ByteBuffer buffer)
{
final short length = buffer.getUnsigned();
@@ -690,6 +697,10 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
size += term.length();
}
+ if (size > MAX_LENGTH)
+ {
+ throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
+ }
byte[] data = new byte[size];
int pos = 0;
final byte[] delimData = delim._data;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
index dc32569ee8..19f00378b1 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java
@@ -467,11 +467,12 @@ public class Connection extends ConnectionInvoker
{
synchronized (lock)
{
+ List <Binary> transactedSessions = new ArrayList();
for (Session ssn : sessions.values())
{
if (ssn.isTransacted())
- {
- removeSession(ssn);
+ {
+ transactedSessions.add(ssn.getName());
ssn.setState(Session.State.CLOSED);
}
else
@@ -481,6 +482,11 @@ public class Connection extends ConnectionInvoker
ssn.resume();
}
}
+
+ for (Binary ssn_name : transactedSessions)
+ {
+ sessions.remove(ssn_name);
+ }
setState(OPEN);
}
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java b/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
index ef6cd41492..f65427e583 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid;
import junit.framework.TestCase;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.AMQShortString;
/**
* This test is to ensure that when an AMQException is rethrown that the specified exception is correctly wrapped up.
@@ -91,6 +92,18 @@ public class AMQExceptionTest extends TestCase
return amqe;
}
+ public void testGetMessageAsString()
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 25; i++)
+ {
+ sb.append("message [" + i + "]");
+ }
+ AMQException e = new AMQException(AMQConstant.INTERNAL_ERROR, sb.toString(), null);
+ AMQShortString message = e.getMessageAsShortString();
+ assertEquals(sb.substring(0, AMQShortString.MAX_LENGTH - 3) + "...", message.toString());
+ }
+
/**
* Private class that extends AMQException but does not have a default exception.
*/
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java b/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
index 92e7ce0a80..9a805d87b3 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
@@ -20,6 +20,10 @@
package org.apache.qpid.framing;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
import junit.framework.TestCase;
public class AMQShortStringTest extends TestCase
{
@@ -105,5 +109,215 @@ public class AMQShortStringTest extends TestCase
assertFalse(new AMQShortString("A").equals(new AMQShortString("a")));
}
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(byte[])}.
+ */
+ public void testCreateAMQShortStringByteArray()
+ {
+ byte[] bytes = null;
+ try
+ {
+ bytes = "test".getBytes("UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ fail("UTF-8 encoding is not supported anymore by JVM:" + e.getMessage());
+ }
+ AMQShortString string = new AMQShortString(bytes);
+ assertEquals("constructed amq short string length differs from expected", 4, string.length());
+ assertTrue("constructed amq short string differs from expected", string.equals("test"));
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.String)}
+ * <p>
+ * Tests short string construction from string with length less than 255.
+ */
+ public void testCreateAMQShortStringString()
+ {
+ AMQShortString string = new AMQShortString("test");
+ assertEquals("constructed amq short string length differs from expected", 4, string.length());
+ assertTrue("constructed amq short string differs from expected", string.equals("test"));
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(char[])}.
+ * <p>
+ * Tests short string construction from char array with length less than 255.
+ */
+ public void testCreateAMQShortStringCharArray()
+ {
+ char[] chars = "test".toCharArray();
+ AMQShortString string = new AMQShortString(chars);
+ assertEquals("constructed amq short string length differs from expected", 4, string.length());
+ assertTrue("constructed amq short string differs from expected", string.equals("test"));
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.CharSequence)}
+ * <p>
+ * Tests short string construction from char sequence with length less than 255.
+ */
+ public void testCreateAMQShortStringCharSequence()
+ {
+ AMQShortString string = new AMQShortString((CharSequence) "test");
+ assertEquals("constructed amq short string length differs from expected", 4, string.length());
+ assertTrue("constructed amq short string differs from expected", string.equals("test"));
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(byte[])}.
+ * <p>
+ * Tests an attempt to create an AMQP short string from byte array with length over 255.
+ */
+ public void testCreateAMQShortStringByteArrayOver255()
+ {
+ String test = buildString('a', 256);
+ byte[] bytes = null;
+ try
+ {
+ bytes = test.getBytes("UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ fail("UTF-8 encoding is not supported anymore by JVM:" + e.getMessage());
+ }
+ try
+ {
+ new AMQShortString(bytes);
+ fail("It should not be possible to create AMQShortString with length over 255");
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertEquals("Exception message differs from expected",
+ "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.String)}
+ * <p>
+ * Tests an attempt to create an AMQP short string from string with length over 255
+ */
+ public void testCreateAMQShortStringStringOver255()
+ {
+ String test = buildString('a', 256);
+ try
+ {
+ new AMQShortString(test);
+ fail("It should not be possible to create AMQShortString with length over 255");
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertEquals("Exception message differs from expected",
+ "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(char[])}.
+ * <p>
+ * Tests an attempt to create an AMQP short string from char array with length over 255.
+ */
+ public void testCreateAMQShortStringCharArrayOver255()
+ {
+ String test = buildString('a', 256);
+ char[] chars = test.toCharArray();
+ try
+ {
+ new AMQShortString(chars);
+ fail("It should not be possible to create AMQShortString with length over 255");
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertEquals("Exception message differs from expected",
+ "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.CharSequence)}
+ * <p>
+ * Tests an attempt to create an AMQP short string from char sequence with length over 255.
+ */
+ public void testCreateAMQShortStringCharSequenceOver255()
+ {
+ String test = buildString('a', 256);
+ try
+ {
+ new AMQShortString((CharSequence) test);
+ fail("It should not be possible to create AMQShortString with length over 255");
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertEquals("Exception message differs from expected",
+ "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
+ }
+ }
+
+ /**
+ * Tests joining of short strings into a short string with length over 255.
+ */
+ public void testJoinOverflow()
+ {
+ List<AMQShortString> data = new ArrayList<AMQShortString>();
+ for (int i = 0; i < 25; i++)
+ {
+ data.add(new AMQShortString("test data!"));
+ }
+ try
+ {
+ AMQShortString.join(data, new AMQShortString(" "));
+ fail("It should not be possible to create AMQShortString with length over 255");
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertEquals("Exception message differs from expected",
+ "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
+ }
+ }
+
+ /**
+ * Tests joining of short strings into a short string with length less than 255.
+ */
+ public void testJoin()
+ {
+ StringBuilder expected = new StringBuilder();
+ List<AMQShortString> data = new ArrayList<AMQShortString>();
+ data.add(new AMQShortString("test data 1"));
+ expected.append("test data 1");
+ data.add(new AMQShortString("test data 2"));
+ expected.append(" test data 2");
+ AMQShortString result = AMQShortString.join(data, new AMQShortString(" "));
+ assertEquals("join result differs from expected", expected.toString(), result.asString());
+ }
+
+ /**
+ * A helper method to generate a string with given length containing given
+ * character
+ *
+ * @param ch
+ * char to build string with
+ * @param length
+ * target string length
+ * @return string
+ */
+ private String buildString(char ch, int length)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++)
+ {
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
}
diff --git a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
index 39805cbc48..1c7c7bb60f 100644
--- a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
+++ b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
@@ -57,10 +57,6 @@
</attributes>
</principal-database>
</principal-databases>
-
- <jmx>
- <principal-database>passwordfile</principal-database>
- </jmx>
</security>
<virtualhosts>${conf}/virtualhosts-ServerConfigurationTest-New.xml</virtualhosts>
diff --git a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
index e87be87154..56eaced9f7 100644
--- a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
+++ b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
@@ -56,9 +56,6 @@
</attributes>
</principal-database>
</principal-databases>
-<jmx>
-<principal-database>passwordfile</principal-database>
-</jmx>
</security>
<virtualhosts>${conf}/virtualhosts-ServerConfigurationTest-New.xml
<default>dev-only</default>
diff --git a/qpid/java/systests/etc/config-systests-firewall-2.xml b/qpid/java/systests/etc/config-systests-firewall-2.xml
index 05c3eaff9f..4c1bf9a800 100644
--- a/qpid/java/systests/etc/config-systests-firewall-2.xml
+++ b/qpid/java/systests/etc/config-systests-firewall-2.xml
@@ -84,10 +84,6 @@
<msg-auth>false</msg-auth>
- <jmx>
- <principal-database>passwordfile</principal-database>
- </jmx>
-
<firewall default-action="deny"/>
</security>
diff --git a/qpid/java/systests/etc/config-systests-firewall-3.xml b/qpid/java/systests/etc/config-systests-firewall-3.xml
index 861a3b33a3..19aaec9e54 100644
--- a/qpid/java/systests/etc/config-systests-firewall-3.xml
+++ b/qpid/java/systests/etc/config-systests-firewall-3.xml
@@ -84,10 +84,6 @@
<msg-auth>false</msg-auth>
- <jmx>
- <principal-database>passwordfile</principal-database>
- </jmx>
-
<firewall default-action="deny">
<rule access="allow" network="127.0.0.1"/>
</firewall>
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
index 49a608190d..212374e8be 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid.test.client.message;
import java.util.concurrent.CountDownLatch;
import javax.jms.DeliveryMode;
+import javax.jms.Destination;
import javax.jms.InvalidSelectorException;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -30,6 +31,7 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
+import javax.jms.TextMessage;
import junit.framework.Assert;
@@ -280,6 +282,38 @@ public class SelectorTest extends QpidBrokerTestCase implements MessageListener
Assert.assertNotNull("Msg5 should not be null", msg5);
}
+ public void testSelectorWithJMSDeliveryMode() throws Exception
+ {
+ Session session = _connection.createSession(false, Session.SESSION_TRANSACTED);
+
+ Destination dest1 = session.createTopic("test1");
+ Destination dest2 = session.createTopic("test2");
+
+ MessageProducer prod1 = session.createProducer(dest1);
+ MessageProducer prod2 = session.createProducer(dest2);
+ MessageConsumer consumer1 = session.createConsumer(dest1,"JMSDeliveryMode = 'PERSISTENT'");
+ MessageConsumer consumer2 = session.createConsumer(dest2,"JMSDeliveryMode = 'NON_PERSISTENT'");
+
+ Message msg1 = session.createTextMessage("Persistent");
+ prod1.send(msg1);
+ prod2.send(msg1);
+
+ prod1.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+ prod2.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+
+ Message msg2 = session.createTextMessage("Non_Persistent");
+ prod1.send(msg2);
+ prod2.send(msg2);
+
+ TextMessage m1 = (TextMessage)consumer1.receive(1000);
+ assertEquals("Consumer1 should receive the persistent message","Persistent",m1.getText());
+ assertNull("Consumer1 should not receiver another message",consumer1.receive(1000));
+
+ TextMessage m2 = (TextMessage)consumer2.receive(1000);
+ assertEquals("Consumer2 should receive the non persistent message","Non_Persistent",m2.getText());
+ assertNull("Consumer2 should not receiver another message",consumer2.receive(1000));
+ }
+
public static void main(String[] argv) throws Exception
{
SelectorTest test = new SelectorTest();
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
index 89d6462a39..5af53e4a70 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
@@ -71,7 +71,7 @@ public class TestParams
url = System.getProperty("url",url);
host = System.getProperty("host","");
port = Integer.getInteger("port", -1);
- address = System.getProperty("address","queue");
+ address = System.getProperty("address",address);
msg_size = Integer.getInteger("msg_size", 1024);
msg_type = Integer.getInteger("msg_type",1);
diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 78af2827df..7c21388213 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -828,8 +828,9 @@ class Engine:
self._closing = True
def attach(self, ssn):
+ if ssn.closed: return
sst = self._attachments.get(ssn)
- if sst is None and not ssn.closed:
+ if sst is None:
for i in xrange(0, self.channel_max):
if not self._sessions.has_key(i):
ch = i
diff --git a/qpid/specs/management-schema.xml b/qpid/specs/management-schema.xml
index 881632c881..9f54b0cd31 100644
--- a/qpid/specs/management-schema.xml
+++ b/qpid/specs/management-schema.xml
@@ -255,6 +255,7 @@
<property name="address" type="sstr" access="RC" index="y"/>
<property name="incoming" type="bool" access="RC"/>
<property name="SystemConnection" type="bool" access="RC" desc="Infrastucture/ Inter-system connection (Cluster, Federation, ...)"/>
+ <property name="userProxyAuth" type="bool" access="RO" desc="Authorization to proxy for users not on broker"/>
<property name="federationLink" type="bool" access="RO" desc="Is this a federation link"/>
<property name="authIdentity" type="sstr" access="RO" desc="authId of connection if authentication enabled"/>
<property name="remoteProcessName" type="lstr" access="RO" optional="y" desc="Name of executable running as remote client"/>
diff --git a/qpid/tools/src/py/qpid-cluster b/qpid/tools/src/py/qpid-cluster
index 312d59f670..d4f9391dcf 100755
--- a/qpid/tools/src/py/qpid-cluster
+++ b/qpid/tools/src/py/qpid-cluster
@@ -247,7 +247,7 @@ def main(argv=None):
parser.add_option("-k", "--all-stop", action="store_true", default=False, help="Shut down the whole cluster")
parser.add_option("-f", "--force", action="store_true", default=False, help="Suppress the 'are you sure' prompt")
parser.add_option("-n", "--numeric", action="store_true", default=False, help="Don't resolve names")
-
+
opts, args = parser.parse_args(args=argv)
if args:
@@ -268,12 +268,12 @@ def main(argv=None):
if opts.del_connection:
config._delConn = opts.del_connection
- if len(config._delConn.split(":")) != 2:
+ if len(config._delConn.split(":")) != 2:
parser.error("Member ID must be of form: <host or ip>:<number>")
if opts.stop:
- config._stopID = opts.stop
- if len(config._stopId.split(":")) != 2:
+ config._stopId = opts.stop
+ if len(config._stopId.split(":")) != 2:
parser.error("Member ID must be of form: <host or ip>:<number>")
config._stopAll = opts.all_stop
@@ -303,6 +303,7 @@ def main(argv=None):
bm.Disconnect()
except Exception, e:
+ raise
print str(e)
return 1
diff --git a/qpid/tools/src/py/qpid-config b/qpid/tools/src/py/qpid-config
index 3df69dc99b..b6eb0558cb 100755
--- a/qpid/tools/src/py/qpid-config
+++ b/qpid/tools/src/py/qpid-config
@@ -236,7 +236,7 @@ def OptionsAndArguments(argv):
config._fileCount = opts.file_count
if opts.file_size:
config._fileSize = opts.file_size
- if opts.max_queue_size:
+ if opts.max_queue_size != None:
config._maxQueueSize = opts.max_queue_size
if opts.max_queue_count:
config._maxQueueCount = opts.max_queue_count
@@ -488,7 +488,7 @@ class BrokerManager:
declArgs[FILECOUNT] = config._fileCount
declArgs[FILESIZE] = config._fileSize
- if config._maxQueueSize:
+ if config._maxQueueSize != None:
declArgs[MAX_QUEUE_SIZE] = config._maxQueueSize
if config._maxQueueCount:
declArgs[MAX_QUEUE_COUNT] = config._maxQueueCount