diff options
author | Stephen D. Huston <shuston@apache.org> | 2009-03-25 23:44:30 +0000 |
---|---|---|
committer | Stephen D. Huston <shuston@apache.org> | 2009-03-25 23:44:30 +0000 |
commit | 67d330f235362bf622b95f8c4d14321272a44ba7 (patch) | |
tree | 82153e6fd6c1c77e9defc80cb2e6b34d23de25cf | |
parent | b51fd45a4ed81bee144c22c2a57fc0e882d44149 (diff) | |
download | qpid-python-67d330f235362bf622b95f8c4d14321272a44ba7.tar.gz |
Merge from trunk tag to-cmake-25mar09 (r758432)
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/cmake@758465 13f79535-47bb-0310-9956-ffa450edef68
743 files changed, 30274 insertions, 11755 deletions
diff --git a/qpid/cpp/configure.ac b/qpid/cpp/configure.ac index 90b943f047..4cdad71858 100644 --- a/qpid/cpp/configure.ac +++ b/qpid/cpp/configure.ac @@ -11,7 +11,7 @@ dnl dnl When updating the name/version number here, also update it in dnl src/qpid/Version.h -AC_INIT([qpidc], [0.4], [qpid-dev@incubator.apache.org]) +AC_INIT([qpidc], [0.5], [dev@qpid.apache.org]) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects]) @@ -87,13 +87,14 @@ else AC_CHECK_DECL([__SUNPRO_CC], [SUNCC=yes], [SUNCC=no]) # Set up for sun CC compiler - if test x$SUNCC = xno; then + if test x$SUNCC = xyes; then if test "${enableval}" = yes; then WARNING_FLAGS=+w fi CXXFLAGS="$CXXFLAGS -library=stlport4 -mt" LD="$CXX" LDFLAGS="$LDFLAGS -library=stlport4 -mt" + AC_SUBST([SUNCC_RUNTIME_LIBS], [-lCrun]) fi fi @@ -150,8 +151,9 @@ test -z "$RUBY" && AC_MSG_ERROR([Missing ruby installation (try "yum install rub specdir=`pwd`/$srcdir/../specs AMQP_FINAL_XML=$specdir/amqp.0-10-qpid-errata.xml +test -f $AMQP_FINAL_XML || test -d $srcdir/src/gen || AC_MSG_ERROR([Neither AMQP specs nor spec-generated code present; cannot build.]) AC_SUBST(AMQP_FINAL_XML) -AM_CONDITIONAL([GENERATE], [ls $AMQP_FINAL_XML >/dev/null]) +AM_CONDITIONAL([GENERATE], [test -f $AMQP_FINAL_XML]) # URL and download URL for the package. URL=http://rhm.et.redhat.com/qpidc @@ -311,14 +313,19 @@ LIBS=$tmp_LIBS AM_CONDITIONAL([RDMA], [test x$with_RDMA = xyes]) # Setup --with-ssl/--without-ssl as arguments to configure -tmp_LIBS=$LIBS +SSL_CFLAGS="" +SSL_LDFLAGS="" AC_ARG_WITH([ssl], [AS_HELP_STRING([--with-ssl], [Build with support for SSL])], [case ${withval} in yes) with_SSL=yes - PKG_CHECK_MODULES([SSL], [nspr],,[AC_MSG_ERROR([nspr not found])]) - PKG_CHECK_MODULES([SSL], [nss],,[AC_MSG_ERROR([nss not found])]) + AC_PATH_PROG([NSPR_CONFIG], [nspr-config]) + AS_IF([test x$NSPR_CONFIG = x], [AC_MSG_ERROR([libnspr not found])], []) + AC_PATH_PROG([NSS_CONFIG], [nss-config]) + AS_IF([test x$NSS_CONFIG = x], [AC_MSG_ERROR([libnss not found])], []) + SSL_CFLAGS="`$NSPR_CONFIG --cflags` `$NSS_CONFIG --cflags`" + SSL_LDFLAGS="`$NSPR_CONFIG --libs` `$NSS_CONFIG --libs`" ;; no) with_SSL=no @@ -329,13 +336,18 @@ AC_ARG_WITH([ssl], esac], [ with_SSL=yes - PKG_CHECK_MODULES([SSL], [nspr],,[with_SSL=no]) - PKG_CHECK_MODULES([SSL], [nss],,[with_SSL=no]) + AC_PATH_PROG([NSPR_CONFIG], [nspr-config]) + AS_IF([test x$NSPR_CONFIG = x], [with_SSL=no], + [AC_PATH_PROG([NSS_CONFIG], [nss-config]) + AS_IF([test x$NSS_CONFIG = x], [with_SSL=no], + [SSL_CFLAGS="`$NSPR_CONFIG --cflags` `$NSS_CONFIG --cflags`" + SSL_LDFLAGS="`$NSPR_CONFIG --libs` `$NSS_CONFIG --libs`"])]) ] ) # Remove from LIBS, we will link it explicitly in make files. -LIBS=$tmp_LIBS AM_CONDITIONAL([SSL], [test x$with_SSL = xyes]) +AC_SUBST([SSL_CFLAGS]) +AC_SUBST([SSL_LDFLAGS]) poller=no @@ -367,6 +379,37 @@ if test $poller = xno; then AC_MSG_ERROR([Polling mechanism not implemented for $host]) fi +#Guess host architecture, to choose platform-dependent objects +case "$host" in + *sun-solaris*) + arch=solaris + ;; +esac +AM_CONDITIONAL([SUNOS], [test x$arch = xsolaris]) + +# Check for some syslog capabilities not present in all systems +AC_TRY_COMPILE([#include <sys/syslog.h>], + [int v = LOG_AUTHPRIV;], + [AC_DEFINE([HAVE_LOG_AUTHPRIV], [1], [Set to 1 whether LOG_AUTHPRIV is supported.])],) + +AC_TRY_COMPILE([#include <sys/syslog.h>], + [int v = LOG_FTP;], + [AC_DEFINE([HAVE_LOG_FTP], [1], [Set to 1 whether LOG_FTP is supported.])],) + +#Check if we need to include libacl to provide acl API +gl_saved_libs=$LIBS + AC_SEARCH_LIBS(acl, [acl], + [test "$ac_cv_search_acl" = "none required" || + LIB_ACL=$ac_cv_search_acl]) + AC_SUBST([LIB_ACL]) +LIBS=$gl_saved_libs + +SOCKLIBS="" +AC_CHECK_LIB([socket],[socket],[SOCKET_LIB="-lsocket"],[SOCKET_LIB=""],[]) +AC_CHECK_LIB([nsl],[getipnodebyname],[NSL_LIB="-lnsl"],[NSL_LIB=""],[]) +SOCKLIBS="$SOCKET_LIB $NSL_LIB" +AC_SUBST([SOCKLIBS]) + AM_PATH_PYTHON() # Files to generate diff --git a/qpid/cpp/docs/api/developer.doxygen.in b/qpid/cpp/docs/api/developer.doxygen.in index 46970d5465..4f643ef097 100644 --- a/qpid/cpp/docs/api/developer.doxygen.in +++ b/qpid/cpp/docs/api/developer.doxygen.in @@ -975,13 +975,13 @@ ENABLE_PREPROCESSING = YES # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. @@ -1009,7 +1009,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/qpid/cpp/docs/api/user.doxygen.in b/qpid/cpp/docs/api/user.doxygen.in index 7a87cc0fab..769ada716e 100644 --- a/qpid/cpp/docs/api/user.doxygen.in +++ b/qpid/cpp/docs/api/user.doxygen.in @@ -1003,7 +1003,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/qpid/cpp/etc/sasl2/qpidd.conf b/qpid/cpp/etc/sasl2/qpidd.conf index 45eea4592b..3197d7792a 100644 --- a/qpid/cpp/etc/sasl2/qpidd.conf +++ b/qpid/cpp/etc/sasl2/qpidd.conf @@ -39,3 +39,7 @@ pwcheck_method: auxprop auxprop_plugin: sasldb sasldb_path: /var/lib/qpidd/qpidd.sasldb + +#following line stops spurious 'sql_select option missing' errors when +#cyrus-sql-sasl plugin is installed +sql_select: dummy select diff --git a/qpid/cpp/examples/Makefile.am b/qpid/cpp/examples/Makefile.am index 255c86a7be..f23f3ee9e0 100644 --- a/qpid/cpp/examples/Makefile.am +++ b/qpid/cpp/examples/Makefile.am @@ -27,18 +27,17 @@ if !HAVE_XML endif MAKEDIST=.libs/Makefile -SUBMAKE=' for d in $(SUBDIRS) ; do $$(MAKE) -C $$$$d $$@ ; done' + $(MAKEDIST): Makefile mkdir -p .libs - @$(ECHO) all: > $(MAKEDIST) - @$(ECHO) $(SUBMAKE) >> $(MAKEDIST) - @$(ECHO) clean: >> $(MAKEDIST) - @$(ECHO) $(SUBMAKE) >> $(MAKEDIST) + @(echo 'all clean:' ; \ + echo ' for d in $(SUBDIRS) ; do $$(MAKE) -C $$$$d $$@ ; done' ; \ + ) > $(MAKEDIST) examplesdir=$(pkgdatadir)/examples -examples_DATA = README $(MAKEDIST) +dist_examples_DATA = README $(MAKEDIST) -EXTRA_DIST = $(examples_DATA) README.verify verify verify_all +EXTRA_DIST = README.verify verify verify_all # For older versions of automake abs_top_srcdir = @abs_top_srcdir@ diff --git a/qpid/cpp/examples/direct/Makefile.am b/qpid/cpp/examples/direct/Makefile.am index 07431f6fe4..8f220d1b7e 100644 --- a/qpid/cpp/examples/direct/Makefile.am +++ b/qpid/cpp/examples/direct/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/direct +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=direct_producer listener declare_queues diff --git a/qpid/cpp/examples/direct/direct_declare_queues.vcproj b/qpid/cpp/examples/direct/direct_declare_queues.vcproj new file mode 100644 index 0000000000..097b0ee3bf --- /dev/null +++ b/qpid/cpp/examples/direct/direct_declare_queues.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="direct_declare_queues"
+ ProjectGUID="{18165D4D-FECA-1BAD-4346-8C4DF2536AA5}"
+ RootNamespace="direct_declare_queues"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="declare_queues.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/direct/direct_direct_producer.vcproj b/qpid/cpp/examples/direct/direct_direct_producer.vcproj new file mode 100644 index 0000000000..94f7da5e69 --- /dev/null +++ b/qpid/cpp/examples/direct/direct_direct_producer.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="direct_direct_producer"
+ ProjectGUID="{9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}"
+ RootNamespace="direct_direct_producer"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_direct_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_direct_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_direct_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_direct_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="direct_producer.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/direct/direct_listener.vcproj b/qpid/cpp/examples/direct/direct_listener.vcproj new file mode 100644 index 0000000000..72e9e15748 --- /dev/null +++ b/qpid/cpp/examples/direct/direct_listener.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="direct_listener"
+ ProjectGUID="{95CE1459-FECA-1BAD-4346-8C4DF2536AA5}"
+ RootNamespace="direct_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/direct/direct_producer.cpp b/qpid/cpp/examples/direct/direct_producer.cpp index 7cca1955cf..ecc9675189 100644 --- a/qpid/cpp/examples/direct/direct_producer.cpp +++ b/qpid/cpp/examples/direct/direct_producer.cpp @@ -50,7 +50,6 @@ #include <qpid/client/Message.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/direct/listener.cpp b/qpid/cpp/examples/direct/listener.cpp index 55229df8a3..38bf24ec41 100644 --- a/qpid/cpp/examples/direct/listener.cpp +++ b/qpid/cpp/examples/direct/listener.cpp @@ -49,7 +49,6 @@ #include <qpid/client/MessageListener.h> #include <qpid/client/SubscriptionManager.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/examples.sln b/qpid/cpp/examples/examples.sln new file mode 100644 index 0000000000..e7e6fcb53c --- /dev/null +++ b/qpid/cpp/examples/examples.sln @@ -0,0 +1,213 @@ +
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+# $Id: VC9WorkspaceCreator.pm 1439 2008-07-10 14:31:19Z elliott_c $
+#
+# This file was generated by MPC. Any changes made directly to
+# this file will be lost the next time it is generated.
+#
+# MPC Command:
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 examples.mwc
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "direct_declare_queues", "direct\direct_declare_queues.vcproj", "{18165D4D-FECA-1BAD-4346-8C4DF2536AA5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "direct_direct_producer", "direct\direct_direct_producer.vcproj", "{9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "direct_listener", "direct\direct_listener.vcproj", "{95CE1459-FECA-1BAD-4346-8C4DF2536AA5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "failover_declare_queues", "failover\failover_declare_queues.vcproj", "{7817898E-FECA-1BAD-8026-8D997AD361D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "failover_replaying_sender", "failover\failover_replaying_sender.vcproj", "{085D6A66-FECA-1BAD-8026-8D997AD361D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "failover_resuming_receiver", "failover\failover_resuming_receiver.vcproj", "{B0DAF702-FECA-1BAD-8026-8D997AD361D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fanout_fanout_producer", "fanout\fanout_fanout_producer.vcproj", "{972AB76B-FECA-1BAD-8826-8C64F27AA1C5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fanout_listener", "fanout\fanout_listener.vcproj", "{95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pub_sub_topic_listener", "pub-sub\pub_sub_topic_listener.vcproj", "{A415E66A-FECA-1BAD-A430-FD5330E23A2D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pub_sub_topic_publisher", "pub-sub\pub_sub_topic_publisher.vcproj", "{05158653-FECA-1BAD-A430-FD5330E23A2D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_console", "qmf-console\qmf_console_console.vcproj", "{490473E1-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_ping", "qmf-console\qmf_console_ping.vcproj", "{771767FB-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_printevents", "qmf-console\qmf_console_printevents.vcproj", "{72C74624-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_queuestats", "qmf-console\qmf_console_queuestats.vcproj", "{B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "request_response_client", "request-response\request_response_client.vcproj", "{2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "request_response_server", "request-response\request_response_server.vcproj", "{46817425-FECA-1BAD-BD3A-8A467D0C5CCC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tradedemo_declare_queues", "tradedemo\tradedemo_declare_queues.vcproj", "{9057502D-FECA-1BAD-23CE-CD4095BD3C8B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tradedemo_topic_listener", "tradedemo\tradedemo_topic_listener.vcproj", "{5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tradedemo_topic_publisher", "tradedemo\tradedemo_topic_publisher.vcproj", "{E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.Build.0 = Debug|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.ActiveCfg = Debug|x64
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.Build.0 = Debug|x64
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.ActiveCfg = Release|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.ActiveCfg = Release|x64
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.Build.0 = Release|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.Build.0 = Debug|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.ActiveCfg = Debug|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.Build.0 = Debug|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.ActiveCfg = Release|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.ActiveCfg = Release|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.Build.0 = Release|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.Build.0 = Debug|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.ActiveCfg = Debug|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.Build.0 = Debug|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.ActiveCfg = Release|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.ActiveCfg = Release|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.Build.0 = Release|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.Build.0 = Debug|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.ActiveCfg = Debug|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.Build.0 = Debug|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.ActiveCfg = Release|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|x64.ActiveCfg = Release|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|x64.Build.0 = Release|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.Build.0 = Debug|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.ActiveCfg = Debug|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.Build.0 = Debug|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.ActiveCfg = Release|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|x64.ActiveCfg = Release|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|x64.Build.0 = Release|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.Build.0 = Debug|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.ActiveCfg = Debug|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.Build.0 = Debug|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.ActiveCfg = Release|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|x64.ActiveCfg = Release|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|x64.Build.0 = Release|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.Build.0 = Debug|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.ActiveCfg = Debug|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.Build.0 = Debug|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.ActiveCfg = Release|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.ActiveCfg = Release|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.Build.0 = Release|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.Build.0 = Debug|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.ActiveCfg = Debug|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.Build.0 = Debug|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.ActiveCfg = Release|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.ActiveCfg = Release|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.Build.0 = Release|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.Build.0 = Debug|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.ActiveCfg = Debug|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.Build.0 = Debug|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.ActiveCfg = Release|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.ActiveCfg = Release|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.Build.0 = Release|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.Build.0 = Debug|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.ActiveCfg = Debug|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.Build.0 = Debug|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.ActiveCfg = Release|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.ActiveCfg = Release|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.Build.0 = Release|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.Build.0 = Debug|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.ActiveCfg = Debug|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.Build.0 = Debug|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.ActiveCfg = Release|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.ActiveCfg = Release|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.Build.0 = Release|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.Build.0 = Debug|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.ActiveCfg = Debug|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.Build.0 = Debug|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.ActiveCfg = Release|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.ActiveCfg = Release|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.Build.0 = Release|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.Build.0 = Debug|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.ActiveCfg = Debug|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.Build.0 = Debug|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.ActiveCfg = Release|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.ActiveCfg = Release|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.Build.0 = Release|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.Build.0 = Debug|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.ActiveCfg = Debug|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.Build.0 = Debug|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.ActiveCfg = Release|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.ActiveCfg = Release|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.Build.0 = Release|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.Build.0 = Debug|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.ActiveCfg = Debug|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.Build.0 = Debug|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.ActiveCfg = Release|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.ActiveCfg = Release|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/cpp/examples/failover/Makefile.am b/qpid/cpp/examples/failover/Makefile.am index c41f26eaba..67d9eb4b95 100644 --- a/qpid/cpp/examples/failover/Makefile.am +++ b/qpid/cpp/examples/failover/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/failover +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=declare_queues resuming_receiver replaying_sender diff --git a/qpid/cpp/examples/failover/failover_declare_queues.vcproj b/qpid/cpp/examples/failover/failover_declare_queues.vcproj new file mode 100644 index 0000000000..918c02e942 --- /dev/null +++ b/qpid/cpp/examples/failover/failover_declare_queues.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="failover_declare_queues"
+ ProjectGUID="{7817898E-FECA-1BAD-8026-8D997AD361D0}"
+ RootNamespace="failover_declare_queues"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="declare_queues.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/failover/failover_replaying_sender.vcproj b/qpid/cpp/examples/failover/failover_replaying_sender.vcproj new file mode 100644 index 0000000000..c1a53471e6 --- /dev/null +++ b/qpid/cpp/examples/failover/failover_replaying_sender.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="failover_replaying_sender"
+ ProjectGUID="{085D6A66-FECA-1BAD-8026-8D997AD361D0}"
+ RootNamespace="failover_replaying_sender"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_replaying_sender\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_replaying_sender\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_replaying_sender\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_replaying_sender\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="replaying_sender.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj b/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj new file mode 100644 index 0000000000..b62e1b5636 --- /dev/null +++ b/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="failover_resuming_receiver"
+ ProjectGUID="{B0DAF702-FECA-1BAD-8026-8D997AD361D0}"
+ RootNamespace="failover_resuming_receiver"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_resuming_receiver\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_resuming_receiver\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_resuming_receiver\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_resuming_receiver\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="resuming_receiver.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/fanout/Makefile.am b/qpid/cpp/examples/fanout/Makefile.am index 6cbf2c93ad..395fcec9aa 100644 --- a/qpid/cpp/examples/fanout/Makefile.am +++ b/qpid/cpp/examples/fanout/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/fanout +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=fanout_producer listener diff --git a/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj b/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj new file mode 100644 index 0000000000..7addd69274 --- /dev/null +++ b/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="fanout_fanout_producer"
+ ProjectGUID="{972AB76B-FECA-1BAD-8826-8C64F27AA1C5}"
+ RootNamespace="fanout_fanout_producer"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_fanout_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_fanout_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_fanout_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_fanout_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="fanout_producer.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/fanout/fanout_listener.vcproj b/qpid/cpp/examples/fanout/fanout_listener.vcproj new file mode 100644 index 0000000000..d097779e80 --- /dev/null +++ b/qpid/cpp/examples/fanout/fanout_listener.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="fanout_listener"
+ ProjectGUID="{95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}"
+ RootNamespace="fanout_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/fanout/fanout_producer.cpp b/qpid/cpp/examples/fanout/fanout_producer.cpp index fb16f7e8b1..decd4d314d 100644 --- a/qpid/cpp/examples/fanout/fanout_producer.cpp +++ b/qpid/cpp/examples/fanout/fanout_producer.cpp @@ -48,7 +48,6 @@ #include <qpid/client/Message.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/fanout/listener.cpp b/qpid/cpp/examples/fanout/listener.cpp index b6050ef728..cd3071c29a 100644 --- a/qpid/cpp/examples/fanout/listener.cpp +++ b/qpid/cpp/examples/fanout/listener.cpp @@ -48,7 +48,6 @@ #include <qpid/client/MessageListener.h> #include <qpid/client/SubscriptionManager.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/makedist.mk b/qpid/cpp/examples/makedist.mk index 4345378983..391ddf47e7 100644 --- a/qpid/cpp/examples/makedist.mk +++ b/qpid/cpp/examples/makedist.mk @@ -3,20 +3,21 @@ AM_CXXFLAGS = $(WARNING_CFLAGS) INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/gen -I$(top_builddir)/src -I$(top_builddir)/src/gen CLIENT_LIB=$(top_builddir)/src/libqpidclient.la CONSOLE_LIB=$(top_builddir)/src/libqmfconsole.la -MAKELDFLAG ?= qpidclient +CLIENTFLAGS=-lqpidclient +CONSOLEFLAGS=-lqmfconsole # Generate a simple non-automake Makefile for distribution. MAKEDIST=.libs/Makefile $(MAKEDIST): Makefile mkdir -p .libs - @$(ECHO) CXX=$(CXX) > $(MAKEDIST) - @$(ECHO) CXXFLAGS=$(CXXFLAGS) >> $(MAKEDIST) - @$(ECHO) LDFLAGS=-l$(MAKELDFLAG) >> $(MAKEDIST) - @$(ECHO) >> $(MAKEDIST) - @$(ECHO) all: $(noinst_PROGRAMS) >> $(MAKEDIST) - @$(ECHO) >> $(MAKEDIST) - @$(ECHO) clean: >> $(MAKEDIST) - @$(ECHO) " rm -f $(noinst_PROGRAMS)" >> $(MAKEDIST) - + @(echo CXX=$(CXX) ; \ + echo CXXFLAGS=$(CXXFLAGS) ; \ + echo LDFLAGS=$(MAKELDFLAGS) ; \ + echo ; \ + echo all: $(noinst_PROGRAMS) ; \ + echo ; \ + echo clean: ; \ + echo " rm -f $(noinst_PROGRAMS)" ; \ + ) > $(MAKEDIST) diff --git a/qpid/cpp/examples/pub-sub/Makefile.am b/qpid/cpp/examples/pub-sub/Makefile.am index bdbf0f8d20..1d52daf638 100644 --- a/qpid/cpp/examples/pub-sub/Makefile.am +++ b/qpid/cpp/examples/pub-sub/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/pub-sub +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=topic_listener topic_publisher diff --git a/qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj b/qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj new file mode 100644 index 0000000000..72a6543a13 --- /dev/null +++ b/qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="pub_sub_topic_listener"
+ ProjectGUID="{A415E66A-FECA-1BAD-A430-FD5330E23A2D}"
+ RootNamespace="pub_sub_topic_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj b/qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj new file mode 100644 index 0000000000..5182b30435 --- /dev/null +++ b/qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="pub_sub_topic_publisher"
+ ProjectGUID="{05158653-FECA-1BAD-A430-FD5330E23A2D}"
+ RootNamespace="pub_sub_topic_publisher"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_publisher.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/pub-sub/topic_listener.cpp b/qpid/cpp/examples/pub-sub/topic_listener.cpp index fe0280cb7e..d38a806303 100644 --- a/qpid/cpp/examples/pub-sub/topic_listener.cpp +++ b/qpid/cpp/examples/pub-sub/topic_listener.cpp @@ -49,7 +49,6 @@ #include <qpid/client/MessageListener.h> #include <qpid/client/SubscriptionManager.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/pub-sub/topic_publisher.cpp b/qpid/cpp/examples/pub-sub/topic_publisher.cpp index 72ba572f75..aed5f8f033 100644 --- a/qpid/cpp/examples/pub-sub/topic_publisher.cpp +++ b/qpid/cpp/examples/pub-sub/topic_publisher.cpp @@ -50,7 +50,6 @@ #include <qpid/client/Message.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/qmf-console/Makefile.am b/qpid/cpp/examples/qmf-console/Makefile.am index 471620f465..04a92c214e 100644 --- a/qpid/cpp/examples/qmf-console/Makefile.am +++ b/qpid/cpp/examples/qmf-console/Makefile.am @@ -19,7 +19,7 @@ examplesdir=$(pkgdatadir)/examples/qmf-console -MAKELDFLAG = qmfconsole +MAKELDFLAGS=$(CONSOLEFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=console printevents ping queuestats diff --git a/qpid/cpp/examples/qmf-console/ping.cpp b/qpid/cpp/examples/qmf-console/ping.cpp index debca7428a..39ec0d3039 100644 --- a/qpid/cpp/examples/qmf-console/ping.cpp +++ b/qpid/cpp/examples/qmf-console/ping.cpp @@ -20,6 +20,7 @@ */ #include "qpid/console/SessionManager.h" +#include "qpid/sys/Time.h" using namespace std; using namespace qpid::console; @@ -107,7 +108,7 @@ int main_int(int /*argc*/, char** /*argv*/) cout << endl; if (result.code == 0 && iter < count - 1) - ::sleep(1); + qpid::sys::sleep(1); } } diff --git a/qpid/cpp/examples/qmf-console/printevents.cpp b/qpid/cpp/examples/qmf-console/printevents.cpp index 38d6f830aa..898972f28d 100644 --- a/qpid/cpp/examples/qmf-console/printevents.cpp +++ b/qpid/cpp/examples/qmf-console/printevents.cpp @@ -88,7 +88,7 @@ int main_int(int /*argc*/, char** /*argv*/) // Sleep indefinitely while asynchronous events are handled by the listener. // for (;;) - ::sleep(1); + qpid::sys::sleep(1); sm.delBroker(broker); return 0; diff --git a/qpid/cpp/examples/qmf-console/qmf_console_console.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_console.vcproj new file mode 100644 index 0000000000..67e34fde98 --- /dev/null +++ b/qpid/cpp/examples/qmf-console/qmf_console_console.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_console"
+ ProjectGUID="{490473E1-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_console"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_console\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_console\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_console\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_console\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="console.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj new file mode 100644 index 0000000000..daf2fd2b74 --- /dev/null +++ b/qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_ping"
+ ProjectGUID="{771767FB-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_ping"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_ping\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_ping\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_ping\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_ping\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="ping.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj new file mode 100644 index 0000000000..b11f4b8d31 --- /dev/null +++ b/qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_printevents"
+ ProjectGUID="{72C74624-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_printevents"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_printevents\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_printevents\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_printevents\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_printevents\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="printevents.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj new file mode 100644 index 0000000000..8c0bce672c --- /dev/null +++ b/qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_queuestats"
+ ProjectGUID="{B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_queuestats"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_queuestats\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_queuestats\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_queuestats\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_queuestats\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="queuestats.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/queuestats.cpp b/qpid/cpp/examples/qmf-console/queuestats.cpp index ea6dc13022..2c38777ad8 100644 --- a/qpid/cpp/examples/qmf-console/queuestats.cpp +++ b/qpid/cpp/examples/qmf-console/queuestats.cpp @@ -21,6 +21,7 @@ #include "qpid/console/ConsoleListener.h" #include "qpid/console/SessionManager.h" +#include "qpid/sys/Time.h" using namespace std; using namespace qpid::console; @@ -123,7 +124,7 @@ int main_int(int /*argc*/, char** /*argv*/) // Sleep while the listener does all the work asynchronously. // for (;;) { - sleep(1); + qpid::sys::sleep(1); } sm.delBroker(broker); diff --git a/qpid/cpp/examples/request-response/Makefile.am b/qpid/cpp/examples/request-response/Makefile.am index 8fb95f24fc..d7e7d692de 100644 --- a/qpid/cpp/examples/request-response/Makefile.am +++ b/qpid/cpp/examples/request-response/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/request-response +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=client server diff --git a/qpid/cpp/examples/request-response/client.cpp b/qpid/cpp/examples/request-response/client.cpp index b1f8d0b587..679d1c5fc2 100644 --- a/qpid/cpp/examples/request-response/client.cpp +++ b/qpid/cpp/examples/request-response/client.cpp @@ -61,7 +61,6 @@ #include <qpid/client/MessageListener.h> #include <qpid/client/SubscriptionManager.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/request-response/request_response_client.vcproj b/qpid/cpp/examples/request-response/request_response_client.vcproj new file mode 100644 index 0000000000..c40478ca7a --- /dev/null +++ b/qpid/cpp/examples/request-response/request_response_client.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="request_response_client"
+ ProjectGUID="{2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}"
+ RootNamespace="request_response_client"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_client\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_client\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_client\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_client\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="client.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/request-response/request_response_server.vcproj b/qpid/cpp/examples/request-response/request_response_server.vcproj new file mode 100644 index 0000000000..170caa0952 --- /dev/null +++ b/qpid/cpp/examples/request-response/request_response_server.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="request_response_server"
+ ProjectGUID="{46817425-FECA-1BAD-BD3A-8A467D0C5CCC}"
+ RootNamespace="request_response_server"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_server\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_server\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_server\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_server\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="server.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/request-response/server.cpp b/qpid/cpp/examples/request-response/server.cpp index 2d62638dff..65a4717b35 100644 --- a/qpid/cpp/examples/request-response/server.cpp +++ b/qpid/cpp/examples/request-response/server.cpp @@ -64,7 +64,6 @@ #include <qpid/client/MessageListener.h> #include <qpid/client/SubscriptionManager.h> -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/tradedemo/Makefile.am b/qpid/cpp/examples/tradedemo/Makefile.am index ef90e04bb0..a3c7fabd65 100644 --- a/qpid/cpp/examples/tradedemo/Makefile.am +++ b/qpid/cpp/examples/tradedemo/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/tradedemo +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=topic_listener topic_publisher declare_queues diff --git a/qpid/cpp/examples/tradedemo/topic_listener.cpp b/qpid/cpp/examples/tradedemo/topic_listener.cpp index 569e558147..c488e7fb69 100644 --- a/qpid/cpp/examples/tradedemo/topic_listener.cpp +++ b/qpid/cpp/examples/tradedemo/topic_listener.cpp @@ -58,7 +58,6 @@ #include <qpid/client/SubscriptionManager.h> #include "qpid/client/QueueOptions.h" -#include <unistd.h> #include <cstdlib> #include <iostream> diff --git a/qpid/cpp/examples/tradedemo/topic_publisher.cpp b/qpid/cpp/examples/tradedemo/topic_publisher.cpp index 913f2cb9fe..e22c185bc7 100644 --- a/qpid/cpp/examples/tradedemo/topic_publisher.cpp +++ b/qpid/cpp/examples/tradedemo/topic_publisher.cpp @@ -59,7 +59,7 @@ #include "qpid/client/QueueOptions.h" -#include <unistd.h> +#include <stdlib.h> #include <cstdlib> #include <iostream> #include <set> diff --git a/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj new file mode 100644 index 0000000000..483ad2e6c9 --- /dev/null +++ b/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tradedemo_declare_queues"
+ ProjectGUID="{9057502D-FECA-1BAD-23CE-CD4095BD3C8B}"
+ RootNamespace="tradedemo_declare_queues"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="declare_queues.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj new file mode 100644 index 0000000000..2e36090602 --- /dev/null +++ b/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tradedemo_topic_listener"
+ ProjectGUID="{5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}"
+ RootNamespace="tradedemo_topic_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj new file mode 100644 index 0000000000..2fdbb901c0 --- /dev/null +++ b/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj @@ -0,0 +1,374 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tradedemo_topic_publisher"
+ ProjectGUID="{E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}"
+ RootNamespace="tradedemo_topic_publisher"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_publisher.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/xml-exchange/Makefile.am b/qpid/cpp/examples/xml-exchange/Makefile.am index 0f99aea44e..aa450a32c2 100644 --- a/qpid/cpp/examples/xml-exchange/Makefile.am +++ b/qpid/cpp/examples/xml-exchange/Makefile.am @@ -18,6 +18,7 @@ # examplesdir=$(pkgdatadir)/examples/xml-exchange +MAKELDFLAGS=$(CLIENTFLAGS) include $(top_srcdir)/examples/makedist.mk noinst_PROGRAMS=declare_queues xml_producer listener diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index f2efa109f3..c6cfca5f83 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -33,6 +33,8 @@ usage = "usage: %prog [options] schema-document..." parser = OptionParser(usage=usage) parser.add_option("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./", help="Output directory") +parser.add_option("-c", "--cmakelists", dest="cmakelists", metavar="FILE", + help="CMakeLists fragment") parser.add_option("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") parser.add_option("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile, @@ -72,3 +74,9 @@ if opts.makefile != None: args["qpidbroker"] = opts.qpidbroker args["genprefix"] = opts.genprefix gen.makeSingleFile("Makefile.mk", opts.makefile, force=True, vars=args) + +if opts.cmakelists != None: + args = {} + args["qpidbroker"] = opts.qpidbroker + args["genprefix"] = opts.genprefix + gen.makeSingleFile("CMakeLists.cmake", opts.cmakelists, force=True, vars=args) diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 35e222ebad..255d41ea0e 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -24,6 +24,7 @@ from errno import * import os import os.path import filecmp +import re class Template: """ @@ -175,6 +176,81 @@ class Makefile: return variables["qpidbroker"] return False +class CMakeLists(Makefile): + """ Object representing a makefile fragment """ + + # Regardless of what normalize() did, switch all the dir separators back + # to '/' - cmake expects that regardless of platform. + def unNormCase (self, path): + return re.sub("\\\\", "/", path) + + def genGenSources (self, stream, variables): + mdir = self.unNormCase(variables["mgenDir"]) + sdir = self.unNormCase(variables["specDir"]) + stream.write (mdir + "/qmf-gen \n") + stream.write (" " + mdir + "/qmfgen/generate.py\n") + stream.write (" " + mdir + "/qmfgen/schema.py\n") + stream.write (" " + mdir + "/qmfgen/management-types.xml\n") + stream.write (" " + sdir + "/management-schema.xml\n") + first = True + for template in self.templateFiles: + if first: + first = False + stream.write (" ") + else: + stream.write ("\n ") + stream.write (mdir + "/qmfgen/templates/" + template) + + def genGenCppFiles (self, stream, variables): + first = True + for file in self.filelists["cpp"]: + if first: + first = False + else: + stream.write (" \n ") + stream.write (self.unNormCase(file)) + + def genGenHFiles (self, stream, variables): + first = True + for file in self.filelists["h"]: + if first: + first = False + else: + stream.write (" \n ") + stream.write (self.unNormCase(file)) + + def genGeneratedFiles(self, stream, variables): + first = True + extensions = ("h", "cpp") + for ext in extensions: + for file in self.filelists[ext]: + if first: + first = False + else: + stream.write(" \n ") + if "genprefix" in variables: + prefix = variables["genprefix"] + if prefix != "": + stream.write(prefix + "/") + stream.write(self.unNormCase(file)) + + def genHeaderInstalls (self, stream, variables): + for package in self.packagelist: + stream.write("#Come back to this later...\n") + name = "_".join(package.split("/")) + stream.write("#" + name + "dir = $(includedir)/qmf/" + package + "\n") + stream.write("#dist_" + name + "_HEADERS = ") + first = True + for file in self.filelists["h"]: + file = self.unNormCase(file) + if file.find("gen/qmf/" + package) == 0: + if first: + first = False + else: + stream.write ("\n ") + stream.write("#" + file) + stream.write("\n\n") + class Generator: """ @@ -208,9 +284,10 @@ class Generator: self.input = self.normalize (templateDir) self.packagePath = self.dest self.filelists = {} - self.filelists["h"] = [] - self.filelists["cpp"] = [] - self.filelists["mk"] = [] + self.filelists["h"] = [] + self.filelists["cpp"] = [] + self.filelists["mk"] = [] + self.filelists["cmake"] = [] self.packagelist = [] self.templateFiles = [] self.variables = {} @@ -354,7 +431,17 @@ class Generator: def makeSingleFile (self, templateFile, target, force=False, vars=None): """ Generate a single expanded template """ - makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + className = templateFile[0:dot] + if className == "Makefile": + classType = Makefile + elif className == "CMakeLists": + classType = CMakeLists + else: + raise ValueError ("Invalid class name %s" % className) + makefile = classType (self.filelists, self.templateFiles, self.packagelist) template = Template (self.input + templateFile, self) if vars: for arg in vars: diff --git a/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb b/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb index 92bd10c9dd..3bacdbd812 100755 --- a/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb +++ b/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb @@ -30,13 +30,14 @@ class MethodBodyDefaultVisitorGen < CppGen def generate() h_file(@filename) { include "qpid/framing/MethodBodyConstVisitor" + include "qpid/CommonImportExport.h" namespace(@namespace) { genl "class AMQMethodBody;" cpp_class(@classname, "public MethodBodyConstVisitor") { genl "public:" genl "virtual void defaultVisit(const AMQMethodBody&) = 0;" @amqp.methods_.each { |m| - genl "virtual void visit(const #{m.body_name}&);" } + genl "QPID_COMMON_EXTERN virtual void visit(const #{m.body_name}&);" } }}} cpp_file(@filename) { diff --git a/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb b/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb index b751f61d36..6e3b79e51e 100755 --- a/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb +++ b/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb @@ -74,7 +74,7 @@ class OperationsInvokerGen < CppGen public genl("Invoker(#{target}& target_) : target(target_) {}") genl "using MethodBodyDefaultVisitor::visit;" - methods.each { |m| genl "void visit(const #{m.body_name}& body);" } + methods.each { |m| genl "QPID_COMMON_EXTERN void visit(const #{m.body_name}& body);" } } end @@ -82,6 +82,7 @@ class OperationsInvokerGen < CppGen h_file(@filename) { include "qpid/framing/#{@ops}" include "qpid/framing/Invoker.h" + include "qpid/CommonImportExport.h" namespace("qpid::framing") { # AMQP_*Operations invoker. methods=@amqp.classes.map { |c| visit_methods(c).to_a }.flatten diff --git a/qpid/cpp/rubygen/framing.0-10/Proxy.rb b/qpid/cpp/rubygen/framing.0-10/Proxy.rb index 97d0df7c58..7e11d62d9b 100755 --- a/qpid/cpp/rubygen/framing.0-10/Proxy.rb +++ b/qpid/cpp/rubygen/framing.0-10/Proxy.rb @@ -44,7 +44,7 @@ public: static #{cname}& get(#{@classname}& proxy) { return proxy.get#{cname}(); } EOS methods_on(c, @chassis).each { |m| - genl "virtual void #{m.cppname}(#{m.signature.join(",\n ")});" + genl "QPID_COMMON_EXTERN virtual void #{m.cppname}(#{m.signature.join(",\n ")});" genl }} end @@ -66,10 +66,12 @@ EOS include "qpid/framing/Array.h" include "qpid/framing/amqp_types.h" include "qpid/framing/amqp_structs.h" + include "qpid/CommonImportExport.h" + namespace("qpid::framing") { cpp_class(@classname, "public Proxy") { public - genl "#{@classname}(FrameHandler& out);" + genl "QPID_COMMON_EXTERN #{@classname}(FrameHandler& out);" genl @amqp.classes.each { |c| inner_class_decl(c) diff --git a/qpid/cpp/rubygen/framing.0-10/Session.rb b/qpid/cpp/rubygen/framing.0-10/Session.rb index 5dd2a91a56..709491e42e 100644 --- a/qpid/cpp/rubygen/framing.0-10/Session.rb +++ b/qpid/cpp/rubygen/framing.0-10/Session.rb @@ -55,9 +55,9 @@ module SyncAsync def decl_ctor_opeq() genl - genl "#{@classname}();" - genl "#{@classname}(const #{@version_base}& other);" - genl "#{@classname}& operator=(const #{@version_base}& other);" + genl "QPID_CLIENT_EXTERN #{@classname}();" + genl "QPID_CLIENT_EXTERN #{@classname}(const #{@version_base}& other);" + genl "QPID_CLIENT_EXTERN #{@classname}& operator=(const #{@version_base}& other);" end def defn_ctor_opeq(inline="") @@ -138,6 +138,7 @@ class SessionNoKeywordGen < CppGen def generate() h_file(@file) { include "qpid/client/#{@version_base}.h" + include "qpid/client/ClientImportExport.h" namespace(@namespace) { doxygen_comment { genl "AMQP #{@amqp.version} #{sync_adjective} session API." @@ -151,7 +152,7 @@ class SessionNoKeywordGen < CppGen genl doxygen(m) args=m.sig_c_default.join(", ") - genl "#{m.return_type(@async)} #{m.session_function}(#{args});" + genl "QPID_CLIENT_EXTERN #{m.return_type(@async)} #{m.session_function}(#{args});" } } }} @@ -229,6 +230,7 @@ class SessionGen < CppGen h_file(@fqclass.file) { include @fqbase.file include "qpid/client/arg" + include "qpid/client/ClientImportExport" namespace("qpid::client") { # Doxygen comment. doxygen_comment { diff --git a/qpid/cpp/rubygen/framing.0-10/constants.rb b/qpid/cpp/rubygen/framing.0-10/constants.rb index d07c84e63a..fa2031b0ce 100755 --- a/qpid/cpp/rubygen/framing.0-10/constants.rb +++ b/qpid/cpp/rubygen/framing.0-10/constants.rb @@ -142,7 +142,7 @@ EOS enum = @amqp.class_(class_name).domain(domain_name).enum enum.choices.each { |c| declare_exception(c, base, class_name, enum) unless c.name == "normal" } genl - genl "sys::ExceptionHolder create#{base}(int code, const std::string& text);" + genl "QPID_COMMON_EXTERN sys::ExceptionHolder create#{base}(int code, const std::string& text);" end def create_exception(class_name, domain_name, base, invalid) @@ -165,6 +165,7 @@ EOS include "qpid/Exception" include "qpid/sys/ExceptionHolder" include "enum" + include "qpid/CommonImportExport.h" namespace(@namespace) { declare_exceptions("execution", "error-code", "SessionException") declare_exceptions("connection", "close-code", "ConnectionException") diff --git a/qpid/cpp/rubygen/framing.0-10/structs.rb b/qpid/cpp/rubygen/framing.0-10/structs.rb index a68e1afb1e..8ea8a91172 100644 --- a/qpid/cpp/rubygen/framing.0-10/structs.rb +++ b/qpid/cpp/rubygen/framing.0-10/structs.rb @@ -351,15 +351,15 @@ EOS end def declare_packed_accessors(f) - genl "void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});"; - genl "#{f.cpptype.ret} get#{f.name.caps}() const;" + genl "QPID_COMMON_EXTERN void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});"; + genl "QPID_COMMON_EXTERN #{f.cpptype.ret} get#{f.name.caps}() const;" if (f.cpptype.name == "FieldTable") - genl "#{f.cpptype.name}& get#{f.name.caps}();" + genl "QPID_COMMON_EXTERN #{f.cpptype.name}& get#{f.name.caps}();" end if (f.type_ != "bit") #extra 'accessors' for packed fields: - genl "bool has#{f.name.caps}() const;" - genl "void clear#{f.name.caps}Flag();" + genl "QPID_COMMON_EXTERN bool has#{f.name.caps}() const;" + genl "QPID_COMMON_EXTERN void clear#{f.name.caps}Flag();" end end @@ -399,6 +399,7 @@ EOS #include <ostream> #include "qpid/framing/amqp_types_full.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -438,17 +439,17 @@ EOS methodbody_extra_defs(s) end if (s.kind_of? AmqpStruct) - indent {genl "friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } + indent {genl "QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } end gen <<EOS - void encode(Buffer&) const; - void decode(Buffer&, uint32_t=0); - void encodeStructBody(Buffer&) const; - void decodeStructBody(Buffer&, uint32_t=0); - uint32_t encodedSize() const; - uint32_t bodySize() const; - void print(std::ostream& out) const; + QPID_COMMON_EXTERN void encode(Buffer&) const; + QPID_COMMON_EXTERN void decode(Buffer&, uint32_t=0); + QPID_COMMON_EXTERN void encodeStructBody(Buffer&) const; + QPID_COMMON_EXTERN void decodeStructBody(Buffer&, uint32_t=0); + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN uint32_t bodySize() const; + QPID_COMMON_EXTERN void print(std::ostream& out) const; }; /* class #{classname} */ }} diff --git a/qpid/cpp/rubygen/generate b/qpid/cpp/rubygen/generate index 836626cd7a..775bd3fd58 100755 --- a/qpid/cpp/rubygen/generate +++ b/qpid/cpp/rubygen/generate @@ -26,7 +26,7 @@ require 'amqpgen' if ARGV.size < 3 puts <<EOS Usage: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] TEMPLATE.rb [ ... ] -or: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] all [ makefragment.mk ] +or: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] all [ makefragment.cmake ] Parse all SPEC.xml files to create an AMQP model, run each TEMPLATE putting the resulting files under OUTDIR. Prints a list of files @@ -76,16 +76,16 @@ templates.each { |t| end } -def make_continue(lines) lines.join(" \\\n "); end +def cmake_continue(lines) lines.join(" \n "); end # Generate makefile -makefile=ARGV.grep(/.mk$/)[0] +makefile=ARGV.grep(/.cmake$/)[0] if makefile dir=Dir.getwd Dir.chdir File.dirname(__FILE__) generator_files=Dir["**/*.rb"] << File.basename(__FILE__) Dir.chdir dir - rgen_generator=generator_files.map{ |f| "$(rgen_dir)/#{f}" } + rgen_generator=generator_files.map{ |f| "${rgen_dir}/#{f}" } rgen_srcs=GenFiles.get.map{ |f| "#{$outdir}/#{f}" } rgen_subdirs={} rgen_srcs.each { |src| @@ -100,13 +100,13 @@ if makefile # Generated makefile fragment. # Including makefile defines $(rgen_dir) $(rgen_cmd) and $(specs). -rgen_generator=#{make_continue rgen_generator} +set(rgen_generator #{cmake_continue rgen_generator}) EOS rgen_subdirs.each_key { |subdir| - out << "\nrgen_#{subdir}_srcs = #{make_continue(rgen_subdirs[subdir])}\n" + out << "\nset(rgen_#{subdir}_srcs #{cmake_continue(rgen_subdirs[subdir])})\n" } out << <<EOS -rgen_srcs=#{make_continue rgen_srcs} +set(rgen_srcs #{cmake_continue rgen_srcs}) # Header file install rules. EOS @@ -115,8 +115,8 @@ EOS dir_ = dir.tr("/", "_") regex=%r|#{dir}/[^/]+\.h$| out << <<EOS -#{dir_}dir = $(includedir)/#{dir} -dist_#{dir_}_HEADERS = #{make_continue rgen_srcs.grep(regex)} +set(#{dir_}dir \${includedir}/#{dir}) +set(dist_#{dir_}_HEADERS #{cmake_continue rgen_srcs.grep(regex)}) EOS } diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am index d5b53dc502..7de05645fa 100644 --- a/qpid/cpp/src/Makefile.am +++ b/qpid/cpp/src/Makefile.am @@ -29,6 +29,7 @@ windows_dist = \ client.vcproj \ qmfconsole.vcproj \ protocol_gen.mak \ + qpid/client/windows/SaslFactory.cpp \ qpid/log/windows/SinkOptions.cpp \ qpid/log/windows/SinkOptions.h \ qpid/sys/windows/check.h \ @@ -41,6 +42,7 @@ windows_dist = \ qpid/sys/windows/IOHandle.cpp \ qpid/sys/windows/IoHandlePrivate.h \ qpid/sys/windows/LockFile.cpp \ + qpid/sys/windows/PollableCondition.cpp \ qpid/sys/windows/Mutex.h \ qpid/sys/windows/Shlib.cpp \ qpid/sys/windows/Socket.cpp \ @@ -126,7 +128,6 @@ posix_plat_src = \ qpid/sys/posix/Time.cpp \ qpid/sys/posix/Thread.cpp \ qpid/sys/posix/Shlib.cpp \ - qpid/sys/posix/SystemInfo.cpp \ qpid/sys/posix/Mutex.cpp \ qpid/sys/posix/Fork.cpp \ qpid/sys/posix/StrError.cpp \ @@ -139,7 +140,6 @@ posix_plat_hdr = \ qpid/sys/posix/PrivatePosix.h \ qpid/sys/posix/Mutex.h \ qpid/sys/posix/Fork.h \ - qpid/sys/posix/PollableCondition.h \ qpid/sys/posix/IntegerTypes.h \ qpid/sys/posix/Time.h @@ -151,7 +151,13 @@ if HAVE_ECF poller = qpid/sys/solaris/ECFPoller.cpp endif -platform_src = $(posix_plat_src) $(poller) +if SUNOS + systeminfo = qpid/sys/solaris/SystemInfo.cpp +else + systeminfo = qpid/sys/posix/SystemInfo.cpp +endif + +platform_src = $(posix_plat_src) $(poller) $(systeminfo) platform_hdr = $(posix_plat_hdr) posix_broker_src = \ @@ -495,6 +501,7 @@ nobase_include_HEADERS = \ qpid/broker/Queue.h \ qpid/broker/QueueListeners.h \ qpid/broker/QueueCleaner.h \ + qpid/broker/BrokerImportExport.h \ qpid/broker/BrokerSingleton.h \ qpid/broker/Bridge.h \ qpid/broker/Connection.h \ @@ -571,6 +578,7 @@ nobase_include_HEADERS = \ qpid/client/AckMode.h \ qpid/client/Bounds.h \ qpid/client/ChainableFrameHandler.h \ + qpid/client/ClientImportExport.h \ qpid/client/Completion.h \ qpid/client/Connection.h \ qpid/client/ConnectionHandler.h \ @@ -666,6 +674,7 @@ nobase_include_HEADERS = \ qpid/management/ManagementEvent.h \ qpid/management/ManagementExchange.h \ qpid/management/ManagementObject.h \ + qpid/sys/alloca.h \ qpid/sys/AggregateOutput.h \ qpid/sys/AsynchIO.h \ qpid/sys/AsynchIOHandler.h \ @@ -715,7 +724,8 @@ nobase_include_HEADERS = \ qpid/sys/Time.h \ qpid/sys/Timer.h \ qpid/sys/TimeoutHandler.h \ - qpid/sys/uuid.h + qpid/sys/uuid.h \ + qpid/CommonImportExport.h # Force build of qpidd during dist phase so help2man will work. dist-hook: $(BUILT_SOURCES) diff --git a/qpid/cpp/src/acl.mk b/qpid/cpp/src/acl.mk index 2b3ab4dfd9..95b47acc1c 100644 --- a/qpid/cpp/src/acl.mk +++ b/qpid/cpp/src/acl.mk @@ -31,4 +31,8 @@ acl_la_SOURCES = \ qpid/acl/AclReader.h acl_la_LIBADD = libqpidbroker.la +if SUNOS + acl_la_LIBADD += libqmfagent.la libqmfconsole.la libqpidcommon.la -lboost_program_options $(SUNCC_RUNTIME_LIBS) +endif + acl_la_LDFLAGS = $(PLUGINLDFLAGS) diff --git a/qpid/cpp/src/broker.vcproj b/qpid/cpp/src/broker.vcproj index 7a7bf337a8..e4911e0bfc 100644 --- a/qpid/cpp/src/broker.vcproj +++ b/qpid/cpp/src/broker.vcproj @@ -42,9 +42,9 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\broker\I386"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\broker\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="BROKER_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -97,13 +97,14 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommond.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbrokerd.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
+ ImportLibrary=".\qpidbrokerd.lib"
TargetMachine="1"
/>
<Tool
@@ -120,13 +121,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib

@copy /Y $(OutDir)\qpidbrokerd.dll deploy\lib\
@copy /Y .\qpidbrokerd.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\broker\I386"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Release\broker\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -155,8 +157,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="BROKER_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -167,7 +169,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -176,15 +178,16 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommon.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbroker.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidbroker.lib"
TargetMachine="1"
/>
<Tool
@@ -201,13 +204,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib

@copy /Y $(OutDir)\qpidbroker.dll deploy\lib\
@copy /Y .\qpidbroker.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\broker\AMD64"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\broker\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -236,10 +240,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="BROKER_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -251,7 +255,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -261,13 +265,14 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommond.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbrokerd.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
+ ImportLibrary=".\qpidbrokerd.lib"
TargetMachine="17"
/>
<Tool
@@ -284,13 +289,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib

@copy /Y $(OutDir)\qpidbrokerd.dll deploy\lib\
@copy /Y .\qpidbrokerd.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\broker\AMD64"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Release\broker\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -319,8 +325,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="BROKER_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -331,7 +337,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -341,15 +347,16 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommon.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbroker.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidbroker.lib"
TargetMachine="17"
/>
<Tool
@@ -366,6 +373,7 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib

@copy /Y $(OutDir)\qpidbroker.dll deploy\lib\
@copy /Y .\qpidbroker.lib deploy\lib\
"
/>
</Configuration>
</Configurations>
@@ -909,12 +917,6 @@ <File
RelativePath="qpid\sys\TCPIOPlugin.cpp">
</File>
- <File
- RelativePath="qpidd.cpp">
- </File>
- <File
- RelativePath="windows\QpiddBroker.cpp">
- </File>
</Filter>
<Filter
Name="Header Files"
@@ -1306,9 +1308,6 @@ <File
RelativePath="qpid\management\ManagementObject.h">
</File>
- <File
- RelativePath="qpidd.h">
- </File>
</Filter>
</Files>
<Globals>
diff --git a/qpid/cpp/src/client.vcproj b/qpid/cpp/src/client.vcproj index e724e04d98..28b7ec73dc 100644 --- a/qpid/cpp/src/client.vcproj +++ b/qpid/cpp/src/client.vcproj @@ -43,8 +43,8 @@ <Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\client\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\client\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CLIENT_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="_DEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclientsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib"
+ OutputFile="$(OutDir)\qpidclientd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidclientd.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\

@copy /Y $(OutDir)\qpidclientd.dll deploy\lib\
@copy /Y .\qpidclientd.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\client\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\client\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CLIENT_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="NDEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclients.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib"
+ OutputFile="$(OutDir)\qpidclient.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidclient.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\

@copy /Y $(OutDir)\qpidclient.dll deploy\lib\
@copy /Y .\qpidclient.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\client\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\client\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CLIENT_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="_DEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclientsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib"
+ OutputFile="$(OutDir)\qpidclientd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidclientd.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\

@copy /Y $(OutDir)\qpidclientd.dll deploy\lib\
@copy /Y .\qpidclientd.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\client\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\client\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CLIENT_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="NDEBUG;CONF_FILE=\"qpidc.conf\";MODULE_DIR=\".\";NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclients.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib"
+ OutputFile="$(OutDir)\qpidclient.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidclient.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\
@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\

@copy /Y $(OutDir)\qpidclient.dll deploy\lib\
@copy /Y .\qpidclient.lib deploy\lib\
"
/>
</Configuration>
</Configurations>
@@ -414,9 +456,6 @@ RelativePath="qpid\client\Results.cpp">
</File>
<File
- RelativePath="qpid\client\SaslFactory.cpp">
- </File>
- <File
RelativePath="qpid\client\SessionBase_0_10.cpp">
</File>
<File
@@ -440,6 +479,9 @@ <File
RelativePath="qpid\client\SubscriptionManager.cpp">
</File>
+ <File
+ RelativePath="qpid\client\windows\SaslFactory.cpp">
+ </File>
</Filter>
<Filter
Name="Header Files"
diff --git a/qpid/cpp/src/cluster.mk b/qpid/cpp/src/cluster.mk index 0d34788d2e..e2054d75e9 100644 --- a/qpid/cpp/src/cluster.mk +++ b/qpid/cpp/src/cluster.mk @@ -40,6 +40,8 @@ cluster_la_SOURCES = \ $(CMAN_SOURCES) \ qpid/cluster/Cluster.cpp \ qpid/cluster/Cluster.h \ + qpid/cluster/Decoder.cpp \ + qpid/cluster/Decoder.h \ qpid/cluster/PollableQueue.h \ qpid/cluster/ClusterMap.cpp \ qpid/cluster/ClusterMap.h \ @@ -49,14 +51,8 @@ cluster_la_SOURCES = \ qpid/cluster/Connection.h \ qpid/cluster/ConnectionCodec.cpp \ qpid/cluster/ConnectionCodec.h \ - qpid/cluster/ConnectionMap.h \ - qpid/cluster/ConnectionMap.cpp \ qpid/cluster/Cpg.cpp \ qpid/cluster/Cpg.h \ - qpid/cluster/Decoder.cpp \ - qpid/cluster/Decoder.h \ - qpid/cluster/ConnectionDecoder.cpp \ - qpid/cluster/ConnectionDecoder.h \ qpid/cluster/Dispatchable.h \ qpid/cluster/UpdateClient.cpp \ qpid/cluster/UpdateClient.h \ @@ -68,8 +64,11 @@ cluster_la_SOURCES = \ qpid/cluster/ExpiryPolicy.cpp \ qpid/cluster/FailoverExchange.cpp \ qpid/cluster/FailoverExchange.h \ + qpid/cluster/UpdateExchange.h \ + qpid/cluster/LockedConnectionMap.h \ qpid/cluster/Multicaster.cpp \ qpid/cluster/Multicaster.h \ + qpid/cluster/McastFrameHandler.h \ qpid/cluster/NoOpConnectionOutputHandler.h \ qpid/cluster/OutputInterceptor.cpp \ qpid/cluster/OutputInterceptor.h \ diff --git a/qpid/cpp/src/common.vcproj b/qpid/cpp/src/common.vcproj index e8c40da426..96d67b9d54 100644 --- a/qpid/cpp/src/common.vcproj +++ b/qpid/cpp/src/common.vcproj @@ -43,8 +43,8 @@ <Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\common\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\common\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="COMMON_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommonsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommond.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidcommond.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid
@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10
@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing
@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows
@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows
@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\*.h deploy\include\qpid\
@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\
@copy /Y qpid\framing\*.h deploy\include\qpid\framing\
@copy /Y qpid\sys\*.h deploy\include\qpid\sys\
@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\
@copy /Y qpid\log\*.h deploy\include\qpid\log\
@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\
@copy /Y qpid\management\*.h deploy\include\qpid\management\

@copy /Y $(OutDir)\qpidcommond.dll deploy\lib\
@copy /Y .\qpidcommond.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\common\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\common\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="COMMON_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommons.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommon.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidcommon.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid
@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10
@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing
@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows
@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows
@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\*.h deploy\include\qpid\
@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\
@copy /Y qpid\framing\*.h deploy\include\qpid\framing\
@copy /Y qpid\sys\*.h deploy\include\qpid\sys\
@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\
@copy /Y qpid\log\*.h deploy\include\qpid\log\
@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\
@copy /Y qpid\management\*.h deploy\include\qpid\management\

@copy /Y $(OutDir)\qpidcommon.dll deploy\lib\
@copy /Y .\qpidcommon.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\common\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\common\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="COMMON_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommonsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommond.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidcommond.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid
@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10
@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing
@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows
@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows
@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\*.h deploy\include\qpid\
@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\
@copy /Y qpid\framing\*.h deploy\include\qpid\framing\
@copy /Y qpid\sys\*.h deploy\include\qpid\sys\
@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\
@copy /Y qpid\log\*.h deploy\include\qpid\log\
@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\
@copy /Y qpid\management\*.h deploy\include\qpid\management\

@copy /Y $(OutDir)\qpidcommond.dll deploy\lib\
@copy /Y .\qpidcommond.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\common\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\common\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="COMMON_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommons.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommon.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidcommon.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid
@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10
@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing
@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows
@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows
@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\*.h deploy\include\qpid\
@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\
@copy /Y qpid\framing\*.h deploy\include\qpid\framing\
@copy /Y qpid\sys\*.h deploy\include\qpid\sys\
@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\
@copy /Y qpid\log\*.h deploy\include\qpid\log\
@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\
@copy /Y qpid\management\*.h deploy\include\qpid\management\

@copy /Y $(OutDir)\qpidcommon.dll deploy\lib\
@copy /Y .\qpidcommon.lib deploy\lib\
"
/>
</Configuration>
</Configurations>
@@ -378,6 +420,9 @@ RelativePath="gen\qpid\framing\ClusterConnectionExchangeBody.cpp">
</File>
<File
+ RelativePath="gen\qpid\framing\ClusterConnectionExpiryIdBody.cpp">
+ </File>
+ <File
RelativePath="gen\qpid\framing\ClusterConnectionMembershipBody.cpp">
</File>
<File
@@ -954,6 +999,9 @@ RelativePath="qpid\sys\windows\LockFile.cpp">
</File>
<File
+ RelativePath="qpid\sys\windows\PollableCondition.cpp">
+ </File>
+ <File
RelativePath="qpid\sys\windows\Shlib.cpp">
<FileConfiguration
Name="Debug|Win32">
@@ -1081,6 +1129,9 @@ RelativePath="gen\qpid\framing\ClusterConnectionExchangeBody.h">
</File>
<File
+ RelativePath="gen\qpid\framing\ClusterConnectionExpiryIdBody.h">
+ </File>
+ <File
RelativePath="gen\qpid\framing\ClusterConnectionMembershipBody.h">
</File>
<File
diff --git a/qpid/cpp/src/qmfc.mk b/qpid/cpp/src/qmfc.mk index 46e8d82f35..a95028413d 100644 --- a/qpid/cpp/src/qmfc.mk +++ b/qpid/cpp/src/qmfc.mk @@ -26,6 +26,7 @@ module_hdr += \ qpid/console/Agent.h \ qpid/console/Broker.h \ qpid/console/ClassKey.h \ + qpid/console/ConsoleImportExport.h \ qpid/console/ConsoleListener.h \ qpid/console/Event.h \ qpid/console/Object.h \ @@ -43,6 +44,7 @@ libqmfconsole_la_SOURCES = \ qpid/console/Broker.cpp \ qpid/console/ClassKey.h \ qpid/console/ClassKey.cpp \ + qpid/console/ConsoleImportExport.h \ qpid/console/ConsoleListener.h \ qpid/console/Event.h \ qpid/console/Event.cpp \ diff --git a/qpid/cpp/src/qmfconsole.vcproj b/qpid/cpp/src/qmfconsole.vcproj index c37055adec..d2f79af64b 100644 --- a/qpid/cpp/src/qmfconsole.vcproj +++ b/qpid/cpp/src/qmfconsole.vcproj @@ -43,8 +43,8 @@ <Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\qmfconsole\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\qmfconsole\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CONSOLE_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsolesd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\qmfconsoled.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qmfconsoled.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\console\*.h deploy\include\qpid\console\

@copy /Y $(OutDir)\qmfconsoled.dll deploy\lib\
@copy /Y .\qmfconsoled.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\qmfconsole\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\qmfconsole\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CONSOLE_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsoles.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\qmfconsole.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qmfconsole.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\console\*.h deploy\include\qpid\console\

@copy /Y $(OutDir)\qmfconsole.dll deploy\lib\
@copy /Y .\qmfconsole.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\qmfconsole\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\qmfconsole\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CONSOLE_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsolesd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\qmfconsoled.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qmfconsoled.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\console\*.h deploy\include\qpid\console\

@copy /Y $(OutDir)\qmfconsoled.dll deploy\lib\
@copy /Y .\qmfconsoled.lib deploy\lib\
"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\qmfconsole\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\qmfconsole\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CONSOLE_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@ />
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsoles.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\qmfconsole.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qmfconsole.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@ />
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console
@if not exist deploy\lib mkdir deploy\lib

@copy /Y qpid\console\*.h deploy\include\qpid\console\

@copy /Y $(OutDir)\qmfconsole.dll deploy\lib\
@copy /Y .\qmfconsole.lib deploy\lib\
"
/>
</Configuration>
</Configurations>
diff --git a/qpid/cpp/src/qpid.sln b/qpid/cpp/src/qpid.sln index a296a13d25..c7004444f9 100644 --- a/qpid/cpp/src/qpid.sln +++ b/qpid/cpp/src/qpid.sln @@ -7,7 +7,7 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # this file will be lost the next time it is generated.
#
# MPC Command:
-# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 -static qpid.mwc
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 qpid.mwc
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "broker", "broker.vcproj", "{09613D48-FECA-1BAD-9D20-8C374564ADCF}"
ProjectSection(ProjectDependencies) = postProject
{C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF} = {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF}
@@ -25,6 +25,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmfconsole", "qmfconsole.vc {6961DBA3-FECA-1BAD-F396-8C394564ADCF} = {6961DBA3-FECA-1BAD-F396-8C394564ADCF}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qpidbroker", "qpidbroker.vcproj", "{66213D3E-FECA-1BAD-9D20-8C374564ADCF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {09613D48-FECA-1BAD-9D20-8C374564ADCF} = {09613D48-FECA-1BAD-9D20-8C374564ADCF}
+ {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF} = {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -65,6 +71,14 @@ Global {C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|Win32.Build.0 = Release|Win32
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|x64.ActiveCfg = Release|x64
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|x64.Build.0 = Release|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|Win32.Build.0 = Debug|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|x64.ActiveCfg = Debug|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|x64.Build.0 = Debug|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|Win32.ActiveCfg = Release|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|Win32.Build.0 = Release|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|x64.ActiveCfg = Release|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/src/qpid/Address.h b/qpid/cpp/src/qpid/Address.h index 9669985165..a5a4345ba3 100755 --- a/qpid/cpp/src/qpid/Address.h +++ b/qpid/cpp/src/qpid/Address.h @@ -20,7 +20,7 @@ */ #include "qpid/sys/IntegerTypes.h" - +#include "qpid/CommonImportExport.h" #include <boost/variant.hpp> #include <iosfwd> #include <string> @@ -31,12 +31,12 @@ namespace qpid { /** TCP address of a broker - host:port */ struct TcpAddress { static const uint16_t DEFAULT_PORT=5672; - explicit TcpAddress(const std::string& host_=std::string(),uint16_t port_=DEFAULT_PORT); + QPID_COMMON_EXTERN explicit TcpAddress(const std::string& host_=std::string(),uint16_t port_=DEFAULT_PORT); std::string host; uint16_t port; }; bool operator==(const TcpAddress& x, const TcpAddress& y); -std::ostream& operator<<(std::ostream& os, const TcpAddress& a); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const TcpAddress& a); /**@internal Not a real address type, this is a placeholder to * demonstrate and validate multi-protocol Urls for unit tests and diff --git a/qpid/cpp/src/qpid/CommonImportExport.h b/qpid/cpp/src/qpid/CommonImportExport.h new file mode 100644 index 0000000000..47872646d9 --- /dev/null +++ b/qpid/cpp/src/qpid/CommonImportExport.h @@ -0,0 +1,33 @@ +#ifndef QPID_COMMON_IMPORT_EXPORT_H +#define QPID_COMMON_IMPORT_EXPORT_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. + */ + +#if defined(WIN32) && !defined(QPID_DECLARE_STATIC) +#if defined(COMMON_EXPORT) +#define QPID_COMMON_EXTERN __declspec(dllexport) +#else +#define QPID_COMMON_EXTERN __declspec(dllimport) +#endif +#else +#define QPID_COMMON_EXTERN +#endif + +#endif diff --git a/qpid/cpp/src/qpid/DataDir.h b/qpid/cpp/src/qpid/DataDir.h index 6b45d8747b..dfdd498cbc 100644 --- a/qpid/cpp/src/qpid/DataDir.h +++ b/qpid/cpp/src/qpid/DataDir.h @@ -24,6 +24,7 @@ #include <string> #include <memory> #include "qpid/sys/LockFile.h" +#include "qpid/CommonImportExport.h" namespace qpid { @@ -38,8 +39,8 @@ class DataDir public: - DataDir (std::string path); - ~DataDir (); + QPID_COMMON_EXTERN DataDir (std::string path); + QPID_COMMON_EXTERN ~DataDir (); bool isEnabled() { return enabled; } const std::string& getPath() { return dirPath; } diff --git a/qpid/cpp/src/qpid/Exception.h b/qpid/cpp/src/qpid/Exception.h index 86bf8fbc4a..0b0bc33e93 100644 --- a/qpid/cpp/src/qpid/Exception.h +++ b/qpid/cpp/src/qpid/Exception.h @@ -27,7 +27,7 @@ #include "qpid/framing/enum.h" #include "qpid/sys/StrError.h" #include "qpid/Msg.h" - +#include "qpid/CommonImportExport.h" #include <memory> #include <string> #include <errno.h> @@ -41,11 +41,11 @@ namespace qpid class Exception : public std::exception { public: - explicit Exception(const std::string& message=std::string()) throw(); - virtual ~Exception() throw(); - virtual const char* what() const throw(); // prefix: message - virtual std::string getMessage() const; // Unprefixed message - virtual std::string getPrefix() const; // Prefix + QPID_COMMON_EXTERN explicit Exception(const std::string& message=std::string()) throw(); + QPID_COMMON_EXTERN virtual ~Exception() throw(); + QPID_COMMON_EXTERN virtual const char* what() const throw(); // prefix: message + QPID_COMMON_EXTERN virtual std::string getMessage() const; // Unprefixed message + QPID_COMMON_EXTERN virtual std::string getPrefix() const; // Prefix private: std::string message; @@ -77,8 +77,8 @@ struct ConnectionException : public Exception { }; struct ClosedException : public Exception { - ClosedException(const std::string& msg=std::string()); - std::string getPrefix() const; + QPID_COMMON_EXTERN ClosedException(const std::string& msg=std::string()); + QPID_COMMON_EXTERN std::string getPrefix() const; }; /** diff --git a/qpid/cpp/src/qpid/Modules.h b/qpid/cpp/src/qpid/Modules.h index 2a3b24f359..ce06dd0ef6 100644 --- a/qpid/cpp/src/qpid/Modules.h +++ b/qpid/cpp/src/qpid/Modules.h @@ -25,6 +25,7 @@ #include "Options.h" #include <string> #include <vector> +#include "qpid/CommonImportExport.h" namespace qpid { @@ -32,11 +33,11 @@ struct ModuleOptions : public qpid::Options { std::string loadDir; std::vector<std::string> load; bool noLoad; - ModuleOptions(const std::string& defaultModuleDir); + QPID_COMMON_EXTERN ModuleOptions(const std::string& defaultModuleDir); }; -void tryShlib(const char* libname, bool noThrow); -void loadModuleDir (std::string dirname, bool isDefault); +QPID_COMMON_EXTERN void tryShlib(const char* libname, bool noThrow); +QPID_COMMON_EXTERN void loadModuleDir (std::string dirname, bool isDefault); } // namespace qpid diff --git a/qpid/cpp/src/qpid/Options.h b/qpid/cpp/src/qpid/Options.h index cb86d27241..aeb7a79329 100644 --- a/qpid/cpp/src/qpid/Options.h +++ b/qpid/cpp/src/qpid/Options.h @@ -23,13 +23,25 @@ */ #include "qpid/Exception.h" + +// Disable warnings triggered by boost. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4251 4275) +#endif + #include <boost/program_options.hpp> #include <boost/format.hpp> + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + #include <sstream> #include <iterator> #include <algorithm> #include <string> - +#include "qpid/CommonImportExport.h" namespace qpid { namespace po=boost::program_options; @@ -37,7 +49,7 @@ namespace po=boost::program_options; ///@internal -std::string prettyArg(const std::string&, const std::string&); +QPID_COMMON_EXTERN std::string prettyArg(const std::string&, const std::string&); /** @internal Normally only constructed by optValue() */ template <class T> @@ -192,24 +204,20 @@ options_description_less_easy_init #endif - - - - struct Options : public po::options_description { struct Exception : public qpid::Exception { Exception(const std::string& msg) : qpid::Exception(msg) {} }; - Options(const std::string& name=std::string()); + QPID_COMMON_EXTERN Options(const std::string& name=std::string()); /** * Parses options from argc/argv, environment variables and config file. * Note the filename argument can reference an options variable that * is updated by argc/argv or environment variable parsing. */ - void parse(int argc, char const* const* argv, + QPID_COMMON_EXTERN void parse(int argc, char const* const* argv, const std::string& configfile=std::string(), bool allowUnknown = false); @@ -242,7 +250,7 @@ struct Options : public po::options_description { * Standard options for configuration */ struct CommonOptions : public Options { - CommonOptions(const std::string& name=std::string(), + QPID_COMMON_EXTERN CommonOptions(const std::string& name=std::string(), const std::string& configfile=std::string()); bool help; bool version; diff --git a/qpid/cpp/src/qpid/Plugin.h b/qpid/cpp/src/qpid/Plugin.h index 50d8e01227..913152f9e1 100644 --- a/qpid/cpp/src/qpid/Plugin.h +++ b/qpid/cpp/src/qpid/Plugin.h @@ -24,6 +24,7 @@ #include <boost/noncopyable.hpp> #include <boost/function.hpp> #include <vector> +#include "qpid/CommonImportExport.h" /**@file Generic plug-in framework. */ @@ -46,10 +47,10 @@ class Plugin : private boost::noncopyable { { public: /** Calls finalize() if not already called. */ - virtual ~Target(); + QPID_COMMON_EXTERN virtual ~Target(); /** Run all the finalizers */ - void finalize(); + QPID_COMMON_EXTERN void finalize(); /** Add a function to run when finalize() is called */ void addFinalizer(const boost::function<void()>&); @@ -65,9 +66,9 @@ class Plugin : private boost::noncopyable { * member variable in a library so it is registered during * initialization when the library is loaded. */ - Plugin(); + QPID_COMMON_EXTERN Plugin(); - virtual ~Plugin(); + QPID_COMMON_EXTERN virtual ~Plugin(); /** * Configuration options for the plugin. @@ -76,7 +77,7 @@ class Plugin : private boost::noncopyable { * @return An options group or 0 for no options. Default returns 0. * Plugin retains ownership of return value. */ - virtual Options* getOptions(); + QPID_COMMON_EXTERN virtual Options* getOptions(); /** * Initialize Plugin functionality on a Target, called before @@ -101,16 +102,16 @@ class Plugin : private boost::noncopyable { /** List of registered Plugin objects. * Caller must not delete plugin pointers. */ - static const Plugins& getPlugins(); + QPID_COMMON_EXTERN static const Plugins& getPlugins(); /** Call earlyInitialize() on all registered plugins */ - static void earlyInitAll(Target&); + QPID_COMMON_EXTERN static void earlyInitAll(Target&); /** Call initialize() on all registered plugins */ - static void initializeAll(Target&); + QPID_COMMON_EXTERN static void initializeAll(Target&); /** For each registered plugin, add plugin.getOptions() to opts. */ - static void addOptions(Options& opts); + QPID_COMMON_EXTERN static void addOptions(Options& opts); }; } // namespace qpid diff --git a/qpid/cpp/src/qpid/SessionId.cpp b/qpid/cpp/src/qpid/SessionId.cpp index fce6619f5d..098998015f 100644 --- a/qpid/cpp/src/qpid/SessionId.cpp +++ b/qpid/cpp/src/qpid/SessionId.cpp @@ -35,7 +35,7 @@ bool SessionId::operator==(const SessionId& id) const { } std::ostream& operator<<(std::ostream& o, const SessionId& id) { - return o << id.getName() << "@" << id.getUserId(); + return o << id.getUserId() << "." << id.getName(); } std::string SessionId::str() const { diff --git a/qpid/cpp/src/qpid/SessionId.h b/qpid/cpp/src/qpid/SessionId.h index 291c42a2bb..bf52f9856b 100644 --- a/qpid/cpp/src/qpid/SessionId.h +++ b/qpid/cpp/src/qpid/SessionId.h @@ -24,6 +24,7 @@ #include <boost/operators.hpp> #include <string> +#include <qpid/CommonImportExport.h> namespace qpid { @@ -42,16 +43,16 @@ class SessionId : boost::totally_ordered1<SessionId> { std::string userId; std::string name; public: - SessionId(const std::string& userId=std::string(), const std::string& name=std::string()); + QPID_COMMON_EXTERN SessionId(const std::string& userId=std::string(), const std::string& name=std::string()); std::string getUserId() const { return userId; } std::string getName() const { return name; } - bool operator<(const SessionId&) const ; - bool operator==(const SessionId& id) const; + QPID_COMMON_EXTERN bool operator<(const SessionId&) const ; + QPID_COMMON_EXTERN bool operator==(const SessionId& id) const; // Convert to a string - std::string str() const; + QPID_COMMON_EXTERN std::string str() const; }; -std::ostream& operator<<(std::ostream&, const SessionId&); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionId&); } // namespace qpid diff --git a/qpid/cpp/src/qpid/SessionState.cpp b/qpid/cpp/src/qpid/SessionState.cpp index ac75b5c5ff..3e844fb24b 100644 --- a/qpid/cpp/src/qpid/SessionState.cpp +++ b/qpid/cpp/src/qpid/SessionState.cpp @@ -113,7 +113,8 @@ SessionState::ReplayRange SessionState::senderExpected(const SessionPoint& expec void SessionState::senderRecord(const AMQFrame& f) { if (isControl(f)) return; // Ignore control frames. - QPID_LOG_IF(debug, f.getMethod(), getId() << ": sent cmd " << sender.sendPoint.command << ": " << *f.getMethod()); + QPID_LOG(trace, getId() << ": sent cmd " << sender.sendPoint.command << ": " << *f.getBody()); + stateful = true; if (timeout) sender.replayList.push_back(f); sender.unflushedSize += f.encodedSize(); @@ -183,6 +184,7 @@ void SessionState::receiverSetCommandPoint(const SessionPoint& point) { } bool SessionState::receiverRecord(const AMQFrame& f) { + if (receiverTrackingDisabled) return true; //Very nasty hack for push bridges if (isControl(f)) return true; // Ignore control frames. stateful = true; receiver.expected.advance(f); @@ -192,12 +194,13 @@ bool SessionState::receiverRecord(const AMQFrame& f) { receiver.received = receiver.expected; receiver.incomplete += receiverGetCurrent(); } - QPID_LOG_IF(debug, f.getMethod(), getId() << ": recv cmd " << receiverGetCurrent() << ": " << *f.getMethod()); - QPID_LOG_IF(debug, !firstTime, "Ignoring duplicate frame: " << receiverGetCurrent() << ": " << f); + QPID_LOG(trace, getId() << ": recv cmd " << receiverGetCurrent() << ": " << *f.getBody()); + if (!firstTime) QPID_LOG(trace, "Ignoring duplicate frame."); return firstTime; } void SessionState::receiverCompleted(SequenceNumber command, bool cumulative) { + if (receiverTrackingDisabled) return; //Very nasty hack for push bridges assert(receiver.incomplete.contains(command)); // Internal error to complete command twice. SequenceNumber first =cumulative ? receiver.incomplete.front() : command; SequenceNumber last = command; @@ -237,7 +240,7 @@ SessionState::Configuration::Configuration(size_t flush, size_t hard) : replayFlushLimit(flush), replayHardLimit(hard) {} SessionState::SessionState(const SessionId& i, const Configuration& c) - : id(i), timeout(), config(c), stateful() + : id(i), timeout(), config(c), stateful(), receiverTrackingDisabled(false) { QPID_LOG(debug, "SessionState::SessionState " << id << ": " << this); } @@ -275,4 +278,7 @@ void SessionState::setState( receiver.bytesSinceKnownCompleted = 0; } +void SessionState::disableReceiverTracking() { receiverTrackingDisabled = true; } +void SessionState::enableReceiverTracking() { receiverTrackingDisabled = false; } + } // namespace qpid diff --git a/qpid/cpp/src/qpid/SessionState.h b/qpid/cpp/src/qpid/SessionState.h index bf4ff6d326..da28738546 100644 --- a/qpid/cpp/src/qpid/SessionState.h +++ b/qpid/cpp/src/qpid/SessionState.h @@ -31,6 +31,7 @@ #include <boost/range/iterator_range.hpp> #include <vector> #include <iosfwd> +#include <qpid/CommonImportExport.h> namespace qpid { using framing::SequenceNumber; @@ -38,19 +39,19 @@ using framing::SequenceSet; /** A point in the session. Points to command id + offset */ struct SessionPoint : boost::totally_ordered1<SessionPoint> { - SessionPoint(SequenceNumber command = 0, uint64_t offset = 0); + QPID_COMMON_EXTERN SessionPoint(SequenceNumber command = 0, uint64_t offset = 0); SequenceNumber command; uint64_t offset; /** Advance past frame f */ - void advance(const framing::AMQFrame& f); + QPID_COMMON_EXTERN void advance(const framing::AMQFrame& f); - bool operator<(const SessionPoint&) const; - bool operator==(const SessionPoint&) const; + QPID_COMMON_EXTERN bool operator<(const SessionPoint&) const; + QPID_COMMON_EXTERN bool operator==(const SessionPoint&) const; }; -std::ostream& operator<<(std::ostream&, const SessionPoint&); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionPoint&); /** * Support for session idempotence barrier and resume as defined in @@ -78,14 +79,14 @@ class SessionState { typedef boost::iterator_range<ReplayList::iterator> ReplayRange; struct Configuration { - Configuration(size_t flush=1024*1024, size_t hard=0); + QPID_COMMON_EXTERN Configuration(size_t flush=1024*1024, size_t hard=0); size_t replayFlushLimit; // Flush when the replay list >= N bytes. 0 disables. size_t replayHardLimit; // Kill session if replay list > N bytes. 0 disables. }; - SessionState(const SessionId& =SessionId(), const Configuration& =Configuration()); + QPID_COMMON_EXTERN SessionState(const SessionId& =SessionId(), const Configuration& =Configuration()); - virtual ~SessionState(); + QPID_COMMON_EXTERN virtual ~SessionState(); bool hasState() const; @@ -100,78 +101,78 @@ class SessionState { // ==== Functions for sender state. /** Record frame f for replay. Should not be called during replay. */ - virtual void senderRecord(const framing::AMQFrame& f); + QPID_COMMON_EXTERN virtual void senderRecord(const framing::AMQFrame& f); /** @return true if we should send flush for confirmed and completed commands. */ - virtual bool senderNeedFlush() const; + QPID_COMMON_EXTERN virtual bool senderNeedFlush() const; /** Called when flush for confirmed and completed commands is sent to peer. */ - virtual void senderRecordFlush(); + QPID_COMMON_EXTERN virtual void senderRecordFlush(); /** True if we should reply to the next incoming completed command */ - virtual bool senderNeedKnownCompleted() const; + QPID_COMMON_EXTERN virtual bool senderNeedKnownCompleted() const; /** Called when knownCompleted is sent to peer. */ - virtual void senderRecordKnownCompleted(); + QPID_COMMON_EXTERN virtual void senderRecordKnownCompleted(); /** Called when the peer confirms up to comfirmed. */ - virtual void senderConfirmed(const SessionPoint& confirmed); + QPID_COMMON_EXTERN virtual void senderConfirmed(const SessionPoint& confirmed); /** Called when the peer indicates commands completed */ - virtual void senderCompleted(const SequenceSet& commands); + QPID_COMMON_EXTERN virtual void senderCompleted(const SequenceSet& commands); /** Point from which the next new (not replayed) data will be sent. */ - virtual SessionPoint senderGetCommandPoint(); + QPID_COMMON_EXTERN virtual SessionPoint senderGetCommandPoint(); /** Set of outstanding incomplete commands */ - virtual SequenceSet senderGetIncomplete() const; + QPID_COMMON_EXTERN virtual SequenceSet senderGetIncomplete() const; /** Point from which we can replay. */ - virtual SessionPoint senderGetReplayPoint() const; + QPID_COMMON_EXTERN virtual SessionPoint senderGetReplayPoint() const; /** Peer expecting commands from this point. *@return Range of frames to be replayed. */ - virtual ReplayRange senderExpected(const SessionPoint& expected); + QPID_COMMON_EXTERN virtual ReplayRange senderExpected(const SessionPoint& expected); // ==== Functions for receiver state /** Set the command point. */ - virtual void receiverSetCommandPoint(const SessionPoint& point); + QPID_COMMON_EXTERN virtual void receiverSetCommandPoint(const SessionPoint& point); /** Returns true if frame should be be processed, false if it is a duplicate. */ - virtual bool receiverRecord(const framing::AMQFrame& f); + QPID_COMMON_EXTERN virtual bool receiverRecord(const framing::AMQFrame& f); /** Command completed locally */ - virtual void receiverCompleted(SequenceNumber command, bool cumulative=false); + QPID_COMMON_EXTERN virtual void receiverCompleted(SequenceNumber command, bool cumulative=false); /** Peer has indicated commands are known completed */ - virtual void receiverKnownCompleted(const SequenceSet& commands); + QPID_COMMON_EXTERN virtual void receiverKnownCompleted(const SequenceSet& commands); /** True if the next completed control should set the timely-reply argument * to request a knonw-completed response. */ - virtual bool receiverNeedKnownCompleted() const; + QPID_COMMON_EXTERN virtual bool receiverNeedKnownCompleted() const; /** Get the incoming command point */ - virtual const SessionPoint& receiverGetExpected() const; + QPID_COMMON_EXTERN virtual const SessionPoint& receiverGetExpected() const; /** Get the received high-water-mark, may be > getExpected() during replay */ - virtual const SessionPoint& receiverGetReceived() const; + QPID_COMMON_EXTERN virtual const SessionPoint& receiverGetReceived() const; /** Completed received commands that the peer may not know about. */ - virtual const SequenceSet& receiverGetUnknownComplete() const; + QPID_COMMON_EXTERN virtual const SequenceSet& receiverGetUnknownComplete() const; /** Incomplete received commands. */ - virtual const SequenceSet& receiverGetIncomplete() const; + QPID_COMMON_EXTERN virtual const SequenceSet& receiverGetIncomplete() const; /** ID of the command currently being handled. */ - virtual SequenceNumber receiverGetCurrent() const; + QPID_COMMON_EXTERN virtual SequenceNumber receiverGetCurrent() const; /** Set the state variables, used to create a session that will resume * from some previously established point. */ - virtual void setState( + QPID_COMMON_EXTERN virtual void setState( const SequenceNumber& replayStart, const SequenceNumber& sendCommandPoint, const SequenceSet& sentIncomplete, @@ -181,6 +182,20 @@ class SessionState { const SequenceSet& receivedIncomplete ); + /** + * So called 'push' bridges work by faking a subscribe request + * (and the accompanying flows etc) to the local broker to initiate + * the outflow of messages for the bridge. + * + * As the peer doesn't send these it cannot include them in its + * session state. To keep the session state on either side of the + * bridge in sync, this hack allows the tracking of state for + * received messages to be disabled for the faked commands and + * subsequently re-enabled. + */ + QPID_COMMON_EXTERN void disableReceiverTracking(); + QPID_COMMON_EXTERN void enableReceiverTracking(); + private: struct SendState { @@ -209,6 +224,7 @@ class SessionState { uint32_t timeout; Configuration config; bool stateful; + bool receiverTrackingDisabled;//very nasty hack for 'push' bridges }; inline bool operator==(const SessionId& id, const SessionState& s) { return s == id; } diff --git a/qpid/cpp/src/qpid/StringUtils.h b/qpid/cpp/src/qpid/StringUtils.h index 3120e43334..4130fae017 100644 --- a/qpid/cpp/src/qpid/StringUtils.h +++ b/qpid/cpp/src/qpid/StringUtils.h @@ -22,6 +22,8 @@ * */ +#include "qpid/CommonImportExport.h" + #include <string> #include <vector> @@ -31,12 +33,12 @@ namespace qpid { * Split 'in' into words using delimiters in 'delims' and put * resulting strings into 'out' vector. */ -void split(std::vector<std::string>& out, const std::string& in, const std::string& delims); +QPID_COMMON_EXTERN void split(std::vector<std::string>& out, const std::string& in, const std::string& delims); /** * Split 'in' into words using delimiters in 'delims' and return the * resulting strings in a vector. */ -std::vector<std::string> split(const std::string& in, const std::string& delims); +QPID_COMMON_EXTERN std::vector<std::string> split(const std::string& in, const std::string& delims); } // namespace qpid diff --git a/qpid/cpp/src/qpid/Url.h b/qpid/cpp/src/qpid/Url.h index 07ca46e70c..353eac28f3 100644 --- a/qpid/cpp/src/qpid/Url.h +++ b/qpid/cpp/src/qpid/Url.h @@ -25,10 +25,11 @@ #include <vector> #include <new> #include <ostream> +#include "qpid/CommonImportExport.h" namespace qpid { -std::ostream& operator<<(std::ostream& os, const TcpAddress& a); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const TcpAddress& a); /** An AMQP URL contains a list of addresses */ struct Url : public std::vector<Address> { @@ -38,12 +39,12 @@ struct Url : public std::vector<Address> { /** Url with local IP address(es), may be more than one address * on a multi-homed host. */ - static Url getIpAddressesUrl(uint16_t port); + QPID_COMMON_EXTERN static Url getIpAddressesUrl(uint16_t port); struct Invalid : public Exception { Invalid(const std::string& s); }; /** Convert to string form. */ - std::string str() const; + QPID_COMMON_EXTERN std::string str() const; /** Empty URL. */ Url() {} @@ -62,14 +63,14 @@ struct Url : public std::vector<Address> { Url& operator=(const std::string& s) { parse(s); return *this; } /** Throw Invalid if the URL does not contain any addresses. */ - void throwIfEmpty() const; + QPID_COMMON_EXTERN void throwIfEmpty() const; /** Replace contents with parsed URL as defined in * https://wiki.108.redhat.com/jira/browse/AMQP-95 *@exception Invalid if the url is invalid. */ - void parse(const char* url); - void parse(const std::string& url) { parse(url.c_str()); } + QPID_COMMON_EXTERN void parse(const char* url); + QPID_COMMON_EXTERN void parse(const std::string& url) { parse(url.c_str()); } /** Replace contesnts with parsed URL as defined in * https://wiki.108.redhat.com/jira/browse/AMQP-95 @@ -84,8 +85,8 @@ struct Url : public std::vector<Address> { inline bool operator==(const Url& a, const Url& b) { return a.str()==b.str(); } inline bool operator!=(const Url& a, const Url& b) { return a.str()!=b.str(); } -std::ostream& operator<<(std::ostream& os, const Url& url); -std::istream& operator>>(std::istream& is, Url& url); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const Url& url); +QPID_COMMON_EXTERN std::istream& operator>>(std::istream& is, Url& url); } // namespace qpid diff --git a/qpid/cpp/src/qpid/Version.h b/qpid/cpp/src/qpid/Version.h index 9bd561b7a9..ab7957e000 100755 --- a/qpid/cpp/src/qpid/Version.h +++ b/qpid/cpp/src/qpid/Version.h @@ -36,7 +36,7 @@ namespace qpid { # endif #else const std::string product = "qpidc"; - const std::string version = "0.3"; + const std::string version = "0.5"; const std::string saslName = "qpid-broker"; #endif } diff --git a/qpid/cpp/src/qpid/acl/AclPlugin.cpp b/qpid/cpp/src/qpid/acl/AclPlugin.cpp index 7310139041..4c6efa19dd 100644 --- a/qpid/cpp/src/qpid/acl/AclPlugin.cpp +++ b/qpid/cpp/src/qpid/acl/AclPlugin.cpp @@ -62,15 +62,10 @@ struct AclPlugin : public Plugin { if (acl) throw Exception("ACL plugin cannot be initialized twice in one process."); - if (values.aclFile.at(0) == '/') - { - values.aclFile = values.aclFile; - } - else - { - std::ostringstream oss; - oss << b.getDataDir().getPath() << "/" << values.aclFile; - values.aclFile = oss.str(); + if (values.aclFile.at(0) != '/' && !b.getDataDir().getPath().empty()) { + std::ostringstream oss; + oss << b.getDataDir().getPath() << "/" << values.aclFile; + values.aclFile = oss.str(); } acl = new Acl(values, b); diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp index 1e2f4cdd78..7c70c12213 100644 --- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp +++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp @@ -151,7 +151,7 @@ void ManagementAgentImpl::init(const client::ConnectionSettings& settings, // TODO: Abstract the socket calls for portability if (extThread) { int pair[2]; - int result = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair); + int result = socketpair(PF_UNIX, SOCK_STREAM, 0, pair); if (result == -1) { return; } @@ -485,6 +485,9 @@ void ManagementAgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, st Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; + if (object->getConfigChanged() || object->getInstChanged()) + object->setUpdateTime(); + encodeHeader(outBuffer, 'g', sequence); object->writeProperties(outBuffer); object->writeStatistics(outBuffer, true); @@ -508,6 +511,9 @@ void ManagementAgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, st Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; + if (object->getConfigChanged() || object->getInstChanged()) + object->setUpdateTime(); + encodeHeader(outBuffer, 'g', sequence); object->writeProperties(outBuffer); object->writeStatistics(outBuffer, true); diff --git a/qpid/cpp/src/qpid/amqp_0_10/Connection.h b/qpid/cpp/src/qpid/amqp_0_10/Connection.h index 743a7de3aa..3e0a5d1ee8 100644 --- a/qpid/cpp/src/qpid/amqp_0_10/Connection.h +++ b/qpid/cpp/src/qpid/amqp_0_10/Connection.h @@ -27,6 +27,7 @@ #include "qpid/sys/ConnectionInputHandler.h" #include "qpid/sys/ConnectionOutputHandler.h" #include "qpid/sys/Mutex.h" +#include "qpid/broker/BrokerImportExport.h" #include <boost/intrusive_ptr.hpp> #include <memory> #include <deque> @@ -56,8 +57,8 @@ class Connection : public sys::ConnectionCodec, size_t buffered; public: - Connection(sys::OutputControl&, const std::string& id, bool isClient); - void setInputHandler(std::auto_ptr<sys::ConnectionInputHandler> c); + QPID_BROKER_EXTERN Connection(sys::OutputControl&, const std::string& id, bool isClient); + QPID_BROKER_EXTERN void setInputHandler(std::auto_ptr<sys::ConnectionInputHandler> c); size_t decode(const char* buffer, size_t size); size_t encode(const char* buffer, size_t size); bool isClosed() const; diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp index f58d59cbd7..db957051d8 100644 --- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp +++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp @@ -277,7 +277,6 @@ void SessionHandler::sendCompletion() { } void SessionHandler::sendAttach(bool force) { - CHECK_ATTACHED("session.send-attach"); QPID_LOG(debug, "SessionHandler::sendAttach attach id=" << getState()->getId()); peer.attach(getState()->getId().getName(), force); if (getState()->hasState()) diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h index d7af7dd6c7..0b158ec2b4 100644 --- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h +++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h @@ -26,6 +26,7 @@ #include "qpid/framing/AMQP_AllProxy.h" #include "qpid/framing/AMQP_AllOperations.h" #include "qpid/SessionState.h" +#include "qpid/CommonImportExport.h" namespace qpid { @@ -43,8 +44,8 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler, public framing::FrameHandler::InOutHandler { public: - SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0); - ~SessionHandler(); + QPID_COMMON_EXTERN SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0); + QPID_COMMON_EXTERN ~SessionHandler(); void setChannel(uint16_t ch) { channel = ch; } uint16_t getChannel() const { return channel.get(); } @@ -55,35 +56,35 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler, virtual framing::FrameHandler* getInHandler() = 0; // Non-protocol methods, called locally to initiate some action. - void sendDetach(); - void sendCompletion(); - void sendAttach(bool force); - void sendTimeout(uint32_t t); - void sendFlush(); - void markReadyToSend();//TODO: only needed for inter-broker bridge; cleanup + QPID_COMMON_EXTERN void sendDetach(); + QPID_COMMON_EXTERN void sendCompletion(); + QPID_COMMON_EXTERN void sendAttach(bool force); + QPID_COMMON_EXTERN void sendTimeout(uint32_t t); + QPID_COMMON_EXTERN void sendFlush(); + QPID_COMMON_EXTERN void markReadyToSend();//TODO: only needed for inter-broker bridge; cleanup /** True if the handler is ready to send and receive */ bool ready() const; // Protocol methods - void attach(const std::string& name, bool force); - void attached(const std::string& name); - void detach(const std::string& name); - void detached(const std::string& name, uint8_t code); - - void requestTimeout(uint32_t t); - void timeout(uint32_t t); - - void commandPoint(const framing::SequenceNumber& id, uint64_t offset); - void expected(const framing::SequenceSet& commands, const framing::Array& fragments); - void confirmed(const framing::SequenceSet& commands,const framing::Array& fragments); - void completed(const framing::SequenceSet& commands, bool timelyReply); - void knownCompleted(const framing::SequenceSet& commands); - void flush(bool expected, bool confirmed, bool completed); - void gap(const framing::SequenceSet& commands); + QPID_COMMON_EXTERN void attach(const std::string& name, bool force); + QPID_COMMON_EXTERN void attached(const std::string& name); + QPID_COMMON_EXTERN void detach(const std::string& name); + QPID_COMMON_EXTERN void detached(const std::string& name, uint8_t code); + + QPID_COMMON_EXTERN void requestTimeout(uint32_t t); + QPID_COMMON_EXTERN void timeout(uint32_t t); + + QPID_COMMON_EXTERN void commandPoint(const framing::SequenceNumber& id, uint64_t offset); + QPID_COMMON_EXTERN void expected(const framing::SequenceSet& commands, const framing::Array& fragments); + QPID_COMMON_EXTERN void confirmed(const framing::SequenceSet& commands,const framing::Array& fragments); + QPID_COMMON_EXTERN void completed(const framing::SequenceSet& commands, bool timelyReply); + QPID_COMMON_EXTERN void knownCompleted(const framing::SequenceSet& commands); + QPID_COMMON_EXTERN void flush(bool expected, bool confirmed, bool completed); + QPID_COMMON_EXTERN void gap(const framing::SequenceSet& commands); protected: - virtual void invoke(const framing::AMQMethodBody& m); + QPID_COMMON_EXTERN virtual void invoke(const framing::AMQMethodBody& m); virtual void setState(const std::string& sessionName, bool force) = 0; virtual void channelException(framing::session::DetachCode code, const std::string& msg) = 0; @@ -94,9 +95,9 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler, virtual void readyToSend() {} virtual void readyToReceive() {} - virtual void handleDetach(); - virtual void handleIn(framing::AMQFrame&); - virtual void handleOut(framing::AMQFrame&); + QPID_COMMON_EXTERN virtual void handleDetach(); + QPID_COMMON_EXTERN virtual void handleIn(framing::AMQFrame&); + QPID_COMMON_EXTERN virtual void handleOut(framing::AMQFrame&); framing::ChannelHandler channel; framing::AMQP_AllProxy::Session peer; diff --git a/qpid/cpp/src/qpid/assert.cpp b/qpid/cpp/src/qpid/assert.cpp index 5d039da528..bf36d3be86 100644 --- a/qpid/cpp/src/qpid/assert.cpp +++ b/qpid/cpp/src/qpid/assert.cpp @@ -35,7 +35,7 @@ void assert_fail(char const * expr, char const * function, char const * file, lo #ifdef NDEBUG throw framing::InternalErrorException(msg.str()); #else - std::cerr << msg << std::endl; + std::cerr << msg.str() << std::endl; abort(); #endif } diff --git a/qpid/cpp/src/qpid/broker/Bridge.cpp b/qpid/cpp/src/qpid/broker/Bridge.cpp index 38a9b5d64c..4d275b958f 100644 --- a/qpid/cpp/src/qpid/broker/Bridge.cpp +++ b/qpid/cpp/src/qpid/broker/Bridge.cpp @@ -22,6 +22,7 @@ #include "ConnectionState.h" #include "Connection.h" #include "LinkRegistry.h" +#include "SessionState.h" #include "qpid/agent/ManagementAgent.h" #include "qpid/framing/FieldTable.h" @@ -80,31 +81,31 @@ Bridge::~Bridge() mgmtObject->resourceDestroy(); } -void Bridge::create(ConnectionState& c) +void Bridge::create(Connection& c) { + connState = &c; FieldTable options; if (args.i_sync) options.setInt("qpid.sync_frequency", args.i_sync); - connState = &c; + SessionHandler& sessionHandler = c.getChannel(id); if (args.i_srcIsLocal) { if (args.i_dynamic) throw Exception("Dynamic routing not supported for push routes"); // Point the bridging commands at the local connection handler - Connection* conn = dynamic_cast<Connection*>(&c); - if (conn == 0) - return; - pushHandler.reset(new PushHandler(conn)); + pushHandler.reset(new PushHandler(&c)); channelHandler.reset(new framing::ChannelHandler(id, pushHandler.get())); + + session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler)); + peer.reset(new framing::AMQP_ServerProxy(*channelHandler)); + + session->attach(name, false); + session->commandPoint(0,0); } else { + sessionHandler.attachAs(name); // Point the bridging commands at the remote peer broker - channelHandler.reset(new framing::ChannelHandler(id, &(connState->getOutput()))); + peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out)); } - session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler)); - peer.reset(new framing::AMQP_ServerProxy(*channelHandler)); - - session->attach(name, false); - session->commandPoint(0,0); - + if (args.i_srcIsLocal) sessionHandler.getSession()->disableReceiverTracking(); if (args.i_srcIsQueue) { peer->getMessage().subscribe(args.i_src, args.i_dest, args.i_sync ? 0 : 1, 0, false, "", 0, options); peer->getMessage().flow(args.i_dest, 0, 0xFFFFFFFF); @@ -116,7 +117,7 @@ void Bridge::create(ConnectionState& c) if (args.i_tag.size()) { queueSettings.setString("qpid.trace.id", args.i_tag); } else { - const string& peerTag = connState->getFederationPeerTag(); + const string& peerTag = c.getFederationPeerTag(); if (peerTag.size()) queueSettings.setString("qpid.trace.id", peerTag); } @@ -129,7 +130,7 @@ void Bridge::create(ConnectionState& c) queueSettings.setString("qpid.trace.exclude", localTag); } - bool durable = false;//should this be an arg, or would be use srcIsQueue for durable queues? + bool durable = false;//should this be an arg, or would we use srcIsQueue for durable queues? bool autoDelete = !durable;//auto delete transient queues? peer->getQueue().declare(queueName, "", false, durable, true, autoDelete, queueSettings); if (!args.i_dynamic) @@ -148,12 +149,23 @@ void Bridge::create(ConnectionState& c) QPID_LOG(debug, "Activated static route from exchange " << args.i_src << " to " << args.i_dest); } } + if (args.i_srcIsLocal) sessionHandler.getSession()->enableReceiverTracking(); } -void Bridge::cancel() +void Bridge::cancel(Connection& c) { + if (args.i_srcIsLocal) { + //recreate peer to be sure that the session handler reference + //is valid (it could have been deleted due to a detach) + SessionHandler& sessionHandler = c.getChannel(id); + peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out)); + } peer->getMessage().cancel(args.i_dest); peer->getSession().detach(name); +} + +void Bridge::closed() +{ if (args.i_dynamic) { Exchange::shared_ptr exchange = link->getBroker()->getExchanges().get(args.i_src); if (exchange.get() != 0) @@ -166,13 +178,13 @@ void Bridge::destroy() listener(this); } -void Bridge::setPersistenceId(uint64_t id) const +void Bridge::setPersistenceId(uint64_t pId) const { if (mgmtObject != 0 && persistenceId == 0) { ManagementAgent* agent = ManagementAgent::Singleton::getInstance(); - agent->addObject (mgmtObject, id); + agent->addObject (mgmtObject, pId); } - persistenceId = id; + persistenceId = pId; } const string& Bridge::getName() const diff --git a/qpid/cpp/src/qpid/broker/Bridge.h b/qpid/cpp/src/qpid/broker/Bridge.h index c530a5d696..dae28ddeaa 100644 --- a/qpid/cpp/src/qpid/broker/Bridge.h +++ b/qpid/cpp/src/qpid/broker/Bridge.h @@ -52,8 +52,9 @@ public: const qmf::org::apache::qpid::broker::ArgsLinkBridge& args); ~Bridge(); - void create(ConnectionState& c); - void cancel(); + void create(Connection& c); + void cancel(Connection& c); + void closed(); void destroy(); bool isDurable() { return args.i_durable; } diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp index 95f55bb596..3f9effc08f 100644 --- a/qpid/cpp/src/qpid/broker/Broker.cpp +++ b/qpid/cpp/src/qpid/broker/Broker.cpp @@ -199,6 +199,7 @@ Broker::Broker(const Broker::Options& conf) : } QueuePolicy::setDefaultMaxSize(conf.queueLimit); + queues.setQueueEvents(&queueEvents); // Early-Initialize plugins const Plugin::Plugins& plugins=Plugin::getPlugins(); @@ -383,9 +384,9 @@ Manageable::status_t Broker::ManagementMethod (uint32_t methodId, _qmf::ArgsBrokerQueueMoveMessages& moveArgs= dynamic_cast<_qmf::ArgsBrokerQueueMoveMessages&>(args); if (queueMoveMessages(moveArgs.i_srcQueue, moveArgs.i_destQueue, moveArgs.i_qty)) - status = Manageable::STATUS_OK; + status = Manageable::STATUS_OK; else - return Manageable::STATUS_INVALID_PARAMETER; + return Manageable::STATUS_INVALID_PARAMETER; break; } default: diff --git a/qpid/cpp/src/qpid/broker/Broker.h b/qpid/cpp/src/qpid/broker/Broker.h index a52a0f67e0..5a1529a3ba 100644 --- a/qpid/cpp/src/qpid/broker/Broker.h +++ b/qpid/cpp/src/qpid/broker/Broker.h @@ -22,6 +22,7 @@ * */ +#include "BrokerImportExport.h" #include "ConnectionFactory.h" #include "ConnectionToken.h" #include "DirectExchange.h" @@ -80,15 +81,16 @@ struct NoSuchTransportException : qpid::Exception * A broker instance. */ class Broker : public sys::Runnable, public Plugin::Target, - public management::Manageable, public RefCounted + public management::Manageable, + public RefCounted { - public: +public: struct Options : public qpid::Options { static const std::string DEFAULT_DATA_DIR_LOCATION; static const std::string DEFAULT_DATA_DIR_NAME; - Options(const std::string& name="Broker Options"); + QPID_BROKER_EXTERN Options(const std::string& name="Broker Options"); bool noDataDir; std::string dataDir; @@ -148,9 +150,9 @@ class Broker : public sys::Runnable, public Plugin::Target, virtual ~Broker(); - Broker(const Options& configuration); - static boost::intrusive_ptr<Broker> create(const Options& configuration); - static boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT); + QPID_BROKER_EXTERN Broker(const Options& configuration); + static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(const Options& configuration); + static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT); /** * Return listening port. If called before bind this is @@ -169,7 +171,7 @@ class Broker : public sys::Runnable, public Plugin::Target, /** Shut down the broker */ virtual void shutdown(); - void setStore (MessageStore*); + QPID_BROKER_EXTERN void setStore (MessageStore*); MessageStore& getStore() { return *store; } void setAcl (AclModule* _acl) {acl = _acl;} AclModule* getAcl() { return acl; } @@ -229,7 +231,7 @@ class Broker : public sys::Runnable, public Plugin::Target, boost::function<std::vector<Url> ()> getKnownBrokers; - static const std::string TCP_TRANSPORT; + static QPID_BROKER_EXTERN const std::string TCP_TRANSPORT; void setRecovery(bool set) { recovery = set; } bool getRecovery() const { return recovery; } diff --git a/qpid/cpp/src/qpid/broker/BrokerImportExport.h b/qpid/cpp/src/qpid/broker/BrokerImportExport.h new file mode 100644 index 0000000000..2edc90993e --- /dev/null +++ b/qpid/cpp/src/qpid/broker/BrokerImportExport.h @@ -0,0 +1,33 @@ +#ifndef QPID_BROKER_IMPORT_EXPORT_H +#define QPID_BROKER_IMPORT_EXPORT_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. + */ + +#if defined(WIN32) && !defined(QPID_BROKER_STATIC) +#if defined(BROKER_EXPORT) +#define QPID_BROKER_EXTERN __declspec(dllexport) +#else +#define QPID_BROKER_EXTERN __declspec(dllimport) +#endif +#else +#define QPID_BROKER_EXTERN +#endif + +#endif diff --git a/qpid/cpp/src/qpid/broker/BrokerSingleton.h b/qpid/cpp/src/qpid/broker/BrokerSingleton.h index 22b707506b..3a842ee05a 100644 --- a/qpid/cpp/src/qpid/broker/BrokerSingleton.h +++ b/qpid/cpp/src/qpid/broker/BrokerSingleton.h @@ -20,6 +20,7 @@ */ #include "Broker.h" +#include "BrokerImportExport.h" namespace qpid { namespace broker { @@ -36,7 +37,7 @@ namespace broker { * * THREAD UNSAFE. */ -class BrokerSingleton : public boost::intrusive_ptr<Broker> +class QPID_BROKER_EXTERN BrokerSingleton : public boost::intrusive_ptr<Broker> { public: BrokerSingleton(); diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp index b7446a2220..b06e06d353 100644 --- a/qpid/cpp/src/qpid/broker/Connection.cpp +++ b/qpid/cpp/src/qpid/broker/Connection.cpp @@ -80,7 +80,8 @@ Connection::Connection(ConnectionOutputHandler* out_, Broker& broker_, const std void Connection::requestIOProcessing(boost::function0<void> callback) { - ioCallback = callback; + ScopedLock<Mutex> l(ioCallbackLock); + ioCallbacks.push(callback); out.activateOutput(); } @@ -221,10 +222,13 @@ bool Connection::hasOutput() { return outputTasks.hasOutput(); } bool Connection::doOutput() { try{ - if (ioCallback) - ioCallback(); // Lend the IO thread for management processing - ioCallback = 0; - + { + ScopedLock<Mutex> l(ioCallbackLock); + while (!ioCallbacks.empty()) { + ioCallbacks.front()(); // Lend the IO thread for management processing + ioCallbacks.pop(); + } + } if (mgmtClosing) close(connection::CLOSE_CODE_CONNECTION_FORCED, "Closed by Management Request"); else diff --git a/qpid/cpp/src/qpid/broker/Connection.h b/qpid/cpp/src/qpid/broker/Connection.h index 71e03d76d4..b659fe6468 100644 --- a/qpid/cpp/src/qpid/broker/Connection.h +++ b/qpid/cpp/src/qpid/broker/Connection.h @@ -25,6 +25,7 @@ #include <memory> #include <sstream> #include <vector> +#include <queue> #include <boost/ptr_container/ptr_map.hpp> @@ -47,6 +48,7 @@ #include "qpid/sys/ConnectionOutputHandler.h" #include "qpid/sys/Socket.h" #include "qpid/sys/TimeoutHandler.h" +#include "qpid/sys/Mutex.h" #include <boost/ptr_container/ptr_map.hpp> #include <boost/bind.hpp> @@ -119,12 +121,15 @@ class Connection : public sys::ConnectionInputHandler, const bool isLink; bool mgmtClosing; const std::string mgmtId; - boost::function0<void> ioCallback; + sys::Mutex ioCallbackLock; + std::queue<boost::function0<void> > ioCallbacks; qmf::org::apache::qpid::broker::Connection* mgmtObject; LinkRegistry& links; management::ManagementAgent* agent; Timer& timer; boost::intrusive_ptr<TimerTask> heartbeatTimer; + public: + qmf::org::apache::qpid::broker::Connection* getMgmtObject() { return mgmtObject; } }; }} diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp index f136d61462..63212c7794 100644 --- a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp +++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp @@ -24,8 +24,7 @@ #include "Connection.h" #include "SecureConnection.h" #include "qpid/Url.h" -#include "qpid/framing/ClientInvoker.h" -#include "qpid/framing/ServerInvoker.h" +#include "qpid/framing/AllInvoker.h" #include "qpid/framing/enum.h" #include "qpid/log/Statement.h" #include "qpid/sys/SecurityLayer.h" @@ -46,37 +45,33 @@ const std::string en_US = "en_US"; const std::string QPID_FED_LINK = "qpid.fed_link"; const std::string QPID_FED_TAG = "qpid.federation_tag"; const std::string SESSION_FLOW_CONTROL("qpid.session_flow"); +const std::string CLIENT_PROCESS_NAME("qpid.client_process"); +const std::string CLIENT_PID("qpid.client_pid"); +const std::string CLIENT_PPID("qpid.client_ppid"); const int SESSION_FLOW_CONTROL_VER = 1; } void ConnectionHandler::close(connection::CloseCode code, const string& text) { - handler->client.close(code, text); + handler->proxy.close(code, text); } void ConnectionHandler::heartbeat() { - handler->client.heartbeat(); + handler->proxy.heartbeat(); } void ConnectionHandler::handle(framing::AMQFrame& frame) { AMQMethodBody* method=frame.getBody()->getMethod(); try{ - bool handled = false; - if (handler->serverMode) { - handled = invoke(static_cast<AMQP_ServerOperations::ConnectionHandler&>(*handler.get()), *method); - } else { - handled = invoke(static_cast<AMQP_ClientOperations::ConnectionHandler&>(*handler.get()), *method); - } - if (!handled) { + if (!invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler.get()), *method)) { handler->connection.getChannel(frame.getChannel()).in(frame); } - }catch(ConnectionException& e){ - handler->client.close(e.code, e.what()); + handler->proxy.close(e.code, e.what()); }catch(std::exception& e){ - handler->client.close(541/*internal error*/, e.what()); + handler->proxy.close(541/*internal error*/, e.what()); } } @@ -88,7 +83,7 @@ void ConnectionHandler::setSecureConnection(SecureConnection* secured) ConnectionHandler::ConnectionHandler(Connection& connection, bool isClient) : handler(new Handler(connection, isClient)) {} ConnectionHandler::Handler::Handler(Connection& c, bool isClient) : - client(c.getOutput()), server(c.getOutput()), + proxy(c.getOutput()), connection(c), serverMode(!isClient), acl(0), secured(0) { if (serverMode) { @@ -106,7 +101,7 @@ ConnectionHandler::Handler::Handler(Connection& c, bool isClient) : Array locales(0x95); boost::shared_ptr<FieldValue> l(new Str16Value(en_US)); locales.add(l); - client.start(properties, mechanisms, locales); + proxy.start(properties, mechanisms, locales); } } @@ -136,14 +131,27 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG)); if (connection.isFederationLink()) { if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){ - client.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link"); + proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link"); return; } QPID_LOG(info, "Connection is a federation link"); } - if ( clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER ) { + if (clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER) { connection.setClientThrottling(); } + + if (connection.getMgmtObject() != 0) { + string procName = clientProperties.getAsString(CLIENT_PROCESS_NAME); + uint32_t pid = clientProperties.getAsInt(CLIENT_PID); + uint32_t ppid = clientProperties.getAsInt(CLIENT_PPID); + + if (!procName.empty()) + connection.getMgmtObject()->set_remoteProcessName(procName); + if (pid != 0) + connection.getMgmtObject()->set_remotePid(pid); + if (ppid != 0) + connection.getMgmtObject()->set_remoteParentPid(ppid); + } } void ConnectionHandler::Handler::secureOk(const string& response) @@ -177,7 +185,7 @@ void ConnectionHandler::Handler::open(const string& /*virtualHost*/, framing::Array array(0x95); // str16 array for (std::vector<Url>::iterator i = urls.begin(); i < urls.end(); ++i) array.add(boost::shared_ptr<Str16Value>(new Str16Value(i->str()))); - client.openOk(array); + proxy.openOk(array); //install security layer if one has been negotiated: if (secured) { @@ -196,7 +204,7 @@ void ConnectionHandler::Handler::close(uint16_t replyCode, const string& replyTe if (replyCode == framing::connection::CLOSE_CODE_CONNECTION_FORCED) connection.notifyConnectionForced(replyText); - client.closeOk(); + proxy.closeOk(); connection.getOutput().close(); } @@ -222,12 +230,12 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, FieldTable ft; ft.setInt(QPID_FED_LINK,1); ft.setString(QPID_FED_TAG, connection.getBroker().getFederationTag()); - server.startOk(ft, mechanism, response, en_US); + proxy.startOk(ft, mechanism, response, en_US); } void ConnectionHandler::Handler::secure(const string& /*challenge*/) { - server.secureOk(""); + proxy.secureOk(""); } void ConnectionHandler::Handler::tune(uint16_t channelMax, @@ -237,8 +245,8 @@ void ConnectionHandler::Handler::tune(uint16_t channelMax, { connection.setFrameMax(frameMax); connection.setHeartbeat(heartbeatMax); - server.tuneOk(channelMax, frameMax, heartbeatMax); - server.open("/", Array(), true); + proxy.tuneOk(channelMax, frameMax, heartbeatMax); + proxy.open("/", Array(), true); } void ConnectionHandler::Handler::openOk(const framing::Array& knownHosts) diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.h b/qpid/cpp/src/qpid/broker/ConnectionHandler.h index b24c10e9e8..ac4816dafa 100644 --- a/qpid/cpp/src/qpid/broker/ConnectionHandler.h +++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.h @@ -25,10 +25,8 @@ #include "SaslAuthenticator.h" #include "qpid/framing/amqp_types.h" #include "qpid/framing/AMQFrame.h" -#include "qpid/framing/AMQP_ClientOperations.h" -#include "qpid/framing/AMQP_ClientProxy.h" -#include "qpid/framing/AMQP_ServerOperations.h" -#include "qpid/framing/AMQP_ServerProxy.h" +#include "qpid/framing/AMQP_AllOperations.h" +#include "qpid/framing/AMQP_AllProxy.h" #include "qpid/framing/enum.h" #include "qpid/framing/FrameHandler.h" #include "qpid/framing/ProtocolInitiation.h" @@ -44,11 +42,9 @@ class SecureConnection; class ConnectionHandler : public framing::FrameHandler { - struct Handler : public framing::AMQP_ServerOperations::ConnectionHandler, - public framing::AMQP_ClientOperations::ConnectionHandler + struct Handler : public framing::AMQP_AllOperations::ConnectionHandler { - framing::AMQP_ClientProxy::Connection client; - framing::AMQP_ServerProxy::Connection server; + framing::AMQP_AllProxy::Connection proxy; Connection& connection; bool serverMode; std::auto_ptr<SaslAuthenticator> authenticator; diff --git a/qpid/cpp/src/qpid/broker/ConnectionState.h b/qpid/cpp/src/qpid/broker/ConnectionState.h index 0e9d211b56..b712af11f5 100644 --- a/qpid/cpp/src/qpid/broker/ConnectionState.h +++ b/qpid/cpp/src/qpid/broker/ConnectionState.h @@ -48,8 +48,9 @@ class ConnectionState : public ConnectionToken, public management::Manageable heartbeatmax(120), stagingThreshold(broker.getStagingThreshold()), federationLink(true), - clientSupportsThrottling(false) - {} + clientSupportsThrottling(false), + clusterOrderOut(0) + {} virtual ~ConnectionState () {} @@ -75,7 +76,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable const string& getFederationPeerTag() const { return federationPeerTag; } std::vector<Url>& getKnownHosts() { return knownHosts; } - void setClientThrottling() { clientSupportsThrottling = true; } + void setClientThrottling(bool set=true) { clientSupportsThrottling = set; } bool getClientThrottling() const { return clientSupportsThrottling; } Broker& getBroker() { return broker; } @@ -86,11 +87,21 @@ class ConnectionState : public ConnectionToken, public management::Manageable //contained output tasks sys::AggregateOutput outputTasks; - sys::ConnectionOutputHandlerPtr& getOutput() { return out; } + sys::ConnectionOutputHandler& getOutput() { return out; } framing::ProtocolVersion getVersion() const { return version; } - void setOutputHandler(qpid::sys::ConnectionOutputHandler* o) { out.set(o); } + /** + * If the broker is part of a cluster, this is a handler provided + * by cluster code. It ensures consistent ordering of commands + * that are sent based on criteria that are not predictably + * ordered cluster-wide, e.g. a timer firing. + */ + framing::FrameHandler* getClusterOrderOutput() { return clusterOrderOut; } + void setClusterOrderOutput(framing::FrameHandler& fh) { clusterOrderOut = &fh; } + + virtual void requestIOProcessing (boost::function0<void>) = 0; + protected: framing::ProtocolVersion version; uint32_t framemax; @@ -103,6 +114,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable string federationPeerTag; std::vector<Url> knownHosts; bool clientSupportsThrottling; + framing::FrameHandler* clusterOrderOut; }; }} diff --git a/qpid/cpp/src/qpid/broker/Daemon.h b/qpid/cpp/src/qpid/broker/Daemon.h index 98468debb7..a9cd98bce2 100644 --- a/qpid/cpp/src/qpid/broker/Daemon.h +++ b/qpid/cpp/src/qpid/broker/Daemon.h @@ -19,10 +19,12 @@ * */ -#include <string> +#include "qpid/sys/IntegerTypes.h" #include <boost/scoped_ptr.hpp> #include <boost/function.hpp> #include <boost/noncopyable.hpp> +#include <string> + namespace qpid { namespace broker { diff --git a/qpid/cpp/src/qpid/broker/DeliverableMessage.h b/qpid/cpp/src/qpid/broker/DeliverableMessage.h index f5db473c22..ad944c746b 100644 --- a/qpid/cpp/src/qpid/broker/DeliverableMessage.h +++ b/qpid/cpp/src/qpid/broker/DeliverableMessage.h @@ -21,6 +21,7 @@ #ifndef _DeliverableMessage_ #define _DeliverableMessage_ +#include "BrokerImportExport.h" #include "Deliverable.h" #include "Queue.h" #include "Message.h" @@ -32,10 +33,10 @@ namespace qpid { class DeliverableMessage : public Deliverable{ boost::intrusive_ptr<Message> msg; public: - DeliverableMessage(const boost::intrusive_ptr<Message>& msg); - virtual void deliverTo(const boost::shared_ptr<Queue>& queue); - Message& getMessage(); - uint64_t contentSize(); + QPID_BROKER_EXTERN DeliverableMessage(const boost::intrusive_ptr<Message>& msg); + QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue); + QPID_BROKER_EXTERN Message& getMessage(); + QPID_BROKER_EXTERN uint64_t contentSize(); virtual ~DeliverableMessage(){} }; } diff --git a/qpid/cpp/src/qpid/broker/DeliveryRecord.h b/qpid/cpp/src/qpid/broker/DeliveryRecord.h index d7ccab0726..2b2d4d0515 100644 --- a/qpid/cpp/src/qpid/broker/DeliveryRecord.h +++ b/qpid/cpp/src/qpid/broker/DeliveryRecord.h @@ -26,6 +26,7 @@ #include <vector> #include <ostream> #include "qpid/framing/SequenceSet.h" +#include "BrokerImportExport.h" #include "Queue.h" #include "QueuedMessage.h" #include "DeliveryId.h" @@ -74,17 +75,16 @@ class DeliveryRecord const uint32_t credit; public: - DeliveryRecord( - const QueuedMessage& msg, - const Queue::shared_ptr& queue, - const std::string& tag, - bool acquired, - bool accepted, - bool windowing, - uint32_t credit=0 // Only used if msg is empty. + QPID_BROKER_EXTERN DeliveryRecord(const QueuedMessage& msg, + const Queue::shared_ptr& queue, + const std::string& tag, + bool acquired, + bool accepted, + bool windowing, + uint32_t credit=0 // Only used if msg is empty. ); - bool matches(DeliveryId tag) const; + QPID_BROKER_EXTERN bool matches(DeliveryId tag) const; bool matchOrAfter(DeliveryId tag) const; bool after(DeliveryId tag) const; bool coveredBy(const framing::SequenceSet* const range) const; @@ -119,7 +119,7 @@ class DeliveryRecord const QueuedMessage& getMessage() const { return msg; } framing::SequenceNumber getId() const { return id; } Queue::shared_ptr getQueue() const { return queue; } - friend bool operator<(const DeliveryRecord&, const DeliveryRecord&); + friend QPID_BROKER_EXTERN bool operator<(const DeliveryRecord&, const DeliveryRecord&); friend std::ostream& operator<<(std::ostream&, const DeliveryRecord&); }; diff --git a/qpid/cpp/src/qpid/broker/DirectExchange.h b/qpid/cpp/src/qpid/broker/DirectExchange.h index ba60469df8..27d101c4fe 100644 --- a/qpid/cpp/src/qpid/broker/DirectExchange.h +++ b/qpid/cpp/src/qpid/broker/DirectExchange.h @@ -23,6 +23,7 @@ #include <map> #include <vector> +#include "BrokerImportExport.h" #include "Exchange.h" #include "qpid/framing/FieldTable.h" #include "qpid/sys/CopyOnWriteArray.h" @@ -44,18 +45,27 @@ class DirectExchange : public virtual Exchange { public: static const std::string typeName; - DirectExchange(const std::string& name, management::Manageable* parent = 0); - DirectExchange(const string& _name, bool _durable, - const qpid::framing::FieldTable& _args, management::Manageable* parent = 0); + QPID_BROKER_EXTERN DirectExchange(const std::string& name, + management::Manageable* parent = 0); + QPID_BROKER_EXTERN DirectExchange(const string& _name, + bool _durable, + const qpid::framing::FieldTable& _args, + management::Manageable* parent = 0); virtual std::string getType() const { return typeName; } - virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue, + const std::string& routingKey, + const qpid::framing::FieldTable* args); virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); - virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args); - virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args); + QPID_BROKER_EXTERN virtual void route(Deliverable& msg, + const std::string& routingKey, + const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue, + const string* const routingKey, + const qpid::framing::FieldTable* const args); - virtual ~DirectExchange(); + QPID_BROKER_EXTERN virtual ~DirectExchange(); virtual bool supportsDynamicBinding() { return true; } }; diff --git a/qpid/cpp/src/qpid/broker/DtxBuffer.h b/qpid/cpp/src/qpid/broker/DtxBuffer.h index b302632037..ce37d09b7a 100644 --- a/qpid/cpp/src/qpid/broker/DtxBuffer.h +++ b/qpid/cpp/src/qpid/broker/DtxBuffer.h @@ -21,6 +21,7 @@ #ifndef _DtxBuffer_ #define _DtxBuffer_ +#include "BrokerImportExport.h" #include "TxBuffer.h" #include "qpid/sys/Mutex.h" @@ -37,9 +38,9 @@ namespace qpid { public: typedef boost::shared_ptr<DtxBuffer> shared_ptr; - DtxBuffer(const std::string& xid = ""); - ~DtxBuffer(); - void markEnded(); + QPID_BROKER_EXTERN DtxBuffer(const std::string& xid = ""); + QPID_BROKER_EXTERN ~DtxBuffer(); + QPID_BROKER_EXTERN void markEnded(); bool isEnded(); void setSuspended(bool suspended); bool isSuspended(); diff --git a/qpid/cpp/src/qpid/broker/DtxWorkRecord.h b/qpid/cpp/src/qpid/broker/DtxWorkRecord.h index 6677784c32..21fc759d66 100644 --- a/qpid/cpp/src/qpid/broker/DtxWorkRecord.h +++ b/qpid/cpp/src/qpid/broker/DtxWorkRecord.h @@ -21,6 +21,7 @@ #ifndef _DtxWorkRecord_ #define _DtxWorkRecord_ +#include "BrokerImportExport.h" #include "DtxBuffer.h" #include "DtxTimeout.h" #include "TransactionalStore.h" @@ -61,12 +62,13 @@ class DtxWorkRecord void abort(); bool prepare(TransactionContext* txn); public: - DtxWorkRecord(const std::string& xid, TransactionalStore* const store); - ~DtxWorkRecord(); - bool prepare(); - bool commit(bool onePhase); - void rollback(); - void add(DtxBuffer::shared_ptr ops); + QPID_BROKER_EXTERN DtxWorkRecord(const std::string& xid, + TransactionalStore* const store); + QPID_BROKER_EXTERN ~DtxWorkRecord(); + QPID_BROKER_EXTERN bool prepare(); + QPID_BROKER_EXTERN bool commit(bool onePhase); + QPID_BROKER_EXTERN void rollback(); + QPID_BROKER_EXTERN void add(DtxBuffer::shared_ptr ops); void recover(std::auto_ptr<TPCTransactionContext> txn, DtxBuffer::shared_ptr ops); void timedout(); void setTimeout(boost::intrusive_ptr<DtxTimeout> t) { timeout = t; } diff --git a/qpid/cpp/src/qpid/broker/Exchange.cpp b/qpid/cpp/src/qpid/broker/Exchange.cpp index f8b9e4b183..dd1fe98b2c 100644 --- a/qpid/cpp/src/qpid/broker/Exchange.cpp +++ b/qpid/cpp/src/qpid/broker/Exchange.cpp @@ -102,8 +102,8 @@ static const std::string QPID_MANAGEMENT("qpid.management"); Exchange::Exchange(const string& _name, bool _durable, const qpid::framing::FieldTable& _args, Manageable* parent) - : name(_name), durable(_durable), args(_args), alternateUsers(0), persistenceId(0), - sequence(false), sequenceNo(0), ive(false), mgmtExchange(0) + : name(_name), durable(_durable), alternateUsers(0), persistenceId(0), + args(_args), sequence(false), sequenceNo(0), ive(false), mgmtExchange(0) { if (parent != 0) { @@ -275,3 +275,7 @@ bool Exchange::MatchQueue::operator()(Exchange::Binding::shared_ptr b) { return b->queue == queue; } + +void Exchange::setProperties(const boost::intrusive_ptr<Message>& msg) { + msg->getProperties<DeliveryProperties>()->setExchange(getName()); +} diff --git a/qpid/cpp/src/qpid/broker/Exchange.h b/qpid/cpp/src/qpid/broker/Exchange.h index 488549bbf6..9260222342 100644 --- a/qpid/cpp/src/qpid/broker/Exchange.h +++ b/qpid/cpp/src/qpid/broker/Exchange.h @@ -23,6 +23,7 @@ */ #include <boost/shared_ptr.hpp> +#include "BrokerImportExport.h" #include "Deliverable.h" #include "Queue.h" #include "MessageStore.h" @@ -58,12 +59,12 @@ public: private: const std::string name; const bool durable; - mutable qpid::framing::FieldTable args; boost::shared_ptr<Exchange> alternate; uint32_t alternateUsers; mutable uint64_t persistenceId; protected: + mutable qpid::framing::FieldTable args; bool sequence; mutable qpid::sys::Mutex sequenceLock; int64_t sequenceNo; @@ -123,7 +124,7 @@ public: explicit Exchange(const std::string& name, management::Manageable* parent = 0); Exchange(const std::string& _name, bool _durable, const qpid::framing::FieldTable& _args, management::Manageable* parent = 0); - virtual ~Exchange(); + QPID_BROKER_EXTERN virtual ~Exchange(); const std::string& getName() const { return name; } bool isDurable() { return durable; } @@ -139,15 +140,16 @@ public: virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0; virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0; virtual bool isBound(Queue::shared_ptr queue, const std::string* const routingKey, const qpid::framing::FieldTable* const args) = 0; + virtual void setProperties(const boost::intrusive_ptr<Message>&); virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0; - + //PersistableExchange: void setPersistenceId(uint64_t id) const; uint64_t getPersistenceId() const { return persistenceId; } uint32_t encodedSize() const; - void encode(framing::Buffer& buffer) const; + QPID_BROKER_EXTERN virtual void encode(framing::Buffer& buffer) const; - static Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer); + static QPID_BROKER_EXTERN Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer); // Manageable entry points management::ManagementObject* GetManagementObject(void) const; diff --git a/qpid/cpp/src/qpid/broker/ExchangeRegistry.h b/qpid/cpp/src/qpid/broker/ExchangeRegistry.h index 787b7896f0..9ca432e41c 100644 --- a/qpid/cpp/src/qpid/broker/ExchangeRegistry.h +++ b/qpid/cpp/src/qpid/broker/ExchangeRegistry.h @@ -22,6 +22,7 @@ * */ +#include "BrokerImportExport.h" #include "Exchange.h" #include "MessageStore.h" #include "qpid/framing/FieldTable.h" @@ -45,13 +46,17 @@ class ExchangeRegistry{ bool, const qpid::framing::FieldTable&, qpid::management::Manageable*> FactoryFunction; ExchangeRegistry () : parent(0) {} - std::pair<Exchange::shared_ptr, bool> declare(const std::string& name, const std::string& type) + QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare + (const std::string& name, const std::string& type) throw(UnknownExchangeTypeException); - std::pair<Exchange::shared_ptr, bool> declare(const std::string& name, const std::string& type, - bool durable, const qpid::framing::FieldTable& args = framing::FieldTable()) - throw(UnknownExchangeTypeException); - void destroy(const std::string& name); - Exchange::shared_ptr get(const std::string& name); + QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare + (const std::string& name, + const std::string& type, + bool durable, + const qpid::framing::FieldTable& args = framing::FieldTable()) + throw(UnknownExchangeTypeException); + QPID_BROKER_EXTERN void destroy(const std::string& name); + QPID_BROKER_EXTERN Exchange::shared_ptr get(const std::string& name); Exchange::shared_ptr getDefault(); /** diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h index 1b7316f6f9..cefe9b7552 100644 --- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h +++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h @@ -23,6 +23,7 @@ */ #include "qpid/RefCounted.h" +#include "BrokerImportExport.h" namespace qpid { namespace broker { @@ -35,9 +36,9 @@ class Message; class ExpiryPolicy : public RefCounted { public: - virtual ~ExpiryPolicy(); - virtual void willExpire(Message&); - virtual bool hasExpired(Message&); + QPID_BROKER_EXTERN virtual ~ExpiryPolicy(); + QPID_BROKER_EXTERN virtual void willExpire(Message&); + QPID_BROKER_EXTERN virtual bool hasExpired(Message&); }; }} // namespace qpid::broker diff --git a/qpid/cpp/src/qpid/broker/FanOutExchange.h b/qpid/cpp/src/qpid/broker/FanOutExchange.h index 5884a19732..edfc4395f4 100644 --- a/qpid/cpp/src/qpid/broker/FanOutExchange.h +++ b/qpid/cpp/src/qpid/broker/FanOutExchange.h @@ -23,6 +23,7 @@ #include <map> #include <vector> +#include "BrokerImportExport.h" #include "Exchange.h" #include "qpid/framing/FieldTable.h" #include "qpid/sys/CopyOnWriteArray.h" @@ -38,22 +39,30 @@ class FanOutExchange : public virtual Exchange { public: static const std::string typeName; - FanOutExchange(const std::string& name, management::Manageable* parent = 0); - FanOutExchange(const string& _name, bool _durable, - const qpid::framing::FieldTable& _args, - management::Manageable* parent = 0); + QPID_BROKER_EXTERN FanOutExchange(const std::string& name, + management::Manageable* parent = 0); + QPID_BROKER_EXTERN FanOutExchange(const string& _name, + bool _durable, + const qpid::framing::FieldTable& _args, + management::Manageable* parent = 0); virtual std::string getType() const { return typeName; } - virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue, + const std::string& routingKey, + const qpid::framing::FieldTable* args); virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args); - virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual void route(Deliverable& msg, + const std::string& routingKey, + const qpid::framing::FieldTable* args); - virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args); + QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue, + const string* const routingKey, + const qpid::framing::FieldTable* const args); - virtual ~FanOutExchange(); + QPID_BROKER_EXTERN virtual ~FanOutExchange(); virtual bool supportsDynamicBinding() { return true; } }; diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp index 104b34da8b..09fb2d9bef 100644 --- a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp +++ b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp @@ -105,33 +105,42 @@ bool HeadersExchange::unbind(Queue::shared_ptr queue, const string& bindingKey, void HeadersExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* args){ - if (!args) return;//can't match if there were no headers passed in + if (!args) { + //can't match if there were no headers passed in + if (mgmtExchange != 0) { + mgmtExchange->inc_msgReceives(); + mgmtExchange->inc_byteReceives(msg.contentSize()); + mgmtExchange->inc_msgDrops(); + mgmtExchange->inc_byteDrops(msg.contentSize()); + } + return; + } + PreRoute pr(msg, this); uint32_t count(0); Bindings::ConstPtr p = bindings.snapshot(); if (p.get()){ - for (std::vector<Binding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); ++i, count++) { - if (match((*i)->args, *args)) msg.deliverTo((*i)->queue); - if ((*i)->mgmtBinding != 0) - (*i)->mgmtBinding->inc_msgMatched (); + for (std::vector<Binding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); ++i) { + if (match((*i)->args, *args)) { + msg.deliverTo((*i)->queue); + count++; + if ((*i)->mgmtBinding != 0) + (*i)->mgmtBinding->inc_msgMatched(); + } } } - if (mgmtExchange != 0) - { - mgmtExchange->inc_msgReceives (); - mgmtExchange->inc_byteReceives (msg.contentSize ()); - if (count == 0) - { - mgmtExchange->inc_msgDrops (); - mgmtExchange->inc_byteDrops (msg.contentSize ()); - } - else - { - mgmtExchange->inc_msgRoutes (count); - mgmtExchange->inc_byteRoutes (count * msg.contentSize ()); + if (mgmtExchange != 0) { + mgmtExchange->inc_msgReceives(); + mgmtExchange->inc_byteReceives(msg.contentSize()); + if (count == 0) { + mgmtExchange->inc_msgDrops(); + mgmtExchange->inc_byteDrops(msg.contentSize()); + } else { + mgmtExchange->inc_msgRoutes(count); + mgmtExchange->inc_byteRoutes(count * msg.contentSize()); } } } diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.h b/qpid/cpp/src/qpid/broker/HeadersExchange.h index e10fab2250..2b01f9ecae 100644 --- a/qpid/cpp/src/qpid/broker/HeadersExchange.h +++ b/qpid/cpp/src/qpid/broker/HeadersExchange.h @@ -22,6 +22,7 @@ #define _HeadersExchange_ #include <vector> +#include "BrokerImportExport.h" #include "Exchange.h" #include "qpid/framing/FieldTable.h" #include "qpid/sys/CopyOnWriteArray.h" @@ -59,24 +60,32 @@ class HeadersExchange : public virtual Exchange { public: static const std::string typeName; - HeadersExchange(const string& name, management::Manageable* parent = 0); - HeadersExchange(const string& _name, bool _durable, - const qpid::framing::FieldTable& _args, - management::Manageable* parent = 0); + QPID_BROKER_EXTERN HeadersExchange(const string& name, + management::Manageable* parent = 0); + QPID_BROKER_EXTERN HeadersExchange(const string& _name, + bool _durable, + const qpid::framing::FieldTable& _args, + management::Manageable* parent = 0); virtual std::string getType() const { return typeName; } - virtual bool bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue, + const string& routingKey, + const qpid::framing::FieldTable* args); virtual bool unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); - virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual void route(Deliverable& msg, + const string& routingKey, + const qpid::framing::FieldTable* args); - virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args); + QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue, + const string* const routingKey, + const qpid::framing::FieldTable* const args); - virtual ~HeadersExchange(); + QPID_BROKER_EXTERN virtual ~HeadersExchange(); - static bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs); + static QPID_BROKER_EXTERN bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs); static bool equal(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs); }; diff --git a/qpid/cpp/src/qpid/broker/IncompleteMessageList.h b/qpid/cpp/src/qpid/broker/IncompleteMessageList.h index f89c0023b0..449194d571 100644 --- a/qpid/cpp/src/qpid/broker/IncompleteMessageList.h +++ b/qpid/cpp/src/qpid/broker/IncompleteMessageList.h @@ -21,6 +21,7 @@ #ifndef _IncompleteMessageList_ #define _IncompleteMessageList_ +#include "BrokerImportExport.h" #include "qpid/sys/Monitor.h" #include "qpid/broker/Message.h" #include <boost/intrusive_ptr.hpp> @@ -43,11 +44,11 @@ class IncompleteMessageList public: typedef Message::MessageCallback CompletionListener; - IncompleteMessageList(); - ~IncompleteMessageList(); + QPID_BROKER_EXTERN IncompleteMessageList(); + QPID_BROKER_EXTERN ~IncompleteMessageList(); - void add(boost::intrusive_ptr<Message> msg); - void process(const CompletionListener& l, bool sync); + QPID_BROKER_EXTERN void add(boost::intrusive_ptr<Message> msg); + QPID_BROKER_EXTERN void process(const CompletionListener& l, bool sync); void each(const CompletionListener& l); }; diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp index e36635831b..dd1a1fa0b4 100644 --- a/qpid/cpp/src/qpid/broker/Link.cpp +++ b/qpid/cpp/src/qpid/broker/Link.cpp @@ -158,7 +158,7 @@ void Link::closed (int, std::string text) } for (Bridges::iterator i = active.begin(); i != active.end(); i++) { - (*i)->cancel(); + (*i)->closed(); created.push_back(*i); } active.clear(); @@ -217,21 +217,27 @@ void Link::add(Bridge::shared_ptr bridge) void Link::cancel(Bridge::shared_ptr bridge) { - Mutex::ScopedLock mutex(lock); - - for (Bridges::iterator i = created.begin(); i != created.end(); i++) { - if ((*i).get() == bridge.get()) { - created.erase(i); - break; + { + Mutex::ScopedLock mutex(lock); + + for (Bridges::iterator i = created.begin(); i != created.end(); i++) { + if ((*i).get() == bridge.get()) { + created.erase(i); + break; + } } - } - for (Bridges::iterator i = active.begin(); i != active.end(); i++) { - if ((*i).get() == bridge.get()) { - bridge->cancel(); - active.erase(i); - break; + for (Bridges::iterator i = active.begin(); i != active.end(); i++) { + if ((*i).get() == bridge.get()) { + cancellations.push_back(bridge); + bridge->closed(); + active.erase(i); + break; + } } } + if (!cancellations.empty()) { + connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this)); + } } void Link::ioThreadProcessing() @@ -242,7 +248,7 @@ void Link::ioThreadProcessing() return; QPID_LOG(debug, "Link::ioThreadProcessing()"); - //process any pending creates + //process any pending creates and/or cancellations if (!created.empty()) { for (Bridges::iterator i = created.begin(); i != created.end(); ++i) { active.push_back(*i); @@ -250,6 +256,13 @@ void Link::ioThreadProcessing() } created.clear(); } + if (!cancellations.empty()) { + for (Bridges::iterator i = cancellations.begin(); i != cancellations.end(); ++i) { + active.push_back(*i); + (*i)->cancel(*connection); + } + cancellations.clear(); + } } void Link::setConnection(Connection* c) @@ -284,7 +297,7 @@ void Link::maintenanceVisit () } } } - else if (state == STATE_OPERATIONAL && !created.empty() && connection != 0) + else if (state == STATE_OPERATIONAL && (!created.empty() || !cancellations.empty()) && connection != 0) connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this)); } diff --git a/qpid/cpp/src/qpid/broker/Link.h b/qpid/cpp/src/qpid/broker/Link.h index 8e741c6eb7..39014b0ec0 100644 --- a/qpid/cpp/src/qpid/broker/Link.h +++ b/qpid/cpp/src/qpid/broker/Link.h @@ -67,6 +67,7 @@ namespace qpid { typedef std::vector<Bridge::shared_ptr> Bridges; Bridges created; // Bridges pending creation Bridges active; // Bridges active + Bridges cancellations; // Bridges pending cancellation uint channelCounter; Connection* connection; management::ManagementAgent* agent; diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp index 97b1c32d64..7d4ab7548e 100644 --- a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp +++ b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp @@ -19,19 +19,24 @@ * */ #include "LinkRegistry.h" +#include "Connection.h" #include "qpid/log/Statement.h" #include <iostream> +#include <boost/format.hpp> using namespace qpid::broker; using namespace qpid::sys; using std::pair; using std::stringstream; using boost::intrusive_ptr; +using boost::format; +using boost::str; namespace _qmf = qmf::org::apache::qpid::broker; #define LINK_MAINT_INTERVAL 2 -LinkRegistry::LinkRegistry (Broker* _broker) : broker(_broker), parent(0), store(0), passive(false), passiveChanged(false) +LinkRegistry::LinkRegistry (Broker* _broker) : broker(_broker), parent(0), store(0), passive(false), passiveChanged(false), + realm(broker ? broker->getOptions().realm : "") { timer.add (intrusive_ptr<TimerTask> (new Periodic(*this))); } @@ -233,66 +238,70 @@ MessageStore* LinkRegistry::getStore() const { return store; } -void LinkRegistry::notifyConnection(const std::string& key, Connection* c) +Link::shared_ptr LinkRegistry::findLink(const std::string& key) { Mutex::ScopedLock locker(lock); LinkMap::iterator l = links.find(key); - if (l != links.end()) - { - l->second->established(); - l->second->setConnection(c); + if (l != links.end()) return l->second; + else return Link::shared_ptr(); +} + +void LinkRegistry::notifyConnection(const std::string& key, Connection* c) +{ + Link::shared_ptr link = findLink(key); + if (link) { + link->established(); + link->setConnection(c); + c->setUserId(str(format("%1%@%2%") % link->getUsername() % realm)); } } void LinkRegistry::notifyClosed(const std::string& key) { - Mutex::ScopedLock locker(lock); - LinkMap::iterator l = links.find(key); - if (l != links.end()) - l->second->closed(0, "Closed by peer"); + Link::shared_ptr link = findLink(key); + if (link) { + link->closed(0, "Closed by peer"); + } } void LinkRegistry::notifyConnectionForced(const std::string& key, const std::string& text) { - Mutex::ScopedLock locker(lock); - LinkMap::iterator l = links.find(key); - if (l != links.end()) - l->second->notifyConnectionForced(text); + Link::shared_ptr link = findLink(key); + if (link) { + link->notifyConnectionForced(text); + } } std::string LinkRegistry::getAuthMechanism(const std::string& key) { - Mutex::ScopedLock locker(lock); - LinkMap::iterator l = links.find(key); - if (l != links.end()) - return l->second->getAuthMechanism(); + Link::shared_ptr link = findLink(key); + if (link) + return link->getAuthMechanism(); return string("ANONYMOUS"); } std::string LinkRegistry::getAuthCredentials(const std::string& key) { - Mutex::ScopedLock locker(lock); - LinkMap::iterator l = links.find(key); - if (l == links.end()) + Link::shared_ptr link = findLink(key); + if (!link) return string(); string result; result += '\0'; - result += l->second->getUsername(); + result += link->getUsername(); result += '\0'; - result += l->second->getPassword(); + result += link->getPassword(); return result; } std::string LinkRegistry::getAuthIdentity(const std::string& key) { - Mutex::ScopedLock locker(lock); - LinkMap::iterator l = links.find(key); - if (l == links.end()) + Link::shared_ptr link = findLink(key); + if (!link) return string(); - return l->second->getUsername(); + return link->getUsername(); } diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.h b/qpid/cpp/src/qpid/broker/LinkRegistry.h index 884228bd63..2397dbc6f3 100644 --- a/qpid/cpp/src/qpid/broker/LinkRegistry.h +++ b/qpid/cpp/src/qpid/broker/LinkRegistry.h @@ -66,9 +66,11 @@ namespace broker { MessageStore* store; bool passive; bool passiveChanged; + std::string realm; void periodicMaintenance (); bool updateAddress(const std::string& oldKey, const TcpAddress& newAddress); + Link::shared_ptr findLink(const std::string& key); static std::string createKey(const TcpAddress& address); public: diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp index 133e2b5ad1..40b5515829 100644 --- a/qpid/cpp/src/qpid/broker/Message.cpp +++ b/qpid/cpp/src/qpid/broker/Message.cpp @@ -160,6 +160,7 @@ void Message::decodeContent(framing::Buffer& buffer) //body on a frame then add that frame to the frameset AMQFrame frame((AMQContentBody())); frame.castBody<AMQContentBody>()->decode(buffer, buffer.available()); + frame.setFirstSegment(false); frames.append(frame); } else { //adjust header flags @@ -382,4 +383,9 @@ void Message::resetEnqueueCompleteCallback() { enqueueCallback = 0; } void Message::setDequeueCompleteCallback(MessageCallback& cb) { dequeueCallback = &cb; } void Message::resetDequeueCompleteCallback() { dequeueCallback = 0; } +framing::FieldTable& Message::getOrInsertHeaders() +{ + return getProperties<MessageProperties>()->getApplicationHeaders(); +} + }} // namespace qpid::broker diff --git a/qpid/cpp/src/qpid/broker/Message.h b/qpid/cpp/src/qpid/broker/Message.h index 96fcf61dfc..458c6c7d1a 100644 --- a/qpid/cpp/src/qpid/broker/Message.h +++ b/qpid/cpp/src/qpid/broker/Message.h @@ -22,6 +22,7 @@ * */ +#include "BrokerImportExport.h" #include "PersistableMessage.h" #include "MessageAdapter.h" #include "qpid/framing/amqp_types.h" @@ -51,8 +52,8 @@ class Message : public PersistableMessage { public: typedef boost::function<void (const boost::intrusive_ptr<Message>&)> MessageCallback; - Message(const framing::SequenceNumber& id = framing::SequenceNumber()); - ~Message(); + QPID_BROKER_EXTERN Message(const framing::SequenceNumber& id = framing::SequenceNumber()); + QPID_BROKER_EXTERN ~Message(); uint64_t getPersistenceId() const { return persistenceId; } void setPersistenceId(uint64_t _persistenceId) const { persistenceId = _persistenceId; } @@ -65,17 +66,18 @@ public: const framing::SequenceNumber& getCommandId() { return frames.getId(); } - uint64_t contentSize() const; + QPID_BROKER_EXTERN uint64_t contentSize() const; - std::string getRoutingKey() const; + QPID_BROKER_EXTERN std::string getRoutingKey() const; const boost::shared_ptr<Exchange> getExchange(ExchangeRegistry&) const; - std::string getExchangeName() const; + QPID_BROKER_EXTERN std::string getExchangeName() const; bool isImmediate() const; - const framing::FieldTable* getApplicationHeaders() const; - bool isPersistent(); + QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const; + framing::FieldTable& getOrInsertHeaders(); + QPID_BROKER_EXTERN bool isPersistent(); bool requiresAccept(); - void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e); + QPID_BROKER_EXTERN void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e); void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e); bool hasExpired(); sys::AbsTime getExpiration() const { return expiration; } @@ -124,8 +126,8 @@ public: uint32_t encodedHeaderSize() const; uint32_t encodedContentSize() const; - void decodeHeader(framing::Buffer& buffer); - void decodeContent(framing::Buffer& buffer); + QPID_BROKER_EXTERN void decodeHeader(framing::Buffer& buffer); + QPID_BROKER_EXTERN void decodeContent(framing::Buffer& buffer); /** * Releases the in-memory content data held by this @@ -139,7 +141,7 @@ public: void sendContent(const Queue& queue, framing::FrameHandler& out, uint16_t maxFrameSize) const; void sendHeader(framing::FrameHandler& out, uint16_t maxFrameSize) const; - bool isContentLoaded() const; + QPID_BROKER_EXTERN bool isContentLoaded() const; bool isExcluded(const std::vector<std::string>& excludes) const; void addTraceId(const std::string& id); diff --git a/qpid/cpp/src/qpid/broker/MessageBuilder.h b/qpid/cpp/src/qpid/broker/MessageBuilder.h index 395de024ab..1f5a2a8b84 100644 --- a/qpid/cpp/src/qpid/broker/MessageBuilder.h +++ b/qpid/cpp/src/qpid/broker/MessageBuilder.h @@ -21,6 +21,7 @@ #ifndef _MessageBuilder_ #define _MessageBuilder_ +#include "BrokerImportExport.h" #include "qpid/framing/FrameHandler.h" #include "qpid/framing/SequenceNumber.h" #include "qpid/RefCounted.h" @@ -34,10 +35,11 @@ namespace qpid { class MessageBuilder : public framing::FrameHandler{ public: - MessageBuilder(MessageStore* const store, uint64_t stagingThreshold); - void handle(framing::AMQFrame& frame); + QPID_BROKER_EXTERN MessageBuilder(MessageStore* const store, + uint64_t stagingThreshold); + QPID_BROKER_EXTERN void handle(framing::AMQFrame& frame); boost::intrusive_ptr<Message> getMessage() { return message; } - void start(const framing::SequenceNumber& id); + QPID_BROKER_EXTERN void start(const framing::SequenceNumber& id); void end(); private: enum State {DORMANT, METHOD, HEADER, CONTENT}; diff --git a/qpid/cpp/src/qpid/broker/NullMessageStore.h b/qpid/cpp/src/qpid/broker/NullMessageStore.h index d99c751d26..a44f8d2804 100644 --- a/qpid/cpp/src/qpid/broker/NullMessageStore.h +++ b/qpid/cpp/src/qpid/broker/NullMessageStore.h @@ -22,6 +22,7 @@ #define _NullMessageStore_ #include <set> +#include "BrokerImportExport.h" #include "MessageStore.h" #include "Queue.h" @@ -38,46 +39,54 @@ class NullMessageStore : public MessageStore std::set<std::string> prepared; uint64_t nextPersistenceId; public: - NullMessageStore(); + QPID_BROKER_EXTERN NullMessageStore(); - virtual bool init(const Options* options); - virtual std::auto_ptr<TransactionContext> begin(); - virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid); - virtual void prepare(TPCTransactionContext& txn); - virtual void commit(TransactionContext& txn); - virtual void abort(TransactionContext& txn); - virtual void collectPreparedXids(std::set<std::string>& xids); + QPID_BROKER_EXTERN virtual bool init(const Options* options); + QPID_BROKER_EXTERN virtual std::auto_ptr<TransactionContext> begin(); + QPID_BROKER_EXTERN virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid); + QPID_BROKER_EXTERN virtual void prepare(TPCTransactionContext& txn); + QPID_BROKER_EXTERN virtual void commit(TransactionContext& txn); + QPID_BROKER_EXTERN virtual void abort(TransactionContext& txn); + QPID_BROKER_EXTERN virtual void collectPreparedXids(std::set<std::string>& xids); - virtual void create(PersistableQueue& queue, const framing::FieldTable& args); - virtual void destroy(PersistableQueue& queue); - virtual void create(const PersistableExchange& exchange, const framing::FieldTable& args); - virtual void destroy(const PersistableExchange& exchange); + QPID_BROKER_EXTERN virtual void create(PersistableQueue& queue, + const framing::FieldTable& args); + QPID_BROKER_EXTERN virtual void destroy(PersistableQueue& queue); + QPID_BROKER_EXTERN virtual void create(const PersistableExchange& exchange, + const framing::FieldTable& args); + QPID_BROKER_EXTERN virtual void destroy(const PersistableExchange& exchange); - virtual void bind(const PersistableExchange& exchange, const PersistableQueue& queue, - const std::string& key, const framing::FieldTable& args); - virtual void unbind(const PersistableExchange& exchange, const PersistableQueue& queue, - const std::string& key, const framing::FieldTable& args); - virtual void create(const PersistableConfig& config); - virtual void destroy(const PersistableConfig& config); - virtual void recover(RecoveryManager& queues); - virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg); - virtual void destroy(PersistableMessage& msg); - virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg, - const std::string& data); - virtual void loadContent(const qpid::broker::PersistableQueue& queue, - const boost::intrusive_ptr<const PersistableMessage>& msg, std::string& data, - uint64_t offset, uint32_t length); - virtual void enqueue(TransactionContext* ctxt, - const boost::intrusive_ptr<PersistableMessage>& msg, - const PersistableQueue& queue); - virtual void dequeue(TransactionContext* ctxt, - const boost::intrusive_ptr<PersistableMessage>& msg, - const PersistableQueue& queue); - virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue); - virtual void flush(const qpid::broker::PersistableQueue& queue); + QPID_BROKER_EXTERN virtual void bind(const PersistableExchange& exchange, + const PersistableQueue& queue, + const std::string& key, + const framing::FieldTable& args); + QPID_BROKER_EXTERN virtual void unbind(const PersistableExchange& exchange, + const PersistableQueue& queue, + const std::string& key, + const framing::FieldTable& args); + QPID_BROKER_EXTERN virtual void create(const PersistableConfig& config); + QPID_BROKER_EXTERN virtual void destroy(const PersistableConfig& config); + QPID_BROKER_EXTERN virtual void recover(RecoveryManager& queues); + QPID_BROKER_EXTERN virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg); + QPID_BROKER_EXTERN virtual void destroy(PersistableMessage& msg); + QPID_BROKER_EXTERN virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg, + const std::string& data); + QPID_BROKER_EXTERN virtual void loadContent(const qpid::broker::PersistableQueue& queue, + const boost::intrusive_ptr<const PersistableMessage>& msg, + std::string& data, + uint64_t offset, + uint32_t length); + QPID_BROKER_EXTERN virtual void enqueue(TransactionContext* ctxt, + const boost::intrusive_ptr<PersistableMessage>& msg, + const PersistableQueue& queue); + QPID_BROKER_EXTERN virtual void dequeue(TransactionContext* ctxt, + const boost::intrusive_ptr<PersistableMessage>& msg, + const PersistableQueue& queue); + QPID_BROKER_EXTERN virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue); + QPID_BROKER_EXTERN virtual void flush(const qpid::broker::PersistableQueue& queue); ~NullMessageStore(){} - virtual bool isNull() const; + QPID_BROKER_EXTERN virtual bool isNull() const; static bool isNullStore(const MessageStore*); }; diff --git a/qpid/cpp/src/qpid/broker/PersistableMessage.h b/qpid/cpp/src/qpid/broker/PersistableMessage.h index 4f2e3abafa..92f89ba578 100644 --- a/qpid/cpp/src/qpid/broker/PersistableMessage.h +++ b/qpid/cpp/src/qpid/broker/PersistableMessage.h @@ -26,6 +26,7 @@ #include <list> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> +#include "BrokerImportExport.h" #include "Persistable.h" #include "qpid/framing/amqp_types.h" #include "qpid/sys/Mutex.h" @@ -93,21 +94,23 @@ class PersistableMessage : public Persistable bool isContentReleased() const; - bool isEnqueueComplete(); + QPID_BROKER_EXTERN bool isEnqueueComplete(); - void enqueueComplete(); + QPID_BROKER_EXTERN void enqueueComplete(); - void enqueueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store); + QPID_BROKER_EXTERN void enqueueAsync(PersistableQueue::shared_ptr queue, + MessageStore* _store); - void enqueueAsync(); + QPID_BROKER_EXTERN void enqueueAsync(); - bool isDequeueComplete(); + QPID_BROKER_EXTERN bool isDequeueComplete(); - void dequeueComplete(); + QPID_BROKER_EXTERN void dequeueComplete(); - void dequeueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store); + QPID_BROKER_EXTERN void dequeueAsync(PersistableQueue::shared_ptr queue, + MessageStore* _store); - void dequeueAsync(); + QPID_BROKER_EXTERN void dequeueAsync(); }; }} diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp index 3ae53c8ea9..aa0cd8ca31 100644 --- a/qpid/cpp/src/qpid/broker/Queue.cpp +++ b/qpid/cpp/src/qpid/broker/Queue.cpp @@ -32,6 +32,7 @@ #include "qpid/log/Statement.h" #include "qpid/management/ManagementBroker.h" #include "qpid/framing/reply_exceptions.h" +#include "qpid/framing/FieldTable.h" #include "qpid/sys/Monitor.h" #include "qpid/sys/Time.h" #include "qmf/org/apache/qpid/broker/ArgsQueuePurge.h" @@ -68,6 +69,9 @@ const std::string qpidLastValueQueueNoBrowse("qpid.last_value_queue_no_browse"); const std::string qpidPersistLastNode("qpid.persist_last_node"); const std::string qpidVQMatchProperty("qpid.LVQ_key"); const std::string qpidQueueEventGeneration("qpid.queue_event_generation"); +//following feature is not ready for general use as it doesn't handle +//the case where a message is enqueued on more than one queue well enough: +const std::string qpidInsertSequenceNumbers("qpid.insert_sequence_numbers"); const int ENQUEUE_ONLY=1; const int ENQUEUE_AND_DEQUEUE=2; @@ -93,7 +97,8 @@ Queue::Queue(const string& _name, bool _autodelete, policyExceeded(false), mgmtObject(0), eventMode(0), - eventMgr(0) + eventMgr(0), + insertSeqNo(0) { if (parent != 0) { @@ -176,7 +181,7 @@ void Queue::deliver(boost::intrusive_ptr<Message>& msg){ void Queue::recover(boost::intrusive_ptr<Message>& msg){ - push(msg); + push(msg, true); msg->enqueueComplete(); // mark the message as enqueued mgntEnqStats(msg); @@ -545,12 +550,13 @@ void Queue::popMsg(QueuedMessage& qmsg) ++dequeueTracker; } -void Queue::push(boost::intrusive_ptr<Message>& msg){ +void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){ QueueListeners::NotificationSet copy; { Mutex::ScopedLock locker(messageLock); QueuedMessage qm(this, msg, ++sequence); if (policy.get()) policy->tryEnqueue(qm); + if (insertSeqNo) msg->getOrInsertHeaders().setInt64(seqNoKey, sequence); LVQ::iterator i; const framing::FieldTable* ft = msg->getApplicationHeaders(); @@ -566,14 +572,21 @@ void Queue::push(boost::intrusive_ptr<Message>& msg){ boost::intrusive_ptr<Message> old = i->second->getReplacementMessage(this); if (!old) old = i->second; i->second->setReplacementMessage(msg,this); - dequeued(QueuedMessage(qm.queue, old, qm.position)); + if (isRecovery) { + //can't issue new requests for the store until + //recovery is complete + pendingDequeues.push_back(QueuedMessage(qm.queue, old, qm.position)); + } else { + dequeue(0, QueuedMessage(qm.queue, old, qm.position)); + } } }else { messages.push_back(qm); listeners.populate(copy); } - if (eventMode && eventMgr) { - eventMgr->enqueued(qm); + if (eventMode) { + if (eventMgr) eventMgr->enqueued(qm); + else QPID_LOG(warning, "Enqueue manager not set, events not generated for " << getName()); } } copy.notify(); @@ -664,7 +677,7 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg) msg->addTraceId(traceId); } - if (msg->isPersistent() && store && !lastValueQueue) { + if (msg->isPersistent() && store) { msg->enqueueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg); store->enqueue(ctxt, pmsg, *this); @@ -676,14 +689,14 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg) // return true if store exists, bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg) { - if (policy.get() && !policy->isEnqueued(msg)) return false; { Mutex::ScopedLock locker(messageLock); + if (policy.get() && !policy->isEnqueued(msg)) return false; if (!ctxt) { dequeued(msg); } } - if (msg.payload->isPersistent() && store && !lastValueQueue) { + if (msg.payload->isPersistent() && store) { msg.payload->dequeueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg.payload); store->dequeue(ctxt, pmsg, *this); @@ -765,6 +778,9 @@ void Queue::configure(const FieldTable& _settings, bool recovering) eventMode = _settings.getAsInt(qpidQueueEventGeneration); + FieldTable::ValuePtr p =_settings.get(qpidInsertSequenceNumbers); + if (p && p->convertsTo<std::string>()) insertSequenceNumbers(p->get<std::string>()); + if (mgmtObject != 0) mgmtObject->set_arguments (_settings); @@ -976,3 +992,17 @@ void Queue::setQueueEventManager(QueueEvents& mgr) { eventMgr = &mgr; } + +void Queue::recoveryComplete() +{ + //process any pending dequeues + for_each(pendingDequeues.begin(), pendingDequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1)); + pendingDequeues.clear(); +} + +void Queue::insertSequenceNumbers(const std::string& key) +{ + seqNoKey = key; + insertSeqNo = !seqNoKey.empty(); + QPID_LOG(debug, "Inserting sequence numbers as " << key); +} diff --git a/qpid/cpp/src/qpid/broker/Queue.h b/qpid/cpp/src/qpid/broker/Queue.h index 14849b3c8e..d1f71581d6 100644 --- a/qpid/cpp/src/qpid/broker/Queue.h +++ b/qpid/cpp/src/qpid/broker/Queue.h @@ -21,6 +21,8 @@ * under the License. * */ + +#include "BrokerImportExport.h" #include "OwnershipToken.h" #include "Consumer.h" #include "Message.h" @@ -85,6 +87,7 @@ namespace qpid { std::vector<std::string> traceExclude; QueueListeners listeners; Messages messages; + Messages pendingDequeues;//used to avoid dequeuing during recovery LVQ lvq; mutable qpid::sys::Mutex consumerLock; mutable qpid::sys::Mutex messageLock; @@ -100,8 +103,10 @@ namespace qpid { RateTracker dequeueTracker; int eventMode; QueueEvents* eventMgr; + bool insertSeqNo; + std::string seqNoKey; - void push(boost::intrusive_ptr<Message>& msg); + void push(boost::intrusive_ptr<Message>& msg, bool isRecovery=false); void setPolicy(std::auto_ptr<QueuePolicy> policy); bool seek(QueuedMessage& msg, Consumer::shared_ptr position); bool getNextMessage(QueuedMessage& msg, Consumer::shared_ptr c); @@ -149,13 +154,14 @@ namespace qpid { typedef std::vector<shared_ptr> vector; - Queue(const string& name, bool autodelete = false, - MessageStore* const store = 0, - const OwnershipToken* const owner = 0, - management::Manageable* parent = 0); - ~Queue(); + QPID_BROKER_EXTERN Queue(const string& name, + bool autodelete = false, + MessageStore* const store = 0, + const OwnershipToken* const owner = 0, + management::Manageable* parent = 0); + QPID_BROKER_EXTERN ~Queue(); - bool dispatch(Consumer::shared_ptr); + QPID_BROKER_EXTERN bool dispatch(Consumer::shared_ptr); /** * Check whether there would be a message available for * dispatch to this consumer. If not, the consumer will be @@ -167,24 +173,28 @@ namespace qpid { void create(const qpid::framing::FieldTable& settings); // "recovering" means we are doing a MessageStore recovery. - void configure(const qpid::framing::FieldTable& settings, bool recovering = false); + QPID_BROKER_EXTERN void configure(const qpid::framing::FieldTable& settings, + bool recovering = false); void destroy(); - void bound(const string& exchange, const string& key, const qpid::framing::FieldTable& args); - void unbind(ExchangeRegistry& exchanges, Queue::shared_ptr shared_ref); + QPID_BROKER_EXTERN void bound(const string& exchange, + const string& key, + const qpid::framing::FieldTable& args); + QPID_BROKER_EXTERN void unbind(ExchangeRegistry& exchanges, + Queue::shared_ptr shared_ref); - bool acquire(const QueuedMessage& msg); + QPID_BROKER_EXTERN bool acquire(const QueuedMessage& msg); bool acquireMessageAt(const qpid::framing::SequenceNumber& position, QueuedMessage& message); /** * Delivers a message to the queue. Will record it as * enqueued if persistent then process it. */ - void deliver(boost::intrusive_ptr<Message>& msg); + QPID_BROKER_EXTERN void deliver(boost::intrusive_ptr<Message>& msg); /** * Dispatches the messages immediately to a consumer if * one is available or stores it for later if not. */ - void process(boost::intrusive_ptr<Message>& msg); + QPID_BROKER_EXTERN void process(boost::intrusive_ptr<Message>& msg); /** * Returns a message to the in-memory queue (due to lack * of acknowledegement from a receiver). If a consumer is @@ -197,17 +207,18 @@ namespace qpid { */ void recover(boost::intrusive_ptr<Message>& msg); - void consume(Consumer::shared_ptr c, bool exclusive = false); - void cancel(Consumer::shared_ptr c); + QPID_BROKER_EXTERN void consume(Consumer::shared_ptr c, + bool exclusive = false); + QPID_BROKER_EXTERN void cancel(Consumer::shared_ptr c); uint32_t purge(const uint32_t purge_request = 0); //defaults to all messages - void purgeExpired(); + QPID_BROKER_EXTERN void purgeExpired(); //move qty # of messages to destination Queue destq uint32_t move(const Queue::shared_ptr destq, uint32_t qty); - uint32_t getMessageCount() const; - uint32_t getConsumerCount() const; + QPID_BROKER_EXTERN uint32_t getMessageCount() const; + QPID_BROKER_EXTERN uint32_t getConsumerCount() const; inline const string& getName() const { return name; } bool isExclusiveOwner(const OwnershipToken* const o) const; void releaseExclusiveOwnership(); @@ -223,8 +234,8 @@ namespace qpid { /** * used to take messages from in memory and flush down to disk. */ - void setLastNodeFailure(); - void clearLastNodeFailure(); + QPID_BROKER_EXTERN void setLastNodeFailure(); + QPID_BROKER_EXTERN void clearLastNodeFailure(); bool enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg); /** @@ -240,7 +251,7 @@ namespace qpid { /** * Gets the next available message */ - QueuedMessage get(); + QPID_BROKER_EXTERN QueuedMessage get(); /** Get the message at position pos */ QueuedMessage find(framing::SequenceNumber pos) const; @@ -290,6 +301,11 @@ namespace qpid { void setPosition(framing::SequenceNumber pos); int getEventMode(); void setQueueEventManager(QueueEvents&); + void insertSequenceNumbers(const std::string& key); + /** + * Notify queue that recovery has completed. + */ + void recoveryComplete(); }; } } diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.h b/qpid/cpp/src/qpid/broker/QueueCleaner.h index 7903266f5f..007826f33e 100644 --- a/qpid/cpp/src/qpid/broker/QueueCleaner.h +++ b/qpid/cpp/src/qpid/broker/QueueCleaner.h @@ -22,6 +22,7 @@ * */ +#include "BrokerImportExport.h" #include "Timer.h" namespace qpid { @@ -34,8 +35,8 @@ class QueueRegistry; class QueueCleaner { public: - QueueCleaner(QueueRegistry& queues, Timer& timer); - void start(qpid::sys::Duration period); + QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, Timer& timer); + QPID_BROKER_EXTERN void start(qpid::sys::Duration period); private: class Task : public TimerTask { diff --git a/qpid/cpp/src/qpid/broker/QueueEvents.cpp b/qpid/cpp/src/qpid/broker/QueueEvents.cpp index a6517e1bfe..7525e4cb76 100644 --- a/qpid/cpp/src/qpid/broker/QueueEvents.cpp +++ b/qpid/cpp/src/qpid/broker/QueueEvents.cpp @@ -20,12 +20,13 @@ */ #include "QueueEvents.h" #include "qpid/Exception.h" +#include "qpid/log/Statement.h" namespace qpid { namespace broker { QueueEvents::QueueEvents(const boost::shared_ptr<sys::Poller>& poller) : - eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller) + eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller), enabled(true) { eventQueue.start(); } @@ -37,12 +38,12 @@ QueueEvents::~QueueEvents() void QueueEvents::enqueued(const QueuedMessage& m) { - eventQueue.push(Event(ENQUEUE, m)); + if (enabled) eventQueue.push(Event(ENQUEUE, m)); } void QueueEvents::dequeued(const QueuedMessage& m) { - eventQueue.push(Event(DEQUEUE, m)); + if (enabled) eventQueue.push(Event(DEQUEUE, m)); } void QueueEvents::registerListener(const std::string& id, const EventListener& listener) @@ -81,6 +82,18 @@ void QueueEvents::shutdown() if (!eventQueue.empty() && !listeners.empty()) eventQueue.shutdown(); } +void QueueEvents::enable() +{ + enabled = true; + QPID_LOG(debug, "Queue events enabled"); +} + +void QueueEvents::disable() +{ + enabled = false; + QPID_LOG(debug, "Queue events disabled"); +} + QueueEvents::Event::Event(EventType t, const QueuedMessage& m) : type(t), msg(m) {} diff --git a/qpid/cpp/src/qpid/broker/QueueEvents.h b/qpid/cpp/src/qpid/broker/QueueEvents.h index 2ba69e33e6..82abd3d20a 100644 --- a/qpid/cpp/src/qpid/broker/QueueEvents.h +++ b/qpid/cpp/src/qpid/broker/QueueEvents.h @@ -22,6 +22,7 @@ * */ +#include "BrokerImportExport.h" #include "QueuedMessage.h" #include "qpid/sys/Mutex.h" #include "qpid/sys/PollableQueue.h" @@ -48,25 +49,29 @@ class QueueEvents EventType type; QueuedMessage msg; - Event(EventType, const QueuedMessage&); + QPID_BROKER_EXTERN Event(EventType, const QueuedMessage&); }; typedef boost::function<void (Event)> EventListener; - QueueEvents(const boost::shared_ptr<sys::Poller>& poller); - ~QueueEvents(); - void enqueued(const QueuedMessage&); - void dequeued(const QueuedMessage&); - void registerListener(const std::string& id, const EventListener&); - void unregisterListener(const std::string& id); + QPID_BROKER_EXTERN QueueEvents(const boost::shared_ptr<sys::Poller>& poller); + QPID_BROKER_EXTERN ~QueueEvents(); + QPID_BROKER_EXTERN void enqueued(const QueuedMessage&); + QPID_BROKER_EXTERN void dequeued(const QueuedMessage&); + QPID_BROKER_EXTERN void registerListener(const std::string& id, + const EventListener&); + QPID_BROKER_EXTERN void unregisterListener(const std::string& id); + void enable(); + void disable(); //process all outstanding events - void shutdown(); + QPID_BROKER_EXTERN void shutdown(); private: typedef qpid::sys::PollableQueue<Event> EventQueue; typedef std::map<std::string, EventListener> Listeners; EventQueue eventQueue; Listeners listeners; + volatile bool enabled; qpid::sys::Mutex lock;//protect listeners from concurrent access void handle(EventQueue::Queue& e); diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp index 41a6709d27..c59736969f 100644 --- a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp +++ b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp @@ -126,7 +126,7 @@ std::string QueuePolicy::getType(const FieldTable& settings) FieldTable::ValuePtr v = settings.get(typeKey); if (v && v->convertsTo<std::string>()) { std::string t = v->get<std::string>(); - transform(t.begin(), t.end(), t.begin(), tolower); + std::transform(t.begin(), t.end(), t.begin(), tolower); if (t == REJECT || t == FLOW_TO_DISK || t == RING || t == RING_STRICT) return t; } return FLOW_TO_DISK; @@ -197,11 +197,12 @@ void RingQueuePolicy::enqueued(const QueuedMessage& m) void RingQueuePolicy::dequeued(const QueuedMessage& m) { qpid::sys::Mutex::ScopedLock l(lock); - QueuePolicy::dequeued(m); //find and remove m from queue - for (Messages::iterator i = queue.begin(); i != queue.end() && m.position <= i->position; i++) { - if (i->position == m.position) { + for (Messages::iterator i = queue.begin(); i != queue.end(); i++) { + if (i->payload == m.payload) { queue.erase(i); + //now update count and size + QueuePolicy::dequeued(m); break; } } @@ -210,9 +211,11 @@ void RingQueuePolicy::dequeued(const QueuedMessage& m) bool RingQueuePolicy::isEnqueued(const QueuedMessage& m) { qpid::sys::Mutex::ScopedLock l(lock); - //for non-strict ring policy, a message can be dequeued before acked; need to detect this - for (Messages::iterator i = queue.begin(); i != queue.end() && m.position <= i->position; i++) { - if (i->position == m.position) { + //for non-strict ring policy, a message can be replaced (and + //therefore dequeued) before it is accepted or released by + //subscriber; need to detect this + for (Messages::const_iterator i = queue.begin(); i != queue.end(); i++) { + if (i->payload == m.payload) { return true; } } @@ -236,13 +239,10 @@ bool RingQueuePolicy::checkLimit(const QueuedMessage& m) oldest = queue.front(); } if (oldest.queue->acquire(oldest) || !strict) { - qpid::sys::Mutex::ScopedLock l(lock); - if (oldest.position == queue.front().position) { - queue.pop_front(); - QPID_LOG(debug, "Ring policy triggered in queue " - << (m.queue ? m.queue->getName() : std::string("unknown queue")) - << ": removed message " << oldest.position << " to make way for " << m.position); - } + oldest.queue->dequeue(0, oldest); + QPID_LOG(debug, "Ring policy triggered in queue " + << (m.queue ? m.queue->getName() : std::string("unknown queue")) + << ": removed message " << oldest.position << " to make way for " << m.position); return true; } else { QPID_LOG(debug, "Ring policy could not be triggered in queue " diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.h b/qpid/cpp/src/qpid/broker/QueuePolicy.h index 0e8c15aa0e..45992f87ac 100644 --- a/qpid/cpp/src/qpid/broker/QueuePolicy.h +++ b/qpid/cpp/src/qpid/broker/QueuePolicy.h @@ -24,6 +24,7 @@ #include <deque> #include <iostream> #include <memory> +#include "BrokerImportExport.h" #include "QueuedMessage.h" #include "qpid/framing/FieldTable.h" #include "qpid/sys/AtomicValue.h" @@ -47,20 +48,20 @@ class QueuePolicy static std::string getType(const qpid::framing::FieldTable& settings); public: - static const std::string maxCountKey; - static const std::string maxSizeKey; - static const std::string typeKey; - static const std::string REJECT; - static const std::string FLOW_TO_DISK; - static const std::string RING; - static const std::string RING_STRICT; + static QPID_BROKER_EXTERN const std::string maxCountKey; + static QPID_BROKER_EXTERN const std::string maxSizeKey; + static QPID_BROKER_EXTERN const std::string typeKey; + static QPID_BROKER_EXTERN const std::string REJECT; + static QPID_BROKER_EXTERN const std::string FLOW_TO_DISK; + static QPID_BROKER_EXTERN const std::string RING; + static QPID_BROKER_EXTERN const std::string RING_STRICT; virtual ~QueuePolicy() {} - void tryEnqueue(const QueuedMessage&); + QPID_BROKER_EXTERN void tryEnqueue(const QueuedMessage&); virtual void dequeued(const QueuedMessage&); virtual bool isEnqueued(const QueuedMessage&); virtual bool checkLimit(const QueuedMessage&); - void update(qpid::framing::FieldTable& settings); + QPID_BROKER_EXTERN void update(qpid::framing::FieldTable& settings); uint32_t getMaxCount() const { return maxCount; } uint64_t getMaxSize() const { return maxSize; } void encode(framing::Buffer& buffer) const; @@ -68,10 +69,11 @@ class QueuePolicy uint32_t encodedSize() const; - static std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings); - static std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT); + static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings); + static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT); static void setDefaultMaxSize(uint64_t); - friend std::ostream& operator<<(std::ostream&, const QueuePolicy&); + friend QPID_BROKER_EXTERN std::ostream& operator<<(std::ostream&, + const QueuePolicy&); protected: QueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT); diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp index 2cb801bf83..d079e543c4 100644 --- a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp +++ b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp @@ -19,6 +19,7 @@ * */ #include "QueueRegistry.h" +#include "QueueEvents.h" #include "qpid/log/Statement.h" #include <sstream> #include <assert.h> @@ -27,7 +28,7 @@ using namespace qpid::broker; using namespace qpid::sys; QueueRegistry::QueueRegistry() : - counter(1), store(0), parent(0), lastNode(false) {} + counter(1), store(0), events(0), parent(0), lastNode(false) {} QueueRegistry::~QueueRegistry(){} @@ -43,7 +44,8 @@ QueueRegistry::declare(const string& declareName, bool durable, if (i == queues.end()) { Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner, parent)); queues[name] = queue; - if (lastNode) queue->setLastNodeFailure(); + if (lastNode) queue->setLastNodeFailure(); + if (events) queue->setQueueEventManager(*events); return std::pair<Queue::shared_ptr, bool>(queue, true); } else { @@ -105,3 +107,7 @@ void QueueRegistry::updateQueueClusterState(bool _lastNode) lastNode = _lastNode; } +void QueueRegistry::setQueueEvents(QueueEvents* e) +{ + events = e; +} diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.h b/qpid/cpp/src/qpid/broker/QueueRegistry.h index c53ba668cc..3c02afedc4 100644 --- a/qpid/cpp/src/qpid/broker/QueueRegistry.h +++ b/qpid/cpp/src/qpid/broker/QueueRegistry.h @@ -21,6 +21,7 @@ #ifndef _QueueRegistry_ #define _QueueRegistry_ +#include "BrokerImportExport.h" #include "Queue.h" #include "qpid/sys/Mutex.h" #include "qpid/management/Manageable.h" @@ -31,6 +32,8 @@ namespace qpid { namespace broker { +class QueueEvents; + /** * A registry of queues indexed by queue name. * @@ -38,10 +41,10 @@ namespace broker { * are deleted when and only when they are no longer in use. * */ -class QueueRegistry{ +class QueueRegistry { public: - QueueRegistry(); - ~QueueRegistry(); + QPID_BROKER_EXTERN QueueRegistry(); + QPID_BROKER_EXTERN ~QueueRegistry(); /** * Declare a queue. @@ -49,8 +52,11 @@ class QueueRegistry{ * @return The queue and a boolean flag which is true if the queue * was created by this declare call false if it already existed. */ - std::pair<Queue::shared_ptr, bool> declare(const string& name, bool durable = false, bool autodelete = false, - const OwnershipToken* owner = 0); + QPID_BROKER_EXTERN std::pair<Queue::shared_ptr, bool> declare + (const string& name, + bool durable = false, + bool autodelete = false, + const OwnershipToken* owner = 0); /** * Destroy the named queue. @@ -64,7 +70,7 @@ class QueueRegistry{ * subsequent calls to find or declare with the same name. * */ - void destroy (const string& name); + QPID_BROKER_EXTERN void destroy(const string& name); template <class Test> bool destroyIf(const string& name, Test test) { qpid::sys::RWlock::ScopedWlock locker(lock); @@ -79,13 +85,15 @@ class QueueRegistry{ /** * Find the named queue. Return 0 if not found. */ - Queue::shared_ptr find(const string& name); + QPID_BROKER_EXTERN Queue::shared_ptr find(const string& name); /** * Generate unique queue name. */ string generateName(); + void setQueueEvents(QueueEvents*); + /** * Set the store to use. May only be called once. */ @@ -120,6 +128,7 @@ private: mutable qpid::sys::RWlock lock; int counter; MessageStore* store; + QueueEvents* events; management::Manageable* parent; bool lastNode; //used to set mode on queue declare diff --git a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp index 8030cf7d0e..5f8b57fa0b 100644 --- a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp +++ b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp @@ -149,7 +149,8 @@ RecoverableConfig::shared_ptr RecoveryManagerImpl::recoverConfig(framing::Buffer void RecoveryManagerImpl::recoveryComplete() { - //TODO (finalise binding setup etc) + //notify all queues + queues.eachQueue(boost::bind(&Queue::recoveryComplete, _1)); } bool RecoverableMessageImpl::loadContent(uint64_t available) diff --git a/qpid/cpp/src/qpid/broker/RetryList.h b/qpid/cpp/src/qpid/broker/RetryList.h index 013233ef00..3cdba72ecf 100644 --- a/qpid/cpp/src/qpid/broker/RetryList.h +++ b/qpid/cpp/src/qpid/broker/RetryList.h @@ -22,6 +22,7 @@ * */ +#include "BrokerImportExport.h" #include "qpid/Address.h" #include "qpid/Url.h" @@ -35,9 +36,9 @@ namespace broker { class RetryList { public: - RetryList(); - void reset(const std::vector<Url>& urls); - bool next(TcpAddress& address); + QPID_BROKER_EXTERN RetryList(); + QPID_BROKER_EXTERN void reset(const std::vector<Url>& urls); + QPID_BROKER_EXTERN bool next(TcpAddress& address); private: std::vector<Url> urls; size_t urlIndex; diff --git a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp index 736b051945..edc66444ec 100644 --- a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp +++ b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp @@ -141,21 +141,31 @@ NullAuthenticator::~NullAuthenticator() {} void NullAuthenticator::getMechanisms(Array& mechanisms) { mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("ANONYMOUS"))); + mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("PLAIN")));//useful for testing } void NullAuthenticator::start(const string& mechanism, const string& response) { if (mechanism == "PLAIN") { // Old behavior - if (response.size() > 0 && response[0] == (char) 0) { - string temp = response.substr(1); - string::size_type i = temp.find((char)0); - string uid = temp.substr(0, i); - string pwd = temp.substr(i + 1); - i = uid.find_last_of(realm); - if (i == string::npos || i != (uid.size() - 1)) { - uid = str(format("%1%@%2%") % uid % realm); + if (response.size() > 0) { + string uid; + string::size_type i = response.find((char)0); + if (i == 0 && response.size() > 1) { + //no authorization id; use authentication id + i = response.find((char)0, 1); + if (i != string::npos) uid = response.substr(1, i-1); + } else if (i != string::npos) { + //authorization id is first null delimited field + uid = response.substr(0, i); + }//else not a valid SASL PLAIN response, throw error? + if (!uid.empty()) { + //append realm if it has not already been added + i = uid.find(realm); + if (i == string::npos || realm.size() + i < uid.size()) { + uid = str(format("%1%@%2%") % uid % realm); + } + connection.setUserId(uid); } - connection.setUserId(uid); } } else { connection.setUserId("anonymous"); diff --git a/qpid/cpp/src/qpid/broker/SemanticState.cpp b/qpid/cpp/src/qpid/broker/SemanticState.cpp index 4f751e43b7..3c7c6d9afa 100644 --- a/qpid/cpp/src/qpid/broker/SemanticState.cpp +++ b/qpid/cpp/src/qpid/broker/SemanticState.cpp @@ -355,20 +355,12 @@ const std::string nullstring; } void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) { + msg->setTimestamp(getSession().getBroker().getExpiryPolicy()); + std::string exchangeName = msg->getExchangeName(); - //TODO: the following should be hidden behind message (using MessageAdapter or similar) - - if (msg->isA<MessageTransferBody>()) { - // Do not replace the delivery-properties.exchange if it is is already set. - // This is used internally (by the cluster) to force the exchange name on a message. - // The client library ensures this is always empty for messages from normal clients. - if (!msg->hasProperties<DeliveryProperties>() || msg->getProperties<DeliveryProperties>()->getExchange().empty()) - msg->getProperties<DeliveryProperties>()->setExchange(exchangeName); - msg->setTimestamp(getSession().getBroker().getExpiryPolicy()); - } - if (!cacheExchange || cacheExchange->getName() != exchangeName){ + if (!cacheExchange || cacheExchange->getName() != exchangeName) cacheExchange = session.getBroker().getExchanges().get(exchangeName); - } + cacheExchange->setProperties(msg); /* verify the userid if specified: */ std::string id = @@ -516,14 +508,16 @@ void SemanticState::ConsumerImpl::setCreditMode() void SemanticState::ConsumerImpl::addByteCredit(uint32_t value) { if (byteCredit != 0xFFFFFFFF) { - byteCredit += value; + if (value == 0xFFFFFFFF) byteCredit = value; + else byteCredit += value; } } void SemanticState::ConsumerImpl::addMessageCredit(uint32_t value) { if (msgCredit != 0xFFFFFFFF) { - msgCredit += value; + if (value == 0xFFFFFFFF) msgCredit = value; + else msgCredit += value; } } diff --git a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp index ae160fabc7..96c47085f0 100644 --- a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp +++ b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp @@ -362,10 +362,6 @@ void SessionAdapter::QueueHandlerImpl::declare(const string& name, const string& getBroker().getExchanges().getDefault()->bind(queue, name, 0); queue->bound(getBroker().getExchanges().getDefault()->getName(), name, arguments); - //if event generation is turned on, pass in a pointer to - //the QueueEvents instance to use - if (queue->getEventMode()) queue->setQueueEventManager(getBroker().getQueueEvents()); - //handle automatic cleanup: if (exclusive) { exclusiveQueues.push_back(queue); diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.cpp b/qpid/cpp/src/qpid/broker/SessionHandler.cpp index 2c4de478f6..442c3eb34b 100644 --- a/qpid/cpp/src/qpid/broker/SessionHandler.cpp +++ b/qpid/cpp/src/qpid/broker/SessionHandler.cpp @@ -34,7 +34,8 @@ using namespace qpid::sys; SessionHandler::SessionHandler(Connection& c, ChannelId ch) : amqp_0_10::SessionHandler(&c.getOutput(), ch), connection(c), - proxy(out) + proxy(out), + clusterOrderProxy(c.getClusterOrderOutput() ? new SetChannelProxy(ch, c.getClusterOrderOutput()) : 0) {} SessionHandler::~SessionHandler() {} @@ -84,11 +85,23 @@ void SessionHandler::readyToSend() { if (session.get()) session->readyToSend(); } -// TODO aconway 2008-05-12: hacky - handle attached for bridge clients. -// We need to integrate the client code so we can run a real client -// in the bridge. -// -void SessionHandler::attached(const std::string& name) { +/** + * Used by inter-broker bridges to set up session id and attach + */ +void SessionHandler::attachAs(const std::string& name) +{ + SessionId id(connection.getUserId(), name); + SessionState::Configuration config = connection.broker.getSessionManager().getSessionConfig(); + session.reset(new SessionState(connection.getBroker(), *this, id, config)); + sendAttach(false); +} + +/** + * TODO: this is a little ugly, fix it; its currently still relied on + * for 'push' bridges + */ +void SessionHandler::attached(const std::string& name) +{ if (session.get()) { amqp_0_10::SessionHandler::attached(name); } else { diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.h b/qpid/cpp/src/qpid/broker/SessionHandler.h index 7449db1560..ffc032f64c 100644 --- a/qpid/cpp/src/qpid/broker/SessionHandler.h +++ b/qpid/cpp/src/qpid/broker/SessionHandler.h @@ -54,10 +54,20 @@ class SessionHandler : public amqp_0_10::SessionHandler { framing::AMQP_ClientProxy& getProxy() { return proxy; } const framing::AMQP_ClientProxy& getProxy() const { return proxy; } + /** + * If commands are sent based on the local time (e.g. in timers), they don't have + * a well-defined ordering across cluster nodes. + * This proxy is for sending such commands. In a clustered broker it will take steps + * to synchronize command order across the cluster. In a stand-alone broker + * it is just a synonym for getProxy() + */ + framing::AMQP_ClientProxy& getClusterOrderProxy() { + return clusterOrderProxy.get() ? *clusterOrderProxy : proxy; + } + virtual void handleDetach(); - - // Overrides - void attached(const std::string& name); + void attached(const std::string& name);//used by 'pushing' inter-broker bridges + void attachAs(const std::string& name);//used by 'pulling' inter-broker bridges protected: virtual void setState(const std::string& sessionName, bool force); @@ -69,9 +79,16 @@ class SessionHandler : public amqp_0_10::SessionHandler { virtual void readyToSend(); private: + struct SetChannelProxy : public framing::AMQP_ClientProxy { // Proxy that sets the channel. + framing::ChannelHandler setChannel; + SetChannelProxy(uint16_t ch, framing::FrameHandler* out) + : framing::AMQP_ClientProxy(setChannel), setChannel(ch, out) {} + }; + Connection& connection; framing::AMQP_ClientProxy proxy; std::auto_ptr<SessionState> session; + std::auto_ptr<SetChannelProxy> clusterOrderProxy; }; }} // namespace qpid::broker diff --git a/qpid/cpp/src/qpid/broker/SessionState.cpp b/qpid/cpp/src/qpid/broker/SessionState.cpp index 82ffede3f9..7e5f605753 100644 --- a/qpid/cpp/src/qpid/broker/SessionState.cpp +++ b/qpid/cpp/src/qpid/broker/SessionState.cpp @@ -66,7 +66,7 @@ SessionState::SessionState( uint32_t maxRate = broker.getOptions().maxSessionRate; if (maxRate) { if (handler->getConnection().getClientThrottling()) { - rateFlowcontrol = new RateFlowcontrol(maxRate); + rateFlowcontrol.reset(new RateFlowcontrol(maxRate)); } else { QPID_LOG(warning, getId() << ": Unable to flow control client - client doesn't support"); } @@ -212,11 +212,15 @@ struct ScheduledCreditTask : public TimerTask { void fire() { // This is the best we can currently do to avoid a destruction/fire race if (!isCancelled()) { - if ( !sessionState.processSendCredit(0) ) { - QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit"); - reset(); - timer.add(this); - } + sessionState.getConnection().requestIOProcessing(boost::bind(&ScheduledCreditTask::sendCredit, this)); + } + } + + void sendCredit() { + if ( !sessionState.processSendCredit(0) ) { + QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit"); + reset(); + timer.add(this); } } }; @@ -274,7 +278,8 @@ bool SessionState::processSendCredit(uint32_t msgs) if ( msgs > 0 && rateFlowcontrol->flowStopped() ) { QPID_LOG(warning, getId() << ": producer throttling violation"); // TODO: Probably do message.stop("") first time then disconnect - getProxy().getMessage().stop(""); + // See comment on getClusterOrderProxy() in .h file + getClusterOrderProxy().getMessage().stop(""); return true; } AbsTime now = AbsTime::now(); @@ -282,7 +287,7 @@ bool SessionState::processSendCredit(uint32_t msgs) if (mgmtObject) mgmtObject->dec_clientCredit(msgs); if ( sendCredit>0 ) { QPID_LOG(debug, getId() << ": send producer credit " << sendCredit); - getProxy().getMessage().flow("", 0, sendCredit); + getClusterOrderProxy().getMessage().flow("", 0, sendCredit); rateFlowcontrol->sentCredit(now, sendCredit); if (mgmtObject) mgmtObject->inc_clientCredit(sendCredit); return true; @@ -363,8 +368,9 @@ void SessionState::readyToSend() { // Issue initial credit - use a heuristic here issue min of 300 messages or 1 secs worth uint32_t credit = std::min(rateFlowcontrol->getRate(), 300U); QPID_LOG(debug, getId() << ": Issuing producer message credit " << credit); - getProxy().getMessage().setFlowMode("", 0); - getProxy().getMessage().flow("", 0, credit); + // See comment on getClusterOrderProxy() in .h file + getClusterOrderProxy().getMessage().setFlowMode("", 0); + getClusterOrderProxy().getMessage().flow("", 0, credit); rateFlowcontrol->sentCredit(AbsTime::now(), credit); if (mgmtObject) mgmtObject->inc_clientCredit(credit); } @@ -372,4 +378,8 @@ void SessionState::readyToSend() { Broker& SessionState::getBroker() { return broker; } +framing::AMQP_ClientProxy& SessionState::getClusterOrderProxy() { + return handler->getClusterOrderProxy(); +} + }} // namespace qpid::broker diff --git a/qpid/cpp/src/qpid/broker/SessionState.h b/qpid/cpp/src/qpid/broker/SessionState.h index c435a741f8..bdfed87905 100644 --- a/qpid/cpp/src/qpid/broker/SessionState.h +++ b/qpid/cpp/src/qpid/broker/SessionState.h @@ -56,7 +56,7 @@ class Message; class SessionHandler; class SessionManager; class RateFlowcontrol; -class TimerTask; +struct TimerTask; /** * Broker-side session state includes session's handler chains, which @@ -125,6 +125,15 @@ class SessionState : public qpid::SessionState, void sendAcceptAndCompletion(); + /** + * If commands are sent based on the local time (e.g. in timers), they don't have + * a well-defined ordering across cluster nodes. + * This proxy is for sending such commands. In a clustered broker it will take steps + * to synchronize command order across the cluster. In a stand-alone broker + * it is just a synonym for getProxy() + */ + framing::AMQP_ClientProxy& getClusterOrderProxy(); + Broker& broker; SessionHandler* handler; sys::AbsTime expiry; // Used by SessionManager. @@ -138,7 +147,7 @@ class SessionState : public qpid::SessionState, // State used for producer flow control (rate limited) qpid::sys::Mutex rateLock; - RateFlowcontrol* rateFlowcontrol; + boost::scoped_ptr<RateFlowcontrol> rateFlowcontrol; boost::intrusive_ptr<TimerTask> flowControlTimer; friend class SessionManager; diff --git a/qpid/cpp/src/qpid/broker/Timer.h b/qpid/cpp/src/qpid/broker/Timer.h index be4ac9d056..564fec5804 100644 --- a/qpid/cpp/src/qpid/broker/Timer.h +++ b/qpid/cpp/src/qpid/broker/Timer.h @@ -21,6 +21,7 @@ #ifndef _Timer_ #define _Timer_ +#include "BrokerImportExport.h" #include "qpid/sys/Monitor.h" #include "qpid/sys/Thread.h" #include "qpid/sys/Runnable.h" @@ -43,9 +44,9 @@ struct TimerTask : public RefCounted { qpid::sys::AbsTime time; volatile bool cancelled; - TimerTask(qpid::sys::Duration timeout); + QPID_BROKER_EXTERN TimerTask(qpid::sys::Duration timeout); TimerTask(qpid::sys::AbsTime time); - virtual ~TimerTask(); + QPID_BROKER_EXTERN virtual ~TimerTask(); void reset(); void cancel(); bool isCancelled() const; @@ -69,10 +70,10 @@ class Timer : private qpid::sys::Runnable { virtual void run(); public: - Timer(); - virtual ~Timer(); + QPID_BROKER_EXTERN Timer(); + QPID_BROKER_EXTERN virtual ~Timer(); - void add(boost::intrusive_ptr<TimerTask> task); + QPID_BROKER_EXTERN void add(boost::intrusive_ptr<TimerTask> task); void start(); void stop(); diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.h b/qpid/cpp/src/qpid/broker/TopicExchange.h index f3a2e221f7..24bf5f7bca 100644 --- a/qpid/cpp/src/qpid/broker/TopicExchange.h +++ b/qpid/cpp/src/qpid/broker/TopicExchange.h @@ -23,6 +23,7 @@ #include <map> #include <vector> +#include "BrokerImportExport.h" #include "Exchange.h" #include "qpid/framing/FieldTable.h" #include "qpid/sys/Monitor.h" @@ -40,7 +41,7 @@ class Tokens : public std::vector<std::string> { /** Tokenize s, provides automatic conversion of string to Tokens */ Tokens(const std::string& s) { operator=(s); } /** Tokenizing assignment operator s */ - Tokens & operator=(const std::string& s); + QPID_BROKER_EXTERN Tokens & operator=(const std::string& s); void key(std::string& key) const; private: @@ -60,12 +61,12 @@ class TopicPattern : public Tokens // Default copy, assign, dtor are sufficient. TopicPattern(const Tokens& tokens) { operator=(tokens); } TopicPattern(const std::string& str) { operator=(str); } - TopicPattern& operator=(const Tokens&); + QPID_BROKER_EXTERN TopicPattern& operator=(const Tokens&); TopicPattern& operator=(const std::string& str) { return operator=(Tokens(str)); } /** Match a topic */ bool match(const std::string& topic) { return match(Tokens(topic)); } - bool match(const Tokens& topic) const; + QPID_BROKER_EXTERN bool match(const Tokens& topic) const; private: void normalize(); @@ -84,21 +85,30 @@ class TopicExchange : public virtual Exchange { public: static const std::string typeName; - TopicExchange(const string& name, management::Manageable* parent = 0); - TopicExchange(const string& _name, bool _durable, - const qpid::framing::FieldTable& _args, management::Manageable* parent = 0); + QPID_BROKER_EXTERN TopicExchange(const string& name, + management::Manageable* parent = 0); + QPID_BROKER_EXTERN TopicExchange(const string& _name, + bool _durable, + const qpid::framing::FieldTable& _args, + management::Manageable* parent = 0); virtual std::string getType() const { return typeName; } - virtual bool bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue, + const string& routingKey, + const qpid::framing::FieldTable* args); virtual bool unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args); - virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args); + QPID_BROKER_EXTERN virtual void route(Deliverable& msg, + const string& routingKey, + const qpid::framing::FieldTable* args); - virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args); + QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue, + const string* const routingKey, + const qpid::framing::FieldTable* const args); - virtual ~TopicExchange(); + QPID_BROKER_EXTERN virtual ~TopicExchange(); virtual bool supportsDynamicBinding() { return true; } }; diff --git a/qpid/cpp/src/qpid/broker/TxAccept.cpp b/qpid/cpp/src/qpid/broker/TxAccept.cpp index c7001e5526..73f365d509 100644 --- a/qpid/cpp/src/qpid/broker/TxAccept.cpp +++ b/qpid/cpp/src/qpid/broker/TxAccept.cpp @@ -50,12 +50,12 @@ void TxAccept::RangeOps::operator()(SequenceNumber start, SequenceNumber end) void TxAccept::RangeOps::prepare(TransactionContext* ctxt) { - for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt)); + std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt)); } void TxAccept::RangeOps::commit() { - for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1)); + std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1)); //now remove if isRedundant(): if (!ranges.empty()) { ack_iterator i = ranges.front().range.start; diff --git a/qpid/cpp/src/qpid/broker/TxBuffer.h b/qpid/cpp/src/qpid/broker/TxBuffer.h index aabb5ea0b1..f63a65f115 100644 --- a/qpid/cpp/src/qpid/broker/TxBuffer.h +++ b/qpid/cpp/src/qpid/broker/TxBuffer.h @@ -24,6 +24,7 @@ #include <algorithm> #include <functional> #include <vector> +#include "BrokerImportExport.h" #include "TransactionalStore.h" #include "TxOp.h" @@ -68,7 +69,7 @@ namespace qpid { /** * Adds an operation to the transaction. */ - void enlist(TxOp::shared_ptr op); + QPID_BROKER_EXTERN void enlist(TxOp::shared_ptr op); /** * Requests that all ops are prepared. This should @@ -81,7 +82,7 @@ namespace qpid { * @returns true if all the operations prepared * successfully, false if not. */ - bool prepare(TransactionContext* const ctxt); + QPID_BROKER_EXTERN bool prepare(TransactionContext* const ctxt); /** * Signals that the ops all prepared successfully and can @@ -91,7 +92,7 @@ namespace qpid { * Should only be called after a call to prepare() returns * true. */ - void commit(); + QPID_BROKER_EXTERN void commit(); /** * Signals that all ops can be rolled back. @@ -100,13 +101,13 @@ namespace qpid { * returns true (2pc) or instead of a prepare call * ('server-local') */ - void rollback(); + QPID_BROKER_EXTERN void rollback(); /** * Helper method for managing the process of server local * commit */ - bool commitLocal(TransactionalStore* const store); + QPID_BROKER_EXTERN bool commitLocal(TransactionalStore* const store); // Used by cluster to replicate transaction status. void accept(TxOpConstVisitor& v) const; diff --git a/qpid/cpp/src/qpid/broker/TxPublish.h b/qpid/cpp/src/qpid/broker/TxPublish.h index 1f73cb8767..ebe3b51f3d 100644 --- a/qpid/cpp/src/qpid/broker/TxPublish.h +++ b/qpid/cpp/src/qpid/broker/TxPublish.h @@ -21,6 +21,7 @@ #ifndef _TxPublish_ #define _TxPublish_ +#include "BrokerImportExport.h" #include "Queue.h" #include "Deliverable.h" #include "Message.h" @@ -65,19 +66,19 @@ namespace qpid { std::list<Queue::shared_ptr> queues; public: - TxPublish(boost::intrusive_ptr<Message> msg); - virtual bool prepare(TransactionContext* ctxt) throw(); - virtual void commit() throw(); - virtual void rollback() throw(); + QPID_BROKER_EXTERN TxPublish(boost::intrusive_ptr<Message> msg); + QPID_BROKER_EXTERN virtual bool prepare(TransactionContext* ctxt) throw(); + QPID_BROKER_EXTERN virtual void commit() throw(); + QPID_BROKER_EXTERN virtual void rollback() throw(); virtual Message& getMessage() { return *msg; }; - virtual void deliverTo(const boost::shared_ptr<Queue>& queue); + QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue); virtual ~TxPublish(){} virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); } - uint64_t contentSize(); + QPID_BROKER_EXTERN uint64_t contentSize(); boost::intrusive_ptr<Message> getMessage() const { return msg; } const std::list<Queue::shared_ptr> getQueues() const { return queues; } diff --git a/qpid/cpp/src/qpid/client/ClientImportExport.h b/qpid/cpp/src/qpid/client/ClientImportExport.h new file mode 100644 index 0000000000..0e6e5660d6 --- /dev/null +++ b/qpid/cpp/src/qpid/client/ClientImportExport.h @@ -0,0 +1,33 @@ +#ifndef QPID_CLIENT_IMPORT_EXPORT_H +#define QPID_CLIENT_IMPORT_EXPORT_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. + */ + +#if defined(WIN32) && !defined(QPID_DECLARE_STATIC) +#if defined(CLIENT_EXPORT) +#define QPID_CLIENT_EXTERN __declspec(dllexport) +#else +#define QPID_CLIENT_EXTERN __declspec(dllimport) +#endif +#else +#define QPID_CLIENT_EXTERN +#endif + +#endif diff --git a/qpid/cpp/src/qpid/client/Connection.h b/qpid/cpp/src/qpid/client/Connection.h index 03631ef56f..846ac33790 100644 --- a/qpid/cpp/src/qpid/client/Connection.h +++ b/qpid/cpp/src/qpid/client/Connection.h @@ -24,6 +24,7 @@ #include <map> #include <string> #include "qpid/client/Session.h" +#include "qpid/client/ClientImportExport.h" namespace qpid { @@ -58,9 +59,9 @@ class Connection * Creates a connection object, but does not open the connection. * @see open() */ - Connection(); + QPID_CLIENT_EXTERN Connection(); - ~Connection(); + QPID_CLIENT_EXTERN ~Connection(); /** * Opens a connection to a broker. @@ -79,7 +80,7 @@ class Connection * hosts, where implemented(!), provide namespace partitioning * within a single broker). */ - void open(const std::string& host, int port = 5672, + QPID_CLIENT_EXTERN void open(const std::string& host, int port = 5672, const std::string& uid = "guest", const std::string& pwd = "guest", const std::string& virtualhost = "/", uint16_t maxFrameSize=65535); @@ -101,7 +102,7 @@ class Connection * hosts, where implemented(!), provide namespace partitioning * within a single broker). */ - void open(const Url& url, + QPID_CLIENT_EXTERN void open(const Url& url, const std::string& uid = "guest", const std::string& pwd = "guest", const std::string& virtualhost = "/", uint16_t maxFrameSize=65535); @@ -116,14 +117,14 @@ class Connection * @param settings used for any settings not provided by the URL. * Settings provided by the url (e.g. host, port) are ignored. */ - void open(const Url& url, const ConnectionSettings& settings); + QPID_CLIENT_EXTERN void open(const Url& url, const ConnectionSettings& settings); /** * Opens a connection to a broker. * * @param the settings to use (host, port etc). @see ConnectionSettings. */ - void open(const ConnectionSettings& settings); + QPID_CLIENT_EXTERN void open(const ConnectionSettings& settings); /** * Close the connection. @@ -131,7 +132,7 @@ class Connection * Any further use of this connection (without reopening it) will * not succeed. */ - void close(); + QPID_CLIENT_EXTERN void close(); /** * Create a new session on this connection. Sessions allow @@ -174,23 +175,23 @@ class Connection * If the name is empty (the default) then a unique name will be * chosen using a Universally-unique identifier (UUID) algorithm. */ - Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0); + QPID_CLIENT_EXTERN Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0); /** * Resume a suspended session. A session may be resumed * on a different connection to the one that created it. */ - void resume(Session& session); + QPID_CLIENT_EXTERN void resume(Session& session); - bool isOpen() const; + QPID_CLIENT_EXTERN bool isOpen() const; - std::vector<Url> getKnownBrokers(); - void registerFailureCallback ( boost::function<void ()> fn ); + QPID_CLIENT_EXTERN std::vector<Url> getKnownBrokers(); + QPID_CLIENT_EXTERN void registerFailureCallback ( boost::function<void ()> fn ); /** * Return the set of client negotiated settings */ - const ConnectionSettings& getNegotiatedSettings(); + QPID_CLIENT_EXTERN const ConnectionSettings& getNegotiatedSettings(); friend class ConnectionAccess; ///<@internal friend class SessionBase_0_10; ///<@internal diff --git a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp index 377b84c019..6efdb91e96 100644 --- a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp +++ b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp @@ -28,6 +28,7 @@ #include "qpid/framing/reply_exceptions.h" #include "qpid/log/Helpers.h" #include "qpid/log/Statement.h" +#include "qpid/sys/SystemInfo.h" using namespace qpid::client; using namespace qpid::framing; @@ -52,6 +53,9 @@ const std::string INVALID_STATE_OPEN_OK("open-ok received in invalid state"); const std::string INVALID_STATE_CLOSE_OK("close-ok received in invalid state"); const std::string SESSION_FLOW_CONTROL("qpid.session_flow"); +const std::string CLIENT_PROCESS_NAME("qpid.client_process"); +const std::string CLIENT_PID("qpid.client_pid"); +const std::string CLIENT_PPID("qpid.client_ppid"); const int SESSION_FLOW_CONTROL_VER = 1; } @@ -80,6 +84,9 @@ ConnectionHandler::ConnectionHandler(const ConnectionSettings& s, ProtocolVersio FINISHED.insert(CLOSED); properties.setInt(SESSION_FLOW_CONTROL, SESSION_FLOW_CONTROL_VER); + properties.setString(CLIENT_PROCESS_NAME, sys::SystemInfo::getProcessName()); + properties.setInt(CLIENT_PID, sys::SystemInfo::getProcessId()); + properties.setInt(CLIENT_PPID, sys::SystemInfo::getParentProcessId()); } void ConnectionHandler::incoming(AMQFrame& frame) diff --git a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp index 8e27d78479..745bdb63b5 100644 --- a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp +++ b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp @@ -180,6 +180,9 @@ void ConnectionImpl::close() template <class F> void ConnectionImpl::closeInternal(const F& f) { + if (heartbeatTask) { + heartbeatTask->cancel(); + } { Mutex::ScopedUnlock u(lock); connector->close(); diff --git a/qpid/cpp/src/qpid/client/ConnectionSettings.h b/qpid/cpp/src/qpid/client/ConnectionSettings.h index f60b11a4ab..71fef219b4 100644 --- a/qpid/cpp/src/qpid/client/ConnectionSettings.h +++ b/qpid/cpp/src/qpid/client/ConnectionSettings.h @@ -25,6 +25,7 @@ #include "qpid/Options.h" #include "qpid/log/Options.h" #include "qpid/Url.h" +#include "qpid/client/ClientImportExport.h" #include <iostream> #include <exception> @@ -42,14 +43,14 @@ namespace client { */ struct ConnectionSettings { - ConnectionSettings(); - virtual ~ConnectionSettings(); + QPID_CLIENT_EXTERN ConnectionSettings(); + QPID_CLIENT_EXTERN virtual ~ConnectionSettings(); /** * Allows socket to be configured; default only sets tcp-nodelay * based on the flag set. Can be overridden. */ - virtual void configureSocket(qpid::sys::Socket&) const; + QPID_CLIENT_EXTERN virtual void configureSocket(qpid::sys::Socket&) const; /** * The protocol used for the connection (defaults to 'tcp') diff --git a/qpid/cpp/src/qpid/client/Connector.cpp b/qpid/cpp/src/qpid/client/Connector.cpp index e6355601df..c251233082 100644 --- a/qpid/cpp/src/qpid/client/Connector.cpp +++ b/qpid/cpp/src/qpid/client/Connector.cpp @@ -92,8 +92,6 @@ class TCPConnector : public Connector, public sys::Codec, private sys::Runnable framing::ProtocolVersion version; bool initiated; - - sys::Mutex closedLock; bool closed; bool joined; @@ -185,7 +183,7 @@ TCPConnector::~TCPConnector() { } void TCPConnector::connect(const std::string& host, int port){ - Mutex::ScopedLock l(closedLock); + Mutex::ScopedLock l(lock); assert(closed); try { socket.connect(host, port); @@ -207,7 +205,7 @@ void TCPConnector::connect(const std::string& host, int port){ } void TCPConnector::init(){ - Mutex::ScopedLock l(closedLock); + Mutex::ScopedLock l(lock); assert(joined); ProtocolInitiation init(version); writeDataBlock(init); @@ -216,17 +214,21 @@ void TCPConnector::init(){ } bool TCPConnector::closeInternal() { - Mutex::ScopedLock l(closedLock); - bool ret = !closed; + bool ret; + { + Mutex::ScopedLock l(lock); + ret = !closed; if (!closed) { closed = true; + aio->queueForDeletion(); poller->shutdown(); } - if (!joined && receiver.id() != Thread::current().id()) { - joined = true; - Mutex::ScopedUnlock u(closedLock); - receiver.join(); + if (joined || receiver.id() == Thread::current().id()) { + return ret; } + joined = true; + } + receiver.join(); return ret; } @@ -259,21 +261,19 @@ const std::string& TCPConnector::getIdentifier() const { } void TCPConnector::send(AMQFrame& frame) { + Mutex::ScopedLock l(lock); + frames.push_back(frame); + //only ask to write if this is the end of a frameset or if we + //already have a buffers worth of data + currentSize += frame.encodedSize(); bool notifyWrite = false; - { - Mutex::ScopedLock l(lock); - frames.push_back(frame); - //only ask to write if this is the end of a frameset or if we - //already have a buffers worth of data - currentSize += frame.encodedSize(); - if (frame.getEof()) { - lastEof = frames.size(); - notifyWrite = true; - } else { - notifyWrite = (currentSize >= maxFrameSize); - } + if (frame.getEof()) { + lastEof = frames.size(); + notifyWrite = true; + } else { + notifyWrite = (currentSize >= maxFrameSize); } - if (notifyWrite) aio->notifyPendingWrite(); + if (notifyWrite && !closed) aio->notifyPendingWrite(); } void TCPConnector::handleClosed() { @@ -384,14 +384,13 @@ void TCPConnector::run() { assert(protect); try { Dispatcher d(poller); - + for (int i = 0; i < 32; i++) { aio->queueReadBuffer(new Buff(maxFrameSize)); } - + aio->start(poller); d.run(); - aio->queueForDeletion(); socket.close(); } catch (const std::exception& e) { QPID_LOG(error, QPID_MSG("FAIL " << identifier << ": " << e.what())); diff --git a/qpid/cpp/src/qpid/client/Dispatcher.cpp b/qpid/cpp/src/qpid/client/Dispatcher.cpp index 27cc4184f9..8d8574520a 100644 --- a/qpid/cpp/src/qpid/client/Dispatcher.cpp +++ b/qpid/cpp/src/qpid/client/Dispatcher.cpp @@ -136,8 +136,7 @@ void Dispatcher::listen(const boost::intrusive_ptr<SubscriptionImpl>& subscripti void Dispatcher::cancel(const std::string& destination) { ScopedLock<Mutex> l(lock); - listeners.erase(destination); - if (autoStop && listeners.empty()) + if (listeners.erase(destination) && running && autoStop && listeners.empty()) queue->close(); } diff --git a/qpid/cpp/src/qpid/client/FailoverManager.cpp b/qpid/cpp/src/qpid/client/FailoverManager.cpp index ab9dbca70f..86b50a0a61 100644 --- a/qpid/cpp/src/qpid/client/FailoverManager.cpp +++ b/qpid/cpp/src/qpid/client/FailoverManager.cpp @@ -21,12 +21,15 @@ #include "FailoverManager.h" #include "qpid/Exception.h" #include "qpid/log/Statement.h" +#include "qpid/sys/Time.h" namespace qpid { namespace client { using qpid::sys::Monitor; +using qpid::sys::AbsTime; +using qpid::sys::Duration; FailoverManager::FailoverManager(const ConnectionSettings& s, ReconnectionStrategy* rs) : settings(s), strategy(rs), state(IDLE) {} @@ -35,15 +38,21 @@ void FailoverManager::execute(Command& c) { bool retry = false; bool completed = false; + AbsTime failed; while (!completed) { try { AsyncSession session = connect().newSession(); + if (retry) { + Duration failoverTime(failed, AbsTime::now()); + QPID_LOG(info, "Failed over for " << &c << " in " << (failoverTime/qpid::sys::TIME_MSEC) << " milliseconds"); + } c.execute(session, retry); session.sync();//TODO: shouldn't be required session.close(); completed = true; } catch(const TransportFailure&) { - retry = true; + retry = true; + failed = AbsTime::now(); } } } diff --git a/qpid/cpp/src/qpid/client/FailoverManager.h b/qpid/cpp/src/qpid/client/FailoverManager.h index 8b6eeda8a1..bef5e18840 100644 --- a/qpid/cpp/src/qpid/client/FailoverManager.h +++ b/qpid/cpp/src/qpid/client/FailoverManager.h @@ -27,6 +27,7 @@ #include "qpid/Exception.h" #include "qpid/client/AsyncSession.h" #include "qpid/sys/Monitor.h" +#include "qpid/client/ClientImportExport.h" #include <vector> namespace qpid { @@ -84,7 +85,7 @@ class FailoverManager * to edit or reorder the list of urls to which reconnection is * attempted */ - FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0); + QPID_CLIENT_EXTERN FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0); /** * Return the current connection if open or attept to reconnect to * the specified list of urls. If no list is specified the list of @@ -95,15 +96,15 @@ class FailoverManager * If the full list is tried and all attempts fail, * CannotConnectException is thrown. */ - Connection& connect(std::vector<Url> brokers = std::vector<Url>()); + QPID_CLIENT_EXTERN Connection& connect(std::vector<Url> brokers = std::vector<Url>()); /** * Return the current connection whether open or not */ - Connection& getConnection(); + QPID_CLIENT_EXTERN Connection& getConnection(); /** * Close the current connection */ - void close(); + QPID_CLIENT_EXTERN void close(); /** * Reliably execute the specified command. This involves creating * a session on which to carry out the work of the command, @@ -116,7 +117,7 @@ class FailoverManager * on failover to ensure they continue to use the same logical * connection. */ - void execute(Command&); + QPID_CLIENT_EXTERN void execute(Command&); private: enum State {IDLE, CONNECTING, CANT_CONNECT}; diff --git a/qpid/cpp/src/qpid/client/Future.h b/qpid/cpp/src/qpid/client/Future.h index 67f39cdf3f..ea01522fe8 100644 --- a/qpid/cpp/src/qpid/client/Future.h +++ b/qpid/cpp/src/qpid/client/Future.h @@ -30,6 +30,7 @@ #include "FutureCompletion.h" #include "FutureResult.h" #include "SessionImpl.h" +#include "ClientImportExport.h" namespace qpid { namespace client { @@ -54,9 +55,9 @@ public: } } - void wait(SessionImpl& session); - bool isComplete(SessionImpl& session); - void setFutureResult(boost::shared_ptr<FutureResult> r); + QPID_CLIENT_EXTERN void wait(SessionImpl& session); + QPID_CLIENT_EXTERN bool isComplete(SessionImpl& session); + QPID_CLIENT_EXTERN void setFutureResult(boost::shared_ptr<FutureResult> r); }; }} diff --git a/qpid/cpp/src/qpid/client/FutureResult.h b/qpid/cpp/src/qpid/client/FutureResult.h index e97d80476d..64428c0341 100644 --- a/qpid/cpp/src/qpid/client/FutureResult.h +++ b/qpid/cpp/src/qpid/client/FutureResult.h @@ -23,6 +23,8 @@ #define _FutureResult_ #include <string> + +#include "ClientImportExport.h" #include "qpid/framing/amqp_framing.h" #include "FutureCompletion.h" @@ -36,7 +38,7 @@ class FutureResult : public FutureCompletion { std::string result; public: - const std::string& getResult(SessionImpl& session) const; + QPID_CLIENT_EXTERN const std::string& getResult(SessionImpl& session) const; void received(const std::string& result); }; diff --git a/qpid/cpp/src/qpid/client/Handle.h b/qpid/cpp/src/qpid/client/Handle.h index 4fd82b7646..d8b822d0f9 100644 --- a/qpid/cpp/src/qpid/client/Handle.h +++ b/qpid/cpp/src/qpid/client/Handle.h @@ -22,6 +22,8 @@ * */ +#include "qpid/client/ClientImportExport.h" + namespace qpid { namespace client { @@ -34,23 +36,23 @@ template <class T> class HandlePrivate; */ template <class T> class Handle { public: - ~Handle(); - Handle(const Handle&); - Handle& operator=(const Handle&); + QPID_CLIENT_EXTERN ~Handle(); + QPID_CLIENT_EXTERN Handle(const Handle&); + QPID_CLIENT_EXTERN Handle& operator=(const Handle&); /**@return true if handle is valid, i.e. not null. */ - bool isValid() const { return impl; } + QPID_CLIENT_EXTERN bool isValid() const { return impl; } /**@return true if handle is null. It is an error to call any function on a null handle. */ - bool isNull() const { return !impl; } + QPID_CLIENT_EXTERN bool isNull() const { return !impl; } - operator bool() const { return impl; } - bool operator !() const { return impl; } + QPID_CLIENT_EXTERN operator bool() const { return impl; } + QPID_CLIENT_EXTERN bool operator !() const { return impl; } - void swap(Handle<T>&); + QPID_CLIENT_EXTERN void swap(Handle<T>&); protected: - Handle(T* =0); + QPID_CLIENT_EXTERN Handle(T* =0); T* impl; friend class HandlePrivate<T>; diff --git a/qpid/cpp/src/qpid/client/LocalQueue.h b/qpid/cpp/src/qpid/client/LocalQueue.h index 30ea00612d..5b739d4303 100644 --- a/qpid/cpp/src/qpid/client/LocalQueue.h +++ b/qpid/cpp/src/qpid/client/LocalQueue.h @@ -22,6 +22,7 @@ * */ +#include "ClientImportExport.h" #include "qpid/client/Message.h" #include "qpid/client/Subscription.h" #include "qpid/client/Demux.h" @@ -75,16 +76,16 @@ class LocalQueue { * * LocalQueue is an alternative to implementing a MessageListener. */ - LocalQueue(); + QPID_CLIENT_EXTERN LocalQueue(); - ~LocalQueue(); + QPID_CLIENT_EXTERN ~LocalQueue(); /** Wait up to timeout for the next message from the local queue. *@param result Set to the message from the queue. *@param timeout wait up this timeout for a message to appear. *@return true if result was set, false if queue was empty after timeout. */ - bool get(Message& result, sys::Duration timeout=0); + QPID_CLIENT_EXTERN bool get(Message& result, sys::Duration timeout=0); /** Get the next message off the local queue, or wait up to the timeout * for message from the broker queue. @@ -92,16 +93,16 @@ class LocalQueue { *@return message from the queue. *@throw ClosedException if subscription is closed or timeout exceeded. */ - Message get(sys::Duration timeout=sys::TIME_INFINITE); + QPID_CLIENT_EXTERN Message get(sys::Duration timeout=sys::TIME_INFINITE); /** Synonym for get() */ - Message pop(sys::Duration timeout=sys::TIME_INFINITE); + QPID_CLIENT_EXTERN Message pop(sys::Duration timeout=sys::TIME_INFINITE); /** Return true if local queue is empty. */ - bool empty() const; + QPID_CLIENT_EXTERN bool empty() const; /** Number of messages on the local queue */ - size_t size() const; + QPID_CLIENT_EXTERN size_t size() const; private: Demux::QueuePtr queue; diff --git a/qpid/cpp/src/qpid/client/Message.h b/qpid/cpp/src/qpid/client/Message.h index 3f932efd8b..235e20f97d 100644 --- a/qpid/cpp/src/qpid/client/Message.h +++ b/qpid/cpp/src/qpid/client/Message.h @@ -25,6 +25,7 @@ #include "qpid/client/Session.h" #include "qpid/framing/MessageTransferBody.h" #include "qpid/framing/TransferContent.h" +#include "qpid/client/ClientImportExport.h" namespace qpid { namespace client { @@ -111,7 +112,7 @@ public: *@param data Data for the message body. *@param routingKey Passed to the exchange that routes the message. */ - Message(const std::string& data=std::string(), + QPID_CLIENT_EXTERN Message(const std::string& data=std::string(), const std::string& routingKey=std::string()); /** The destination of messages sent to the broker is the exchange @@ -119,26 +120,26 @@ public: * the delivery tag identifyig the local subscription (often this * is the name of the subscribed queue.) */ - std::string getDestination() const; + QPID_CLIENT_EXTERN std::string getDestination() const; /** Check the redelivered flag. */ - bool isRedelivered() const; + QPID_CLIENT_EXTERN bool isRedelivered() const; /** Set the redelivered flag. */ - void setRedelivered(bool redelivered); + QPID_CLIENT_EXTERN void setRedelivered(bool redelivered); /** Get a modifyable reference to the message headers. */ - framing::FieldTable& getHeaders(); + QPID_CLIENT_EXTERN framing::FieldTable& getHeaders(); /** Get a non-modifyable reference to the message headers. */ - const framing::FieldTable& getHeaders() const; + QPID_CLIENT_EXTERN const framing::FieldTable& getHeaders() const; ///@internal - const framing::MessageTransferBody& getMethod() const; + QPID_CLIENT_EXTERN const framing::MessageTransferBody& getMethod() const; ///@internal - const framing::SequenceNumber& getId() const; + QPID_CLIENT_EXTERN const framing::SequenceNumber& getId() const; /**@internal for incoming messages */ - Message(const framing::FrameSet& frameset); + QPID_CLIENT_EXTERN Message(const framing::FrameSet& frameset); private: //method and id are only set for received messages: diff --git a/qpid/cpp/src/qpid/client/MessageListener.h b/qpid/cpp/src/qpid/client/MessageListener.h index 75aad6521b..b86aa10c54 100644 --- a/qpid/cpp/src/qpid/client/MessageListener.h +++ b/qpid/cpp/src/qpid/client/MessageListener.h @@ -19,6 +19,7 @@ * */ #include <string> +#include "qpid/client/ClientImportExport.h" #ifndef _MessageListener_ #define _MessageListener_ @@ -85,7 +86,7 @@ namespace client { class MessageListener{ public: - virtual ~MessageListener(); + QPID_CLIENT_EXTERN virtual ~MessageListener(); /** Called for each message arriving from the broker. Override * in your own subclass to process messages. diff --git a/qpid/cpp/src/qpid/client/MessageReplayTracker.h b/qpid/cpp/src/qpid/client/MessageReplayTracker.h index 45b16fb704..280cbae4a5 100644 --- a/qpid/cpp/src/qpid/client/MessageReplayTracker.h +++ b/qpid/cpp/src/qpid/client/MessageReplayTracker.h @@ -23,7 +23,7 @@ */ #include "AsyncSession.h" #include "Message.h" - +#include "qpid/client/ClientImportExport.h" #include <list> #include <string> @@ -37,13 +37,13 @@ namespace client { class MessageReplayTracker { public: - MessageReplayTracker(uint flushInterval); - void send(const Message& message, const std::string& destination = ""); - void init(AsyncSession session); - void replay(AsyncSession session); - void setFlushInterval(uint interval); - uint getFlushInterval(); - void checkCompletion(); + QPID_CLIENT_EXTERN MessageReplayTracker(uint flushInterval); + QPID_CLIENT_EXTERN void send(const Message& message, const std::string& destination = ""); + QPID_CLIENT_EXTERN void init(AsyncSession session); + QPID_CLIENT_EXTERN void replay(AsyncSession session); + QPID_CLIENT_EXTERN void setFlushInterval(uint interval); + QPID_CLIENT_EXTERN uint getFlushInterval(); + QPID_CLIENT_EXTERN void checkCompletion(); template <class F> void foreach(F& f) { for (std::list<ReplayRecord>::const_iterator i = buffer.begin(); i != buffer.end(); i++) { diff --git a/qpid/cpp/src/qpid/client/QueueOptions.h b/qpid/cpp/src/qpid/client/QueueOptions.h index d159378198..57d9487217 100644 --- a/qpid/cpp/src/qpid/client/QueueOptions.h +++ b/qpid/cpp/src/qpid/client/QueueOptions.h @@ -18,6 +18,8 @@ * under the License. * */ + +#include "ClientImportExport.h" #include "qpid/framing/FieldTable.h" #ifndef _QueueOptions_ @@ -36,8 +38,8 @@ enum QueueOrderingPolicy {FIFO, LVQ, LVQ_NO_BROWSE}; class QueueOptions: public framing::FieldTable { public: - QueueOptions(); - virtual ~QueueOptions(); + QPID_CLIENT_EXTERN QueueOptions(); + QPID_CLIENT_EXTERN virtual ~QueueOptions(); /** * Sets the queue sizing policy @@ -51,58 +53,58 @@ class QueueOptions: public framing::FieldTable * @param maxSize Set the max number of bytes for the sizing policies * @param setMaxCount Set the max number of messages for the sizing policies */ - void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount ); + QPID_CLIENT_EXTERN void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount ); /** * Enables the persisting of a queue to the store module when a cluster fails down to it's last * node. Does so optimistically. Will start persisting when cluster count >1 again. */ - void setPersistLastNode(); + QPID_CLIENT_EXTERN void setPersistLastNode(); /** * Sets the odering policy on the Queue, default ordering is FIFO. */ - void setOrdering(QueueOrderingPolicy op); + QPID_CLIENT_EXTERN void setOrdering(QueueOrderingPolicy op); /** * Use broker defualt sizing ploicy */ - void clearSizePolicy(); + QPID_CLIENT_EXTERN void clearSizePolicy(); /** * Clear Persist Last Node Policy */ - void clearPersistLastNode(); + QPID_CLIENT_EXTERN void clearPersistLastNode(); /** * get the key used match LVQ in args for message transfer */ - void getLVQKey(std::string& key); + QPID_CLIENT_EXTERN void getLVQKey(std::string& key); /** * Use default odering policy */ - void clearOrdering(); + QPID_CLIENT_EXTERN void clearOrdering(); /** * Turns on event generation for this queue (either enqueue only * or for enqueue and dequeue events); the events can then be * processed by a regsitered broker plugin. */ - void enableQueueEvents(bool enqueueOnly); + QPID_CLIENT_EXTERN void enableQueueEvents(bool enqueueOnly); - static const std::string strMaxCountKey; - static const std::string strMaxSizeKey; - static const std::string strTypeKey; - static const std::string strREJECT; - static const std::string strFLOW_TO_DISK; - static const std::string strRING; - static const std::string strRING_STRICT; - static const std::string strLastValueQueue; - static const std::string strPersistLastNode; - static const std::string strLVQMatchProperty; - static const std::string strLastValueQueueNoBrowse; - static const std::string strQueueEventMode; + static QPID_CLIENT_EXTERN const std::string strMaxCountKey; + static QPID_CLIENT_EXTERN const std::string strMaxSizeKey; + static QPID_CLIENT_EXTERN const std::string strTypeKey; + static QPID_CLIENT_EXTERN const std::string strREJECT; + static QPID_CLIENT_EXTERN const std::string strFLOW_TO_DISK; + static QPID_CLIENT_EXTERN const std::string strRING; + static QPID_CLIENT_EXTERN const std::string strRING_STRICT; + static QPID_CLIENT_EXTERN const std::string strLastValueQueue; + static QPID_CLIENT_EXTERN const std::string strPersistLastNode; + static QPID_CLIENT_EXTERN const std::string strLVQMatchProperty; + static QPID_CLIENT_EXTERN const std::string strLastValueQueueNoBrowse; + static QPID_CLIENT_EXTERN const std::string strQueueEventMode; }; } diff --git a/qpid/cpp/src/qpid/client/SessionBase_0_10.h b/qpid/cpp/src/qpid/client/SessionBase_0_10.h index 091c977053..3ae21936f6 100644 --- a/qpid/cpp/src/qpid/client/SessionBase_0_10.h +++ b/qpid/cpp/src/qpid/client/SessionBase_0_10.h @@ -33,6 +33,7 @@ #include "qpid/client/SessionImpl.h" #include "qpid/client/TypedResult.h" #include "qpid/shared_ptr.h" +#include "qpid/client/ClientImportExport.h" #include <string> namespace qpid { @@ -65,19 +66,19 @@ class SessionBase_0_10 { typedef framing::TransferContent DefaultContent; ///@internal - SessionBase_0_10(); - ~SessionBase_0_10(); + QPID_CLIENT_EXTERN SessionBase_0_10(); + QPID_CLIENT_EXTERN ~SessionBase_0_10(); /** Get the next message frame-set from the session. */ - framing::FrameSet::shared_ptr get(); + QPID_CLIENT_EXTERN framing::FrameSet::shared_ptr get(); /** Get the session ID */ - SessionId getId() const; + QPID_CLIENT_EXTERN SessionId getId() const; /** Close the session. * A session is automatically closed when all handles to it are destroyed. */ - void close(); + QPID_CLIENT_EXTERN void close(); /** * Synchronize the session: sync() waits until all commands issued @@ -88,25 +89,25 @@ class SessionBase_0_10 { * AsyncSession::executionSync() directly in the unusual event * that you want to do an asynchronous sync. */ - void sync(); + QPID_CLIENT_EXTERN void sync(); /** Set the timeout for this session. */ - uint32_t timeout(uint32_t seconds); + QPID_CLIENT_EXTERN uint32_t timeout(uint32_t seconds); /** Suspend the session - detach it from its connection */ - void suspend(); + QPID_CLIENT_EXTERN void suspend(); /** Resume a suspended session with a new connection */ - void resume(Connection); + QPID_CLIENT_EXTERN void resume(Connection); /** Get the channel associated with this session */ - uint16_t getChannel() const; + QPID_CLIENT_EXTERN uint16_t getChannel() const; - Execution& getExecution(); - void flush(); - void markCompleted(const framing::SequenceSet& ids, bool notifyPeer); - void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer); - void sendCompletion(); + QPID_CLIENT_EXTERN Execution& getExecution(); + QPID_CLIENT_EXTERN void flush(); + QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceSet& ids, bool notifyPeer); + QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer); + QPID_CLIENT_EXTERN void sendCompletion(); protected: boost::shared_ptr<SessionImpl> impl; diff --git a/qpid/cpp/src/qpid/client/SessionImpl.cpp b/qpid/cpp/src/qpid/client/SessionImpl.cpp index ee542a9cf8..5df376efa0 100644 --- a/qpid/cpp/src/qpid/client/SessionImpl.cpp +++ b/qpid/cpp/src/qpid/client/SessionImpl.cpp @@ -512,6 +512,7 @@ void SessionImpl::detach(const std::string& _name) if (id.getName() != _name) throw InternalErrorException("Incorrect session name"); setState(DETACHED); QPID_LOG(info, "Session detached by peer: " << id); + proxy.detached(_name, DETACH_CODE_NORMAL); } void SessionImpl::detached(const std::string& _name, uint8_t _code) { @@ -744,7 +745,8 @@ void SessionImpl::assertOpen() const void SessionImpl::handleClosed() { - demux.close(exceptionHolder.empty() ? new ClosedException() : exceptionHolder); + demux.close(exceptionHolder.empty() ? + sys::ExceptionHolder(new ClosedException()) : exceptionHolder); results.close(); } diff --git a/qpid/cpp/src/qpid/client/SslConnector.cpp b/qpid/cpp/src/qpid/client/SslConnector.cpp index 75c3f5677e..a4298dd4ca 100644 --- a/qpid/cpp/src/qpid/client/SslConnector.cpp +++ b/qpid/cpp/src/qpid/client/SslConnector.cpp @@ -221,6 +221,7 @@ bool SslConnector::closeInternal() { bool ret = !closed; if (!closed) { closed = true; + aio->queueForDeletion(); poller->shutdown(); } if (!joined && receiver.id() != Thread::current().id()) { @@ -386,7 +387,6 @@ void SslConnector::run(){ aio->start(poller); d.run(); - aio->queueForDeletion(); socket.close(); } catch (const std::exception& e) { QPID_LOG(error, e.what()); diff --git a/qpid/cpp/src/qpid/client/Subscription.h b/qpid/cpp/src/qpid/client/Subscription.h index 47bb5d42a5..43c6100254 100644 --- a/qpid/cpp/src/qpid/client/Subscription.h +++ b/qpid/cpp/src/qpid/client/Subscription.h @@ -26,6 +26,7 @@ #include "qpid/client/SubscriptionSettings.h" #include "qpid/client/Handle.h" #include "qpid/client/Message.h" +#include "qpid/client/ClientImportExport.h" namespace qpid { namespace client { @@ -39,74 +40,74 @@ class SubscriptionManager; */ class Subscription : public Handle<SubscriptionImpl> { public: - Subscription(SubscriptionImpl* si=0) : Handle<SubscriptionImpl>(si) {} + QPID_CLIENT_EXTERN Subscription(SubscriptionImpl* si=0) : Handle<SubscriptionImpl>(si) {} - /** The name of the subsctription, used as the "destination" for messages from the broker. + /** The name of the subscription, used as the "destination" for messages from the broker. * Usually the same as the queue name but can be set differently. */ - std::string getName() const; + QPID_CLIENT_EXTERN std::string getName() const; /** Name of the queue this subscription subscribes to */ - std::string getQueue() const; + QPID_CLIENT_EXTERN std::string getQueue() const; /** Get the flow control and acknowledgement settings for this subscription */ - const SubscriptionSettings& getSettings() const; + QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const; /** Set the flow control parameters */ - void setFlowControl(const FlowControl&); + QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&); /** Automatically acknowledge (acquire and accept) batches of n messages. * You can disable auto-acknowledgement by setting n=0, and use acquire() and accept() * to manually acquire and accept messages. */ - void setAutoAck(unsigned int n); + QPID_CLIENT_EXTERN void setAutoAck(unsigned int n); /** Get the set of ID's for messages received by this subscription but not yet acquired. * This will always be empty if getSettings().acquireMode=ACQUIRE_MODE_PRE_ACQUIRED */ - SequenceSet getUnacquired() const; + QPID_CLIENT_EXTERN SequenceSet getUnacquired() const; /** Get the set of ID's for messages received by this subscription but not yet accepted. */ - SequenceSet getUnaccepted() const; + QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const; /** Acquire messageIds and remove them from the unacquired set. * oAdd them to the unaccepted set if getSettings().acceptMode == ACCEPT_MODE_EXPLICIT. */ - void acquire(const SequenceSet& messageIds); + QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds); /** Accept messageIds and remove them from the unaccepted set. *@pre messageIds is a subset of getUnaccepted() */ - void accept(const SequenceSet& messageIds); + QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds); /** Release messageIds and remove them from the unaccepted set. *@pre messageIds is a subset of getUnaccepted() */ - void release(const SequenceSet& messageIds); + QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds); /* Acquire a single message */ - void acquire(const Message& m) { acquire(SequenceSet(m.getId())); } + QPID_CLIENT_EXTERN void acquire(const Message& m) { acquire(SequenceSet(m.getId())); } /* Accept a single message */ - void accept(const Message& m) { accept(SequenceSet(m.getId())); } + QPID_CLIENT_EXTERN void accept(const Message& m) { accept(SequenceSet(m.getId())); } /* Release a single message */ - void release(const Message& m) { release(SequenceSet(m.getId())); } + QPID_CLIENT_EXTERN void release(const Message& m) { release(SequenceSet(m.getId())); } /** Get the session associated with this subscription */ - Session getSession() const; + QPID_CLIENT_EXTERN Session getSession() const; /** Get the subscription manager associated with this subscription */ - SubscriptionManager& getSubscriptionManager() const; + QPID_CLIENT_EXTERN SubscriptionManager& getSubscriptionManager() const; /** Cancel the subscription. */ - void cancel(); + QPID_CLIENT_EXTERN void cancel(); /** Grant the specified amount of message credit */ - void grantMessageCredit(uint32_t); + QPID_CLIENT_EXTERN void grantMessageCredit(uint32_t); /** Grant the specified amount of byte credit */ - void grantByteCredit(uint32_t); + QPID_CLIENT_EXTERN void grantByteCredit(uint32_t); friend class SubscriptionManager; }; diff --git a/qpid/cpp/src/qpid/client/SubscriptionImpl.h b/qpid/cpp/src/qpid/client/SubscriptionImpl.h index 74fbacb951..e2b970ce05 100644 --- a/qpid/cpp/src/qpid/client/SubscriptionImpl.h +++ b/qpid/cpp/src/qpid/client/SubscriptionImpl.h @@ -30,6 +30,7 @@ #include "qpid/framing/SequenceSet.h" #include "qpid/sys/Mutex.h" #include "qpid/RefCounted.h" +#include "qpid/client/ClientImportExport.h" #include <memory> namespace qpid { @@ -39,62 +40,62 @@ class SubscriptionManager; class SubscriptionImpl : public RefCounted, public MessageListener { public: - SubscriptionImpl(SubscriptionManager&, const std::string& queue, + QPID_CLIENT_EXTERN SubscriptionImpl(SubscriptionManager&, const std::string& queue, const SubscriptionSettings&, const std::string& name, MessageListener* =0); /** The name of the subsctription, used as the "destination" for messages from the broker. * Usually the same as the queue name but can be set differently. */ - std::string getName() const; + QPID_CLIENT_EXTERN std::string getName() const; /** Name of the queue this subscription subscribes to */ - std::string getQueue() const; + QPID_CLIENT_EXTERN std::string getQueue() const; /** Get the flow control and acknowledgement settings for this subscription */ - const SubscriptionSettings& getSettings() const; + QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const; /** Set the flow control parameters */ - void setFlowControl(const FlowControl&); + QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&); /** Automatically acknowledge (acquire and accept) batches of n messages. * You can disable auto-acknowledgement by setting n=0, and use acquire() and accept() * to manually acquire and accept messages. */ - void setAutoAck(size_t n); + QPID_CLIENT_EXTERN void setAutoAck(size_t n); /** Get the set of ID's for messages received by this subscription but not yet acquired. * This will always be empty if acquireMode=ACQUIRE_MODE_PRE_ACQUIRED */ - SequenceSet getUnacquired() const; + QPID_CLIENT_EXTERN SequenceSet getUnacquired() const; /** Get the set of ID's for messages acquired by this subscription but not yet accepted. */ - SequenceSet getUnaccepted() const; + QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const; /** Acquire messageIds and remove them from the un-acquired set for the session. */ - void acquire(const SequenceSet& messageIds); + QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds); /** Accept messageIds and remove them from the un-accepted set for the session. */ - void accept(const SequenceSet& messageIds); + QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds); /** Release messageIds and remove them from the un-accepted set for the session. */ - void release(const SequenceSet& messageIds); + QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds); /** Get the session associated with this subscription */ - Session getSession() const; + QPID_CLIENT_EXTERN Session getSession() const; /** Get the subscription manager associated with this subscription */ - SubscriptionManager& getSubscriptionManager() const; + QPID_CLIENT_EXTERN SubscriptionManager& getSubscriptionManager() const; /** Send subscription request and issue appropriate flow control commands. */ - void subscribe(); + QPID_CLIENT_EXTERN void subscribe(); /** Cancel the subscription. */ - void cancel(); + QPID_CLIENT_EXTERN void cancel(); /** Grant specified credit for this subscription **/ - void grantCredit(framing::message::CreditUnit unit, uint32_t value); + QPID_CLIENT_EXTERN void grantCredit(framing::message::CreditUnit unit, uint32_t value); - void received(Message&); + QPID_CLIENT_EXTERN void received(Message&); /** * Set up demux diversion for messages sent to this subscription @@ -104,7 +105,7 @@ class SubscriptionImpl : public RefCounted, public MessageListener { * Cancel any demux diversion that may have been setup for this * subscription */ - void cancelDiversion(); + QPID_CLIENT_EXTERN void cancelDiversion(); private: diff --git a/qpid/cpp/src/qpid/client/SubscriptionManager.h b/qpid/cpp/src/qpid/client/SubscriptionManager.h index 6b45092931..91ad2b6d56 100644 --- a/qpid/cpp/src/qpid/client/SubscriptionManager.h +++ b/qpid/cpp/src/qpid/client/SubscriptionManager.h @@ -30,6 +30,7 @@ #include <qpid/client/LocalQueue.h> #include <qpid/client/Subscription.h> #include <qpid/sys/Runnable.h> +#include <qpid/client/ClientImportExport.h> #include <set> #include <sstream> @@ -97,7 +98,7 @@ class SubscriptionManager : public sys::Runnable { public: /** Create a new SubscriptionManager associated with a session */ - SubscriptionManager(const Session& session); + QPID_CLIENT_EXTERN SubscriptionManager(const Session& session); /** * Subscribe a MessagesListener to receive messages from queue. @@ -110,7 +111,7 @@ class SubscriptionManager : public sys::Runnable *@param settings settings for the subscription. *@param name unique destination name for the subscription, defaults to queue name. */ - Subscription subscribe(MessageListener& listener, + QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener, const std::string& queue, const SubscriptionSettings& settings, const std::string& name=std::string()); @@ -125,7 +126,7 @@ class SubscriptionManager : public sys::Runnable *@param name unique destination name for the subscription, defaults to queue name. * If not specified, the queue name is used. */ - Subscription subscribe(LocalQueue& localQueue, + QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue, const std::string& queue, const SubscriptionSettings& settings, const std::string& name=std::string()); @@ -141,7 +142,7 @@ class SubscriptionManager : public sys::Runnable *@param name unique destination name for the subscription, defaults to queue name. * If not specified, the queue name is used. */ - Subscription subscribe(MessageListener& listener, + QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener, const std::string& queue, const std::string& name=std::string()); @@ -154,7 +155,7 @@ class SubscriptionManager : public sys::Runnable *@param name unique destination name for the subscription, defaults to queue name. * If not specified, the queue name is used. */ - Subscription subscribe(LocalQueue& localQueue, + QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue, const std::string& queue, const std::string& name=std::string()); @@ -164,53 +165,53 @@ class SubscriptionManager : public sys::Runnable *@param timeout wait up this timeout for a message to appear. *@return true if result was set, false if no message available after timeout. */ - bool get(Message& result, const std::string& queue, sys::Duration timeout=0); + QPID_CLIENT_EXTERN bool get(Message& result, const std::string& queue, sys::Duration timeout=0); /** Get a single message from a queue. *@param timeout wait up this timeout for a message to appear. *@return message from the queue. *@throw Exception if the timeout is exceeded. */ - Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE); + QPID_CLIENT_EXTERN Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE); /** Get a subscription by name. *@throw Exception if not found. */ - Subscription getSubscription(const std::string& name) const; + QPID_CLIENT_EXTERN Subscription getSubscription(const std::string& name) const; /** Cancel a subscription. See also: Subscription.cancel() */ - void cancel(const std::string& name); + QPID_CLIENT_EXTERN void cancel(const std::string& name); /** Deliver messages in the current thread until stop() is called. * Only one thread may be running in a SubscriptionManager at a time. * @see run */ - void run(); + QPID_CLIENT_EXTERN void run(); /** Start a new thread to deliver messages. * Only one thread may be running in a SubscriptionManager at a time. * @see start */ - void start(); + QPID_CLIENT_EXTERN void start(); /** * Wait for the thread started by a call to start() to complete. */ - void wait(); + QPID_CLIENT_EXTERN void wait(); /** If set true, run() will stop when all subscriptions * are cancelled. If false, run will only stop when stop() * is called. True by default. */ - void setAutoStop(bool set=true); + QPID_CLIENT_EXTERN void setAutoStop(bool set=true); /** Stop delivery. Causes run() to return, or the thread started with start() to exit. */ - void stop(); + QPID_CLIENT_EXTERN void stop(); static const uint32_t UNLIMITED=0xFFFFFFFF; /** Set the flow control for a subscription. */ - void setFlowControl(const std::string& name, const FlowControl& flow); + QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, const FlowControl& flow); /** Set the flow control for a subscription. *@param name: name of the subscription. @@ -218,22 +219,22 @@ class SubscriptionManager : public sys::Runnable *@param bytes: byte credit. *@param window: if true use window-based flow control. */ - void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true); + QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true); /** Set the default settings for subscribe() calls that don't * include a SubscriptionSettings parameter. */ - void setDefaultSettings(const SubscriptionSettings& s) { defaultSettings = s; } + QPID_CLIENT_EXTERN void setDefaultSettings(const SubscriptionSettings& s) { defaultSettings = s; } /** Get the default settings for subscribe() calls that don't * include a SubscriptionSettings parameter. */ - const SubscriptionSettings& getDefaultSettings() const { return defaultSettings; } + QPID_CLIENT_EXTERN const SubscriptionSettings& getDefaultSettings() const { return defaultSettings; } /** Get the default settings for subscribe() calls that don't * include a SubscriptionSettings parameter. */ - SubscriptionSettings& getDefaultSettings() { return defaultSettings; } + QPID_CLIENT_EXTERN SubscriptionSettings& getDefaultSettings() { return defaultSettings; } /** * Set the default flow control settings for subscribe() calls @@ -243,7 +244,7 @@ class SubscriptionManager : public sys::Runnable *@param bytes: byte credit. *@param window: if true use window-based flow control. */ - void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true) { + QPID_CLIENT_EXTERN void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true) { defaultSettings.flowControl = FlowControl(messages, bytes, window); } @@ -251,16 +252,16 @@ class SubscriptionManager : public sys::Runnable *Set the default accept-mode for subscribe() calls that don't *include a SubscriptionSettings parameter. */ - void setAcceptMode(AcceptMode mode) { defaultSettings.acceptMode = mode; } + QPID_CLIENT_EXTERN void setAcceptMode(AcceptMode mode) { defaultSettings.acceptMode = mode; } /** * Set the default acquire-mode subscribe()s that don't specify SubscriptionSettings. */ - void setAcquireMode(AcquireMode mode) { defaultSettings.acquireMode = mode; } + QPID_CLIENT_EXTERN void setAcquireMode(AcquireMode mode) { defaultSettings.acquireMode = mode; } - void registerFailoverHandler ( boost::function<void ()> fh ); + QPID_CLIENT_EXTERN void registerFailoverHandler ( boost::function<void ()> fh ); - Session getSession() const; + QPID_CLIENT_EXTERN Session getSession() const; private: mutable sys::Mutex lock; diff --git a/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp new file mode 100644 index 0000000000..58956609a4 --- /dev/null +++ b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp @@ -0,0 +1,139 @@ +/* + * + * 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/client/SaslFactory.h" +#include "qpid/client/ConnectionSettings.h" + +#include "qpid/Exception.h" +#include "qpid/framing/reply_exceptions.h" +#include "qpid/sys/SecurityLayer.h" +#include "qpid/log/Statement.h" + +#include "boost/tokenizer.hpp" + +namespace qpid { +namespace client { + +using qpid::sys::SecurityLayer; +using qpid::framing::InternalErrorException; + +class WindowsSasl : public Sasl +{ + public: + WindowsSasl(const ConnectionSettings&); + ~WindowsSasl(); + std::string start(const std::string& mechanisms); + std::string step(const std::string& challenge); + std::string getMechanism(); + std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize); + private: + ConnectionSettings settings; + std::string mechanism; +}; + +qpid::sys::Mutex SaslFactory::lock; +std::auto_ptr<SaslFactory> SaslFactory::instance; + +SaslFactory::SaslFactory() +{ +} + +SaslFactory::~SaslFactory() +{ +} + +SaslFactory& SaslFactory::getInstance() +{ + qpid::sys::Mutex::ScopedLock l(lock); + if (!instance.get()) { + instance = std::auto_ptr<SaslFactory>(new SaslFactory()); + } + return *instance; +} + +std::auto_ptr<Sasl> SaslFactory::create(const ConnectionSettings& settings) +{ + std::auto_ptr<Sasl> sasl(new WindowsSasl(settings)); + return sasl; +} + +namespace { + const std::string ANONYMOUS = "ANONYMOUS"; + const std::string PLAIN = "PLAIN"; +} + +WindowsSasl::WindowsSasl(const ConnectionSettings& s) + : settings(s) +{ +} + +WindowsSasl::~WindowsSasl() +{ +} + +std::string WindowsSasl::start(const std::string& mechanisms) +{ + QPID_LOG(debug, "WindowsSasl::start(" << mechanisms << ")"); + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(" "); + bool havePlain = false; + bool haveAnon = false; + tokenizer mechs(mechanisms, sep); + for (tokenizer::iterator mech = mechs.begin(); + mech != mechs.end(); + ++mech) { + if (*mech == ANONYMOUS) + haveAnon = true; + else if (*mech == PLAIN) + havePlain = true; + } + if (!haveAnon && !havePlain) + throw InternalErrorException(QPID_MSG("Sasl error: no common mechanism")); + + std::string resp = ""; + if (havePlain) { + mechanism = PLAIN; + resp = ((char)0) + settings.username + ((char)0) + settings.password; + } + else { + mechanism = ANONYMOUS; + } + return resp; +} + +std::string WindowsSasl::step(const std::string& challenge) +{ + // Shouldn't get this for PLAIN... + throw InternalErrorException(QPID_MSG("Sasl step error")); +} + +std::string WindowsSasl::getMechanism() +{ + return mechanism; +} + +std::auto_ptr<SecurityLayer> WindowsSasl::getSecurityLayer(uint16_t maxFrameSize) +{ + return std::auto_ptr<SecurityLayer>(0); +} + +}} // namespace qpid::client diff --git a/qpid/cpp/src/qpid/cluster/Cluster.cpp b/qpid/cpp/src/qpid/cluster/Cluster.cpp index 6221b0054c..f8e412f1e6 100644 --- a/qpid/cpp/src/qpid/cluster/Cluster.cpp +++ b/qpid/cpp/src/qpid/cluster/Cluster.cpp @@ -21,7 +21,9 @@ #include "Connection.h" #include "UpdateClient.h" #include "FailoverExchange.h" +#include "UpdateExchange.h" +#include "qpid/assert.h" #include "qmf/org/apache/qpid/cluster/ArgsClusterStopClusterNode.h" #include "qmf/org/apache/qpid/cluster/Package.h" #include "qpid/broker/Broker.h" @@ -91,9 +93,10 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) : cpg(*this), name(settings.name), myUrl(settings.url.empty() ? Url() : Url(settings.url)), - myId(cpg.self()), + self(cpg.self()), readMax(settings.readMax), writeEstimate(settings.writeEstimate), + expiryPolicy(new ExpiryPolicy(mcast, self, broker.getTimer())), mcast(cpg, poller, boost::bind(&Cluster::leave, this)), dispatcher(cpg, poller, boost::bind(&Cluster::leave, this)), deliverEventQueue(boost::bind(&Cluster::deliveredEvent, this, _1), @@ -104,15 +107,12 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) : boost::bind(&Cluster::leave, this), "Error delivering frames", poller), - connections(*this), - decoder(boost::bind(&PollableFrameQueue::push, &deliverFrameQueue, _1), connections), - expiryPolicy(new ExpiryPolicy(boost::bind(&Cluster::isLeader, this), mcast, myId, broker.getTimer())), - frameId(0), initialized(false), + decoder(boost::bind(&Cluster::deliverFrame, this, _1)), + discarding(true), state(INIT), lastSize(0), - lastBroker(false), - sequence(0) + lastBroker(false) { mAgent = ManagementAgent::Singleton::getInstance(); if (mAgent != 0){ @@ -122,7 +122,13 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) : mgmtObject->set_status("JOINING"); } + // Failover exchange provides membership updates to clients. failoverExchange.reset(new FailoverExchange(this)); + broker.getExchanges().registerExchange(failoverExchange); + + // Update exchange is used during updates to replicate messages without modifying delivery-properties.exchange. + broker.getExchanges().registerExchange(boost::shared_ptr<broker::Exchange>(new UpdateExchange(this))); + if (settings.quorum) quorum.init(); cpg.join(name); // pump the CPG dispatch manually till we get initialized. @@ -149,21 +155,21 @@ void Cluster::initialize() { // Called in connection thread to insert a client connection. void Cluster::addLocalConnection(const boost::intrusive_ptr<Connection>& c) { - Lock l(lock); - connections.insert(c); + localConnections.insert(c); } // Called in connection thread to insert an updated shadow connection. void Cluster::addShadowConnection(const boost::intrusive_ptr<Connection>& c) { - Lock l(lock); - assert(state <= UPDATEE); // Only during update. - connections.insert(c); + // Safe to use connections here because we're pre-catchup, either + // discarding or stalled, so deliveredFrame is not processing any + // connection events. + assert(discarding); + connections.insert(ConnectionMap::value_type(c->getId(), c)); } +// Called by Connection::deliverClose() in deliverFrameQueue thread. void Cluster::erase(const ConnectionId& id) { - // Called only by Connection::deliverClose in deliver thread, no need to lock. connections.erase(id); - decoder.erase(id); } std::vector<string> Cluster::getIds() const { @@ -193,7 +199,6 @@ void Cluster::leave(Lock&) { if (state != LEFT) { state = LEFT; QPID_LOG(notice, *this << " leaving cluster " << name); - connections.clear(); try { broker.shutdown(); } catch (const std::exception& e) { QPID_LOG(critical, *this << " error during broker shutdown: " << e.what()); @@ -213,52 +218,88 @@ void Cluster::deliver( MemberId from(nodeid, pid); framing::Buffer buf(static_cast<char*>(msg), msg_len); Event e(Event::decodeCopy(from, buf)); - e.setSequence(sequence++); - if (from == myId) // Record self-deliveries for flow control. + if (from == self) // Record self-deliveries for flow control. mcast.selfDeliver(e); - deliver(e); + deliverEvent(e); } -void Cluster::deliver(const Event& e) { - if (state == LEFT) return; - QPID_LATENCY_INIT(e); +void Cluster::deliverEvent(const Event& e) { deliverEventQueue.push(e); } -// Handler for deliverEventQueue +void Cluster::deliverFrame(const EventFrame& e) { + deliverFrameQueue.push(e); +} + +// Handler for deliverEventQueue. +// This thread decodes frames from events. void Cluster::deliveredEvent(const Event& e) { - QPID_LATENCY_RECORD("delivered event queue", e); - Buffer buf(const_cast<char*>(e.getData()), e.getSize()); - if (e.getType() == CONTROL) { - AMQFrame frame; - while (frame.decode(buf)) - deliverFrameQueue.push(EventFrame(e, frame)); + QPID_LOG(trace, *this << " DLVR: " << e); + if (e.isCluster()) { + EventFrame ef(e, e.getFrame()); + // Stop the deliverEventQueue on update offers. + // This preserves the connection decoder fragments for an update. + ClusterUpdateOfferBody* offer = dynamic_cast<ClusterUpdateOfferBody*>(ef.frame.getBody()); + if (offer) + deliverEventQueue.stop(); + deliverFrame(ef); } - else if (e.getType() == DATA) - decoder.decode(e, e.getData()); + else if(!discarding) { + if (e.isControl()) + deliverFrame(EventFrame(e, e.getFrame())); + else + decoder.decode(e, e.getData()); +} + else // Discard connection events if discarding is set. + QPID_LOG(trace, *this << " DROP: " << e); } -// Handler for deliverFrameQueue +// Handler for deliverFrameQueue. +// This thread executes the main logic. void Cluster::deliveredFrame(const EventFrame& e) { Mutex::ScopedLock l(lock); - const_cast<AMQFrame&>(e.frame).setClusterId(frameId++); - QPID_LOG(trace, *this << " DLVR: " << e); - QPID_LATENCY_RECORD("delivered frame queue", e.frame); - if (e.isCluster()) { // Cluster control frame + if (e.isCluster()) { + QPID_LOG(trace, *this << " DLVR: " << e); ClusterDispatcher dispatch(*this, e.connectionId.getMember(), l); if (!framing::invoke(dispatch, *e.frame.getBody()).wasHandled()) throw Exception(QPID_MSG("Invalid cluster control")); } - else { // Connection frame. - if (state <= UPDATEE) { - QPID_LOG(trace, *this << " DROP: " << e); - return; - } - boost::intrusive_ptr<Connection> connection = connections.get(e.connectionId); - if (connection) // Ignore frames to closed local connections. + else if (state >= CATCHUP) { + QPID_LOG(trace, *this << " DLVR: " << e); + ConnectionPtr connection = getConnection(e.connectionId, l); + if (connection) connection->deliveredFrame(e); } - QPID_LATENCY_RECORD("processed", e.frame); + else // Drop connection frames while state < CATCHUP + QPID_LOG(trace, *this << " DROP: " << e); +} + +// Called in deliverFrameQueue thread +ConnectionPtr Cluster::getConnection(const ConnectionId& id, Lock&) { + ConnectionPtr cp; + ConnectionMap::iterator i = connections.find(id); + if (i != connections.end()) + cp = i->second; + else { + if(id.getMember() == self) + cp = localConnections.getErase(id); + else { + // New remote connection, create a shadow. + std::ostringstream mgmtId; + mgmtId << id; + cp = new Connection(*this, shadowOut, mgmtId.str(), id); + } + if (cp) + connections.insert(ConnectionMap::value_type(id, cp)); + } + return cp; +} + +Cluster::ConnectionVector Cluster::getConnections(Lock&) { + ConnectionVector result(connections.size()); + std::transform(connections.begin(), connections.end(), result.begin(), + boost::bind(&ConnectionMap::value_type::second, _1)); + return result; } struct AddrList { @@ -306,42 +347,45 @@ void Cluster::configChange ( std::string addresses; for (cpg_address* p = current; p < current+nCurrent; ++p) addresses.append(MemberId(*p).str()); - deliver(Event::control(ClusterConfigChangeBody(ProtocolVersion(), addresses), myId)); + deliverEvent(Event::control(ClusterConfigChangeBody(ProtocolVersion(), addresses), self)); } void Cluster::setReady(Lock&) { state = READY; if (mgmtObject!=0) mgmtObject->set_status("ACTIVE"); mcast.release(); + broker.getQueueEvents().enable(); } void Cluster::configChange(const MemberId&, const std::string& addresses, Lock& l) { bool memberChange = map.configChange(addresses); if (state == LEFT) return; - if (!map.isAlive(myId)) { // Final config change. + if (!map.isAlive(self)) { // Final config change. leave(l); return; } if (state == INIT) { // First configChange if (map.aliveCount() == 1) { - setClusterId(true); + setClusterId(true, l); + discarding = false; setReady(l); - map = ClusterMap(myId, myUrl, true); + map = ClusterMap(self, myUrl, true); memberUpdate(l); QPID_LOG(notice, *this << " first in cluster"); } else { // Joining established group. state = JOINER; QPID_LOG(info, *this << " joining cluster: " << map); - mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), myId); + mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), self); elders = map.getAlive(); - elders.erase(myId); + elders.erase(self); broker.getLinks().setPassive(true); + broker.getQueueEvents().disable(); } - } - else if (state >= READY && memberChange) { + } + else if (state >= CATCHUP && memberChange) { memberUpdate(l); elders = ClusterMap::intersection(elders, map.getAlive()); if (elders.empty()) { @@ -351,13 +395,11 @@ void Cluster::configChange(const MemberId&, const std::string& addresses, Lock& } } -bool Cluster::isLeader() const { return elders.empty(); } - -void Cluster::tryMakeOffer(const MemberId& id, Lock& ) { +void Cluster::makeOffer(const MemberId& id, Lock& ) { if (state == READY && map.isJoiner(id)) { state = OFFER; QPID_LOG(info, *this << " send update-offer to " << id); - mcast.mcastControl(ClusterUpdateOfferBody(ProtocolVersion(), id, clusterId), myId); + mcast.mcastControl(ClusterUpdateOfferBody(ProtocolVersion(), id, clusterId), self); } } @@ -367,88 +409,89 @@ void Cluster::tryMakeOffer(const MemberId& id, Lock& ) { // callbacks will be invoked. // void Cluster::brokerShutdown() { - if (state != LEFT) { - try { cpg.shutdown(); } - catch (const std::exception& e) { - QPID_LOG(error, *this << " shutting down CPG: " << e.what()); - } + try { cpg.shutdown(); } + catch (const std::exception& e) { + QPID_LOG(error, *this << " shutting down CPG: " << e.what()); } delete this; } void Cluster::updateRequest(const MemberId& id, const std::string& url, Lock& l) { map.updateRequest(id, url); - tryMakeOffer(id, l); + makeOffer(id, l); } void Cluster::ready(const MemberId& id, const std::string& url, Lock& l) { if (map.ready(id, Url(url))) memberUpdate(l); - if (state == CATCHUP && id == myId) { + if (state == CATCHUP && id == self) { setReady(l); QPID_LOG(notice, *this << " caught up, active cluster member"); } } void Cluster::updateOffer(const MemberId& updater, uint64_t updateeInt, const Uuid& uuid, Lock& l) { + // NOTE: deliverEventQueue has been stopped at the update offer by + // deliveredEvent in case an update is required. if (state == LEFT) return; MemberId updatee(updateeInt); boost::optional<Url> url = map.updateOffer(updater, updatee); - if (updater == myId) { + if (updater == self) { assert(state == OFFER); - if (url) { // My offer was first. + if (url) // My offer was first. updateStart(updatee, *url, l); - } else { // Another offer was first. + deliverEventQueue.start(); // Don't need to update setReady(l); QPID_LOG(info, *this << " cancelled update offer to " << updatee); - tryMakeOffer(map.firstJoiner(), l); // Maybe make another offer. + makeOffer(map.firstJoiner(), l); // Maybe make another offer. } } - else if (updatee == myId && url) { + else if (updatee == self && url) { assert(state == JOINER); - setClusterId(uuid); + setClusterId(uuid, l); state = UPDATEE; QPID_LOG(info, *this << " receiving update from " << updater); - deliverFrameQueue.stop(); checkUpdateIn(l); } + else + deliverEventQueue.start(); // Don't need to update } -void Cluster::updateStart(const MemberId& updatee, const Url& url, Lock&) { +void Cluster::updateStart(const MemberId& updatee, const Url& url, Lock& l) { + // NOTE: deliverEventQueue is already stopped at the stall point by deliveredEvent. if (state == LEFT) return; assert(state == OFFER); state = UPDATER; - QPID_LOG(info, *this << " stall for update to " << updatee << " at " << url); - deliverFrameQueue.stop(); - if (updateThread.id()) updateThread.join(); // Join the previous updatethread. + QPID_LOG(info, *this << " sending update to " << updatee << " at " << url); + if (updateThread.id()) + updateThread.join(); // Join the previous updateThread to avoid leaks. client::ConnectionSettings cs; cs.username = settings.username; cs.password = settings.password; cs.mechanism = settings.mechanism; updateThread = Thread( - new UpdateClient(myId, updatee, url, broker, map, frameId, connections.values(), + new UpdateClient(self, updatee, url, broker, map, *expiryPolicy, getConnections(l), decoder, boost::bind(&Cluster::updateOutDone, this), boost::bind(&Cluster::updateOutError, this, _1), cs)); } // Called in update thread. -void Cluster::updateInDone(const ClusterMap& m, uint64_t fid) { +void Cluster::updateInDone(const ClusterMap& m) { Lock l(lock); updatedMap = m; - frameId = fid; checkUpdateIn(l); } -void Cluster::checkUpdateIn(Lock& ) { - if (state == LEFT) return; +void Cluster::checkUpdateIn(Lock&) { if (state == UPDATEE && updatedMap) { map = *updatedMap; - mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), myId); + mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self); state = CATCHUP; + discarding = false; // ok to set, we're stalled for update. QPID_LOG(info, *this << " received update, starting catch-up"); - deliverFrameQueue.start(); + deliverEventQueue.start(); } } @@ -462,8 +505,8 @@ void Cluster::updateOutDone(Lock& l) { assert(state == UPDATER); state = READY; mcast.release(); - deliverFrameQueue.start(); - tryMakeOffer(map.firstJoiner(), l); // Try another offer + deliverEventQueue.start(); // Start processing events again. + makeOffer(map.firstJoiner(), l); // Try another offer } void Cluster::updateOutError(const std::exception& e) { @@ -487,7 +530,7 @@ Manageable::status_t Cluster::ManagementMethod (uint32_t methodId, Args& args, s { _qmf::ArgsClusterStopClusterNode& iargs = (_qmf::ArgsClusterStopClusterNode&) args; stringstream stream; - stream << myId; + stream << self; if (iargs.i_brokerId == stream.str()) stopClusterNode(l); } @@ -508,7 +551,7 @@ void Cluster::stopClusterNode(Lock& l) { void Cluster::stopFullCluster(Lock& ) { QPID_LOG(notice, *this << " shutting down cluster " << name); - mcast.mcastControl(ClusterShutdownBody(), myId); + mcast.mcastControl(ClusterShutdownBody(), self); } void Cluster::memberUpdate(Lock& l) { @@ -518,13 +561,13 @@ void Cluster::memberUpdate(Lock& l) { size_t size = urls.size(); failoverExchange->setUrls(urls); - if (size == 1 && lastSize > 1 && state >= READY) { - QPID_LOG(info, *this << " last broker standing, update queue policies"); + if (size == 1 && lastSize > 1 && state >= CATCHUP) { + QPID_LOG(notice, *this << " last broker standing, update queue policies"); lastBroker = true; broker.getQueues().updateQueueClusterState(true); } else if (size > 1 && lastBroker) { - QPID_LOG(info, *this << " last broker standing joined by " << size-1 << " replicas, updating queue policies" << size); + QPID_LOG(notice, *this << " last broker standing joined by " << size-1 << " replicas, updating queue policies" << size); lastBroker = false; broker.getQueues().updateQueueClusterState(false); } @@ -546,17 +589,23 @@ void Cluster::memberUpdate(Lock& l) { mgmtObject->set_memberIDs(idstr); } - // Close connections belonging to members that have now been excluded - connections.update(myId, map); + // Erase connections belonging to members that have left the cluster. + ConnectionMap::iterator i = connections.begin(); + while (i != connections.end()) { + ConnectionMap::iterator j = i++; + MemberId m = j->second->getId().getMember(); + if (m != self && !map.isMember(m)) + connections.erase(j); + } } std::ostream& operator<<(std::ostream& o, const Cluster& cluster) { static const char* STATE[] = { "INIT", "JOINER", "UPDATEE", "CATCHUP", "READY", "OFFER", "UPDATER", "LEFT" }; - return o << cluster.myId << "(" << STATE[cluster.state] << ")"; + return o << cluster.self << "(" << STATE[cluster.state] << ")"; } MemberId Cluster::getId() const { - return myId; // Immutable, no need to lock. + return self; // Immutable, no need to lock. } broker::Broker& Cluster::getBroker() const { @@ -571,11 +620,11 @@ void Cluster::checkQuorum() { } } -void Cluster::setClusterId(const Uuid& uuid) { +void Cluster::setClusterId(const Uuid& uuid, Lock&) { clusterId = uuid; if (mgmtObject) { stringstream stream; - stream << myId; + stream << self; mgmtObject->set_clusterID(clusterId.str()); mgmtObject->set_memberID(stream.str()); } diff --git a/qpid/cpp/src/qpid/cluster/Cluster.h b/qpid/cpp/src/qpid/cluster/Cluster.h index 8c5eb06ff7..b716e2d781 100644 --- a/qpid/cpp/src/qpid/cluster/Cluster.h +++ b/qpid/cpp/src/qpid/cluster/Cluster.h @@ -19,34 +19,34 @@ * */ -#include "ClusterSettings.h" #include "ClusterMap.h" -#include "ConnectionMap.h" +#include "ClusterSettings.h" #include "Cpg.h" +#include "Decoder.h" #include "Event.h" +#include "EventFrame.h" +#include "ExpiryPolicy.h" #include "FailoverExchange.h" +#include "LockedConnectionMap.h" #include "Multicaster.h" -#include "EventFrame.h" #include "NoOpConnectionOutputHandler.h" +#include "PollableQueue.h" #include "PollerDispatch.h" #include "Quorum.h" -#include "Decoder.h" -#include "PollableQueue.h" -#include "ExpiryPolicy.h" +#include "qmf/org/apache/qpid/cluster/Cluster.h" +#include "qpid/Url.h" #include "qpid/broker/Broker.h" -#include "qpid/sys/Monitor.h" #include "qpid/management/Manageable.h" -#include "qpid/Url.h" -#include "qmf/org/apache/qpid/cluster/Cluster.h" +#include "qpid/sys/Monitor.h" -#include <boost/intrusive_ptr.hpp> #include <boost/bind.hpp> +#include <boost/intrusive_ptr.hpp> #include <boost/optional.hpp> #include <algorithm> -#include <vector> #include <map> +#include <vector> namespace qpid { @@ -58,6 +58,7 @@ class Uuid; namespace cluster { class Connection; +class EventFrame; /** * Connection to the cluster @@ -65,82 +66,91 @@ class Connection; class Cluster : private Cpg::Handler, public management::Manageable { public: typedef boost::intrusive_ptr<Connection> ConnectionPtr; - typedef std::vector<ConnectionPtr> Connections; + typedef std::vector<ConnectionPtr> ConnectionVector; - /** Construct the cluster in plugin earlyInitialize */ + // Public functions are thread safe unless otherwise mentioned in a comment. + + // Construct the cluster in plugin earlyInitialize. Cluster(const ClusterSettings&, broker::Broker&); virtual ~Cluster(); - /** Join the cluster in plugin initialize. Requires transport - * plugins to be available.. */ + // Called by plugin initialize: cluster start-up requires transport plugins . + // Thread safety: only called by plugin initialize. void initialize(); - // Connection map - called in connection threads. + // Connection map. void addLocalConnection(const ConnectionPtr&); void addShadowConnection(const ConnectionPtr&); void erase(const ConnectionId&); - // URLs of current cluster members - called in connection threads. + // URLs of current cluster members. std::vector<std::string> getIds() const; std::vector<Url> getUrls() const; boost::shared_ptr<FailoverExchange> getFailoverExchange() const { return failoverExchange; } - // Leave the cluster - called in any thread. + // Leave the cluster - called when fatal errors occur. void leave(); // Update completed - called in update thread - void updateInDone(const ClusterMap&, uint64_t frameId); + void updateInDone(const ClusterMap&); MemberId getId() const; broker::Broker& getBroker() const; Multicaster& getMulticast() { return mcast; } - boost::function<bool ()> isQuorate; - void checkQuorum(); // called in connection threads. + void checkQuorum(); size_t getReadMax() { return readMax; } size_t getWriteEstimate() { return writeEstimate; } - bool isLeader() const; // Called in deliver thread. + void deliverFrame(const EventFrame&); + + // Called only during update by Connection::shadowReady + Decoder& getDecoder() { return decoder; } + + ExpiryPolicy& getExpiryPolicy() { return *expiryPolicy; } private: typedef sys::Monitor::ScopedLock Lock; typedef PollableQueue<Event> PollableEventQueue; typedef PollableQueue<EventFrame> PollableFrameQueue; + typedef std::map<ConnectionId, ConnectionPtr> ConnectionMap; - // NB: The final Lock& parameter on functions below is used to mark functions - // that should only be called by a function that already holds the lock. - // The parameter makes it hard to forget since you have to have an instance of - // a Lock to call the unlocked functions. - + // NB: A dummy Lock& parameter marks functions that must only be + // called with Cluster::lock locked. + void leave(Lock&); std::vector<std::string> getIds(Lock&) const; std::vector<Url> getUrls(Lock&) const; - // Make an offer if we can - called in deliver thread. - void tryMakeOffer(const MemberId&, Lock&); - - // Called in main thread in ~Broker. + // == Called in main thread from Broker destructor. void brokerShutdown(); + // == Called in deliverEventQueue thread + void deliveredEvent(const Event&); + + // == Called in deliverFrameQueue thread + void deliveredFrame(const EventFrame&); + // Cluster controls implement XML methods from cluster.xml. - // Called in deliver thread. - // void updateRequest(const MemberId&, const std::string&, Lock&); void updateOffer(const MemberId& updater, uint64_t updatee, const framing::Uuid&, Lock&); void ready(const MemberId&, const std::string&, Lock&); void configChange(const MemberId&, const std::string& addresses, Lock& l); void messageExpired(const MemberId&, uint64_t, Lock& l); void shutdown(const MemberId&, Lock&); - void deliveredEvent(const Event&); - void deliveredFrame(const EventFrame&); - // Helper, called in deliver thread. + // Helper functions + ConnectionPtr getConnection(const ConnectionId&, Lock&); + ConnectionVector getConnections(Lock&); void updateStart(const MemberId& updatee, const Url& url, Lock&); - + void makeOffer(const MemberId&, Lock&); void setReady(Lock&); + void memberUpdate(Lock&); + void setClusterId(const framing::Uuid&, Lock&); + // == Called in CPG dispatch thread void deliver( // CPG deliver callback. cpg_handle_t /*handle*/, struct cpg_name *group, @@ -149,7 +159,7 @@ class Cluster : private Cpg::Handler, public management::Manageable { void* /*msg*/, int /*msg_len*/); - void deliver(const Event&); + void deliverEvent(const Event&); void configChange( // CPG config change callback. cpg_handle_t /*handle*/, @@ -159,23 +169,21 @@ class Cluster : private Cpg::Handler, public management::Manageable { struct cpg_address */*joined*/, int /*nJoined*/ ); + // == Called in management threads. virtual qpid::management::ManagementObject* GetManagementObject() const; virtual management::Manageable::status_t ManagementMethod (uint32_t methodId, management::Args& args, std::string& text); void stopClusterNode(Lock&); void stopFullCluster(Lock&); - void memberUpdate(Lock&); - // Called in connection IO threads . + // == Called in connection IO threads . void checkUpdateIn(Lock&); - // Called in UpdateClient thread. + // == Called in UpdateClient thread. void updateOutDone(); void updateOutError(const std::exception&); void updateOutDone(Lock&); - void setClusterId(const framing::Uuid&); - // Immutable members set on construction, never changed. ClusterSettings settings; broker::Broker& broker; @@ -184,34 +192,38 @@ class Cluster : private Cpg::Handler, public management::Manageable { Cpg cpg; const std::string name; Url myUrl; - const MemberId myId; + const MemberId self; const size_t readMax; const size_t writeEstimate; framing::Uuid clusterId; NoOpConnectionOutputHandler shadowOut; qpid::management::ManagementAgent* mAgent; + boost::intrusive_ptr<ExpiryPolicy> expiryPolicy; // Thread safe members Multicaster mcast; PollerDispatch dispatcher; PollableEventQueue deliverEventQueue; PollableFrameQueue deliverFrameQueue; - ConnectionMap connections; boost::shared_ptr<FailoverExchange> failoverExchange; Quorum quorum; - - // Used only in delivery thread - Decoder decoder; - ClusterMap::Set elders; - boost::intrusive_ptr<ExpiryPolicy> expiryPolicy; - uint64_t frameId; + LockedConnectionMap localConnections; // Used only during initialization bool initialized; - // Remaining members are protected by lock + // Used only in deliverEventQueue thread or when stalled for update. + Decoder decoder; + bool discarding; + + // Remaining members are protected by lock. + // FIXME aconway 2009-03-06: Most of these members are also only used in + // deliverFrameQueue thread or during stall. Review and separate members + // that require a lock, drop lock when not needed. + // mutable sys::Monitor lock; + // Local cluster state, cluster map enum { INIT, ///< Initial state, no CPG messages received. @@ -223,15 +235,16 @@ class Cluster : private Cpg::Handler, public management::Manageable { UPDATER, ///< Offer accepted, sending a state update. LEFT ///< Final state, left the cluster. } state; + + ConnectionMap connections; ClusterMap map; + ClusterMap::Set elders; size_t lastSize; bool lastBroker; - uint64_t sequence; - - // Update related sys::Thread updateThread; boost::optional<ClusterMap> updatedMap; + friend std::ostream& operator<<(std::ostream&, const Cluster&); friend class ClusterDispatcher; }; diff --git a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp index 132043f91a..adb6621caf 100644 --- a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp +++ b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp @@ -138,7 +138,6 @@ struct ClusterPlugin : public Plugin { broker->setConnectionFactory( boost::shared_ptr<sys::ConnectionCodec::Factory>( new ConnectionCodec::Factory(broker->getConnectionFactory(), *cluster))); - broker->getExchanges().registerExchange(cluster->getFailoverExchange()); ManagementBroker* mgmt = dynamic_cast<ManagementBroker*>(ManagementAgent::Singleton::getInstance()); if (mgmt) { std::auto_ptr<IdAllocator> allocator(new UpdateClientIdAllocator()); diff --git a/qpid/cpp/src/qpid/cluster/ClusterSettings.h b/qpid/cpp/src/qpid/cluster/ClusterSettings.h index a8f33be75e..88e8829dfe 100644 --- a/qpid/cpp/src/qpid/cluster/ClusterSettings.h +++ b/qpid/cpp/src/qpid/cluster/ClusterSettings.h @@ -35,7 +35,7 @@ struct ClusterSettings { size_t readMax, writeEstimate; std::string username, password, mechanism; - ClusterSettings() : quorum(false), readMax(10), writeEstimate(64), username("guest"), password("guest") {} + ClusterSettings() : quorum(false), readMax(10), writeEstimate(64) {} Url getUrl(uint16_t port) const { if (url.empty()) return Url::getIpAddressesUrl(port); diff --git a/qpid/cpp/src/qpid/cluster/Connection.cpp b/qpid/cpp/src/qpid/cluster/Connection.cpp index 1a3f7c4ef7..aa7d082720 100644 --- a/qpid/cpp/src/qpid/cluster/Connection.cpp +++ b/qpid/cpp/src/qpid/cluster/Connection.cpp @@ -40,6 +40,7 @@ #include "qpid/framing/ConnectionCloseOkBody.h" #include "qpid/log/Statement.h" #include "qpid/sys/LatencyMetric.h" +#include "qpid/sys/AtomicValue.h" #include <boost/current_function.hpp> @@ -58,27 +59,36 @@ using namespace framing; NoOpConnectionOutputHandler Connection::discardHandler; -// Shadow connections -Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out, - const std::string& wrappedId, ConnectionId myId) - : cluster(c), self(myId), catchUp(false), output(*this, out), - connection(&output, cluster.getBroker(), wrappedId), expectProtocolHeader(false) +namespace { +sys::AtomicValue<uint64_t> idCounter; +} + +// Shadow connection +Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out, const std::string& logId, const ConnectionId& id) + : cluster(c), self(id), catchUp(false), output(*this, out), + connection(&output, cluster.getBroker(), logId), expectProtocolHeader(false), + mcastFrameHandler(cluster.getMulticast(), self) { init(); } -// Local connections +// Local connection Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out, - const std::string& wrappedId, MemberId myId, bool isCatchUp, bool isLink) - : cluster(c), self(myId, this), catchUp(isCatchUp), output(*this, out), - connection(&output, cluster.getBroker(), wrappedId, isLink, catchUp ? ++catchUpId : 0), - expectProtocolHeader(isLink) + const std::string& logId, MemberId member, bool isCatchUp, bool isLink) + : cluster(c), self(member, ++idCounter), catchUp(isCatchUp), output(*this, out), + connection(&output, cluster.getBroker(), logId, isLink, catchUp ? ++catchUpId : 0), + expectProtocolHeader(isLink), mcastFrameHandler(cluster.getMulticast(), self) { init(); } void Connection::init() { QPID_LOG(debug, cluster << " new connection: " << *this); - if (isLocalClient()) { + if (isLocalClient()) { + connection.setClusterOrderOutput(mcastFrameHandler); // Actively send cluster-order frames from local node cluster.addLocalConnection(this); giveReadCredit(cluster.getReadMax()); } + else { // Shadow or catch-up connection + connection.setClusterOrderOutput(nullFrameHandler); // Passive, discard cluster-order frames + connection.setClientThrottling(false); // Disable client throttling, done by active node. + } } void Connection::giveReadCredit(int credit) { @@ -140,10 +150,16 @@ bool Connection::checkUnsupported(const AMQBody& body) { void Connection::deliveredFrame(const EventFrame& f) { assert(!catchUp); currentChannel = f.frame.getChannel(); - if (!framing::invoke(*this, *f.frame.getBody()).wasHandled() // Connection contol. + if (f.frame.getBody() // frame can be emtpy with just readCredit + && !framing::invoke(*this, *f.frame.getBody()).wasHandled() // Connection contol. && !checkUnsupported(*f.frame.getBody())) // Unsupported operation. { - connection.received(const_cast<AMQFrame&>(f.frame)); // Pass to broker connection. + if (f.type == DATA) // incoming data frames to broker::Connection + connection.received(const_cast<AMQFrame&>(f.frame)); + else { // frame control, send frame via SessionState + broker::SessionState* ss = connection.getChannel(f.frame.getChannel()).getSession(); + if (ss) ss->out(const_cast<AMQFrame&>(f.frame)); + } } giveReadCredit(f.readCredit); } @@ -186,12 +202,12 @@ void Connection::left() { connection.closed(); } -// Decode data from local clients. +// ConnectoinCodec::decode receives read buffers from directly-connected clients. size_t Connection::decode(const char* buffer, size_t size) { if (catchUp) { // Handle catch-up locally. Buffer buf(const_cast<char*>(buffer), size); while (localDecoder.decode(buf)) - received(localDecoder.frame); + received(localDecoder.getFrame()); } else { // Multicast local connections. assert(isLocal()); @@ -242,6 +258,7 @@ void Connection::sessionState( const SequenceSet& unknownCompleted, const SequenceSet& receivedIncomplete) { + sessionState().setState( replayStart, sendCommandPoint, @@ -253,21 +270,23 @@ void Connection::sessionState( QPID_LOG(debug, cluster << " received session state update for " << sessionState().getId()); } -void Connection::shadowReady(uint64_t memberId, uint64_t connectionId, const string& username) { - ConnectionId shadow = ConnectionId(memberId, connectionId); - QPID_LOG(debug, cluster << " catch-up connection " << *this << " becomes shadow " << shadow); - self = shadow; +void Connection::shadowReady(uint64_t memberId, uint64_t connectionId, const string& username, const string& fragment) { + ConnectionId shadowId = ConnectionId(memberId, connectionId); + QPID_LOG(debug, cluster << " catch-up connection " << *this << " becomes shadow " << shadowId); + self = shadowId; connection.setUserId(username); + // OK to use decoder here because we are stalled for update. + cluster.getDecoder().get(self).setFragment(fragment.data(), fragment.size()); } -void Connection::membership(const FieldTable& joiners, const FieldTable& members, uint64_t frameId) { +void Connection::membership(const FieldTable& joiners, const FieldTable& members) { QPID_LOG(debug, cluster << " incoming update complete on connection " << *this); - cluster.updateInDone(ClusterMap(joiners, members), frameId); + cluster.updateInDone(ClusterMap(joiners, members)); self.second = 0; // Mark this as completed update connection. } bool Connection::isLocal() const { - return self.first == cluster.getId() && self.second == this; + return self.first == cluster.getId() && self.second; } bool Connection::isShadow() const { @@ -333,6 +352,10 @@ void Connection::queuePosition(const string& qname, const SequenceNumber& positi q->setPosition(position); } +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"; diff --git a/qpid/cpp/src/qpid/cluster/Connection.h b/qpid/cpp/src/qpid/cluster/Connection.h index 98b47e1bc0..6434f763a8 100644 --- a/qpid/cpp/src/qpid/cluster/Connection.h +++ b/qpid/cpp/src/qpid/cluster/Connection.h @@ -27,14 +27,15 @@ #include "OutputInterceptor.h" #include "NoOpConnectionOutputHandler.h" #include "EventFrame.h" +#include "McastFrameHandler.h" #include "qpid/broker/Connection.h" #include "qpid/amqp_0_10/Connection.h" #include "qpid/sys/AtomicValue.h" #include "qpid/sys/ConnectionInputHandler.h" #include "qpid/sys/ConnectionOutputHandler.h" -#include "qpid/framing/FrameDecoder.h" #include "qpid/framing/SequenceNumber.h" +#include "qpid/framing/FrameDecoder.h" #include <iosfwd> @@ -63,10 +64,10 @@ class Connection : public: typedef sys::PollableQueue<EventFrame> PollableFrameQueue; - /** Local connection, use this in ConnectionId */ - Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& id, MemberId, bool catchUp, bool isLink); - /** Shadow connection */ - Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& id, ConnectionId); + /** Local connection. */ + Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& logId, MemberId, bool catchUp, bool isLink); + /** Shadow connection. */ + Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& logId, const ConnectionId& id); ~Connection(); ConnectionId getId() const { return self; } @@ -99,7 +100,7 @@ class Connection : /** Called if the connectors member has left the cluster */ void left(); - // ConnectionCodec methods + // ConnectionCodec methods - called by IO layer with a read buffer. size_t decode(const char* buffer, size_t size); // Called for data delivered from the cluster. @@ -117,9 +118,9 @@ class Connection : const framing::SequenceNumber& received, const framing::SequenceSet& unknownCompleted, const SequenceSet& receivedIncomplete); - void shadowReady(uint64_t memberId, uint64_t connectionId, const std::string& username); + void shadowReady(uint64_t memberId, uint64_t connectionId, const std::string& username, const std::string& fragment); - void membership(const framing::FieldTable&, const framing::FieldTable&, uint64_t frameId); + void membership(const framing::FieldTable&, const framing::FieldTable&); void deliveryRecord(const std::string& queue, const framing::SequenceNumber& position, @@ -134,6 +135,7 @@ class Connection : uint32_t credit); void queuePosition(const std::string&, const framing::SequenceNumber&); + void expiryId(uint64_t); void txStart(); void txAccept(const framing::SequenceSet&); @@ -148,8 +150,12 @@ class Connection : void exchange(const std::string& encoded); void giveReadCredit(int credit); - + private: + struct NullFrameHandler : public framing::FrameHandler { + void handle(framing::AMQFrame&) {} + }; + void init(); bool checkUnsupported(const framing::AMQBody& body); void deliverClose(); @@ -174,6 +180,8 @@ class Connection : framing::ChannelId currentChannel; boost::shared_ptr<broker::TxBuffer> txBuffer; bool expectProtocolHeader; + McastFrameHandler mcastFrameHandler; + NullFrameHandler nullFrameHandler; static qpid::sys::AtomicValue<uint64_t> catchUpId; diff --git a/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp b/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp index 442ac1438f..007337792b 100644 --- a/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp +++ b/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp @@ -44,18 +44,15 @@ ConnectionCodec::Factory::create(ProtocolVersion v, sys::OutputControl& out, con return 0; } -// Used for outgoing Link connections, we don't care. +// Used for outgoing Link connections sys::ConnectionCodec* -ConnectionCodec::Factory::create(sys::OutputControl& out, const std::string& id) { - return new ConnectionCodec(out, id, cluster, false, true); - //return next->create(out, id); +ConnectionCodec::Factory::create(sys::OutputControl& out, const std::string& logId) { + return new ConnectionCodec(out, logId, cluster, false, true); } -ConnectionCodec::ConnectionCodec(sys::OutputControl& out, const std::string& id, Cluster& cluster, bool catchUp, bool isLink) - : codec(out, id, isLink), - interceptor(new Connection(cluster, codec, id, cluster.getId(), catchUp, isLink)), - id(interceptor->getId()), - localId(id) +ConnectionCodec::ConnectionCodec(sys::OutputControl& out, const std::string& logId, Cluster& cluster, bool catchUp, bool isLink) + : codec(out, logId, isLink), + interceptor(new Connection(cluster, codec, logId, cluster.getId(), catchUp, isLink)) { std::auto_ptr<sys::ConnectionInputHandler> ih(new ProxyInputHandler(interceptor)); codec.setInputHandler(ih); diff --git a/qpid/cpp/src/qpid/cluster/ConnectionCodec.h b/qpid/cpp/src/qpid/cluster/ConnectionCodec.h index 69c2b0c3c8..ea01b7abb9 100644 --- a/qpid/cpp/src/qpid/cluster/ConnectionCodec.h +++ b/qpid/cpp/src/qpid/cluster/ConnectionCodec.h @@ -56,7 +56,7 @@ class ConnectionCodec : public sys::ConnectionCodec { sys::ConnectionCodec* create(sys::OutputControl&, const std::string& id); }; - ConnectionCodec(sys::OutputControl& out, const std::string& id, Cluster& c, bool catchUp, bool isLink); + ConnectionCodec(sys::OutputControl& out, const std::string& logId, Cluster& c, bool catchUp, bool isLink); ~ConnectionCodec(); // ConnectionCodec functions. @@ -71,8 +71,6 @@ class ConnectionCodec : public sys::ConnectionCodec { private: amqp_0_10::Connection codec; boost::intrusive_ptr<cluster::Connection> interceptor; - cluster::ConnectionId id; - std::string localId; }; }} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp b/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp deleted file mode 100644 index 3c18cf751e..0000000000 --- a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp +++ /dev/null @@ -1,57 +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 "ConnectionDecoder.h" -#include "EventFrame.h" -#include "ConnectionMap.h" - -namespace qpid { -namespace cluster { - -using namespace framing; - -ConnectionDecoder::ConnectionDecoder(const Handler& h) : handler(h) {} - -void ConnectionDecoder::decode(const EventHeader& eh, const void* data, ConnectionMap& map) { - assert(eh.getType() == DATA); // Only handle connection data events. - const char* cp = static_cast<const char*>(data); - Buffer buf(const_cast<char*>(cp), eh.getSize()); - if (decoder.decode(buf)) { // Decoded a frame - AMQFrame frame(decoder.frame); - while (decoder.decode(buf)) { - handler(EventFrame(eh, frame)); - frame = decoder.frame; - } - // Set read-credit on the last frame ending in this event. - // Credit will be given when this frame is processed. - handler(EventFrame(eh, frame, 1)); - } - else { - // We must give 1 unit read credit per event. - // This event does not complete any frames so - // we give read credit directly. - ConnectionPtr connection = map.getLocal(eh.getConnectionId()); - if (connection) - connection->giveReadCredit(1); - } -} - -}} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp b/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp deleted file mode 100644 index b412bb13cc..0000000000 --- a/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp +++ /dev/null @@ -1,96 +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 "ConnectionMap.h" -#include "Cluster.h" -#include "qpid/framing/reply_exceptions.h" -#include "qpid/log/Statement.h" - -namespace qpid { -namespace cluster { - -using framing::InternalErrorException; - -void ConnectionMap::insert(ConnectionPtr p) { - std::pair<Map::iterator, bool> ib = map.insert(Map::value_type(p->getId(), p)); - if (!ib.second) { - assert(0); - throw InternalErrorException(QPID_MSG("Duplicate connection replica: " << p->getId())); - } -} - -void ConnectionMap::erase(const ConnectionId& id) { - Map::iterator i = map.find(id); - if (i == map.end()) { - assert(0); - QPID_LOG(warning, "Erase non-existent connection replica: " << id); - } - map.erase(i); -} - -ConnectionMap::ConnectionPtr ConnectionMap::get(const ConnectionId& id) { - Map::const_iterator i = map.find(id); - if (i == map.end()) { - // Deleted local connection. - if(id.getMember() == cluster.getId()) - return 0; - // New remote connection, create a shadow. - std::ostringstream mgmtId; - mgmtId << id; - ConnectionPtr cp = new Connection(cluster, shadowOut, mgmtId.str(), id); - std::pair<Map::iterator, bool> ib = map.insert(Map::value_type(id, cp)); - if (!ib.second) - throw InternalErrorException(QPID_MSG("Duplicate entry in cluster connection map: " << id)); - i = ib.first; - } - return i->second; -} - -ConnectionMap::ConnectionPtr ConnectionMap::getLocal(const ConnectionId& id) { - if (id.getMember() != cluster.getId()) return 0; - Map::const_iterator i = map.find(id); - assert(i != map.end()); // FIXME aconway 2009-02-11: remove or exception. - return i == map.end() ? 0 : i->second; -} - -ConnectionMap::Vector ConnectionMap::values() const { - Vector result(map.size()); - std::transform(map.begin(), map.end(), result.begin(), - boost::bind(&Map::value_type::second, _1)); - return result; -} - -void ConnectionMap::update(MemberId myId, const ClusterMap& cluster) { - for (Map::iterator i = map.begin(); i != map.end(); ) { - MemberId member = i->first.getMember(); - if (member != myId && !cluster.isMember(member)) { - i->second->left(); - map.erase(i++); - } else { - i++; - } - } -} - -void ConnectionMap::clear() { - map.clear(); -} - -}} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/ConnectionMap.h b/qpid/cpp/src/qpid/cluster/ConnectionMap.h deleted file mode 100644 index f8aa663339..0000000000 --- a/qpid/cpp/src/qpid/cluster/ConnectionMap.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef QPID_CLUSTER_CONNECTIONMAP_H -#define QPID_CLUSTER_CONNECTIONMAP_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 "types.h" -#include "Connection.h" -#include "ClusterMap.h" -#include "NoOpConnectionOutputHandler.h" -#include "qpid/sys/Mutex.h" -#include <boost/intrusive_ptr.hpp> -#include <map> - -namespace qpid { -namespace cluster { - -class Cluster; - -/** - * Thread safe map of connections. The map is used in: - * - deliver thread to look connections and create new shadow connections. - * - local catch-up connection threads to add a caught-up shadow connections. - * - local client connection threads when local connections are created. - */ -class ConnectionMap { - public: - typedef boost::intrusive_ptr<cluster::Connection> ConnectionPtr; - typedef std::vector<ConnectionPtr> Vector; - - ConnectionMap(Cluster& c) : cluster(c) {} - - /** Insert a local connection or a caught up shadow connection. - * Called in local connection thread. - */ - void insert(ConnectionPtr p); - - /** Erase a closed connection. Called in deliver thread. */ - void erase(const ConnectionId& id); - - /** Get an existing connection. Returns 0 if id is a closed local - * connections, frames for closed connections should be ignored. - */ - ConnectionPtr get(const ConnectionId& id); - - /** If ID is a local connection and in the map return it, else return 0 */ - ConnectionPtr getLocal(const ConnectionId& id); - - /** Get connections for sending an update. */ - Vector values() const; - - /** Remove connections who's members are no longer in the cluster. Deliver thread. */ - void update(MemberId myId, const ClusterMap& cluster); - - - void clear(); - - size_t size() const; - - private: - typedef std::map<ConnectionId, ConnectionPtr> Map; - - Cluster& cluster; - NoOpConnectionOutputHandler shadowOut; - Map map; -}; - - -}} // namespace qpid::cluster - -#endif /*!QPID_CLUSTER_CONNECTIONMAP_H*/ diff --git a/qpid/cpp/src/qpid/cluster/Cpg.cpp b/qpid/cpp/src/qpid/cluster/Cpg.cpp index c5a1b72003..915a578989 100644 --- a/qpid/cpp/src/qpid/cluster/Cpg.cpp +++ b/qpid/cpp/src/qpid/cluster/Cpg.cpp @@ -107,17 +107,16 @@ void Cpg::leave() { check(cpg_leave(handle, &group), cantLeaveMsg(group)); } -bool Cpg::isFlowControlEnabled() { - cpg_flow_control_state_t flowState; - check(cpg_flow_control_state_get(handle, &flowState), "Cannot get CPG flow control status."); - return flowState == CPG_FLOW_CONTROL_ENABLED; -} + + bool Cpg::mcast(const iovec* iov, int iovLen) { - if (isFlowControlEnabled()) { - QPID_LOG(debug, "CPG flow control enabled") + // Check for flow control + cpg_flow_control_state_t flowState; + check(cpg_flow_control_state_get(handle, &flowState), "Cannot get CPG flow control status."); + if (flowState == CPG_FLOW_CONTROL_ENABLED) return false; - } + cpg_error_t result; do { result = cpg_mcast_joined(handle, CPG_TYPE_AGREED, const_cast<iovec*>(iov), iovLen); @@ -149,9 +148,13 @@ void Cpg::dispatchBlocking() { string Cpg::errorStr(cpg_error_t err, const std::string& msg) { std::ostringstream os; os << msg << ": "; + // FIXME aconway 2009-03-11: The commented out cases below are + // because of mistakes in the latest corosync header files. + // The code should be re-instated when that is sorted out. + // switch (err) { case CPG_OK: os << "ok"; break; - case CPG_ERR_LIBRARY: os << "library"; break; + // case CPG_ERR_LIBRARY: os << "library"; break; case CPG_ERR_TIMEOUT: os << "timeout"; break; case CPG_ERR_TRY_AGAIN: os << "try again"; break; case CPG_ERR_INVALID_PARAM: os << "invalid param"; break; @@ -161,8 +164,8 @@ string Cpg::errorStr(cpg_error_t err, const std::string& msg) { case CPG_ERR_NOT_EXIST: os << "not exist"; break; case CPG_ERR_EXIST: os << "exist"; break; case CPG_ERR_NOT_SUPPORTED: os << "not supported"; break; - case CPG_ERR_SECURITY: os << "security"; break; - case CPG_ERR_TOO_MANY_GROUPS: os << "too many groups"; break; + // case CPG_ERR_SECURITY: os << "security"; break; + // case CPG_ERR_TOO_MANY_GROUPS: os << "too many groups"; break; default: os << ": unknown cpg error " << err; }; os << " (" << err << ")"; @@ -203,13 +206,19 @@ ostream& operator<<(ostream& o, const ConnectionId& c) { std::string MemberId::str() const { char s[8]; - reinterpret_cast<uint32_t&>(s[0]) = htonl(first); - reinterpret_cast<uint32_t&>(s[4]) = htonl(second); + uint32_t x; + x = htonl(first); + ::memcpy(s, &x, 4); + x = htonl(second); + ::memcpy(s+4, &x, 4); return std::string(s,8); } MemberId::MemberId(const std::string& s) { - first = ntohl(reinterpret_cast<const uint32_t&>(s[0])); - second = ntohl(reinterpret_cast<const uint32_t&>(s[4])); + uint32_t x; + memcpy(&x, &s[0], 4); + first = ntohl(x); + memcpy(&x, &s[4], 4); + second = ntohl(x); } }} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/Cpg.h b/qpid/cpp/src/qpid/cluster/Cpg.h index 5ac5a5bdbc..ac27a09ae6 100644 --- a/qpid/cpp/src/qpid/cluster/Cpg.h +++ b/qpid/cpp/src/qpid/cluster/Cpg.h @@ -114,8 +114,6 @@ class Cpg : public sys::IOHandle { int getFd(); - bool isFlowControlEnabled(); - private: static std::string errorStr(cpg_error_t err, const std::string& msg); static std::string cantJoinMsg(const Name&); diff --git a/qpid/cpp/src/qpid/cluster/Decoder.cpp b/qpid/cpp/src/qpid/cluster/Decoder.cpp index 1ba36bb521..b337ef43f4 100644 --- a/qpid/cpp/src/qpid/cluster/Decoder.cpp +++ b/qpid/cpp/src/qpid/cluster/Decoder.cpp @@ -18,33 +18,44 @@ * under the License. * */ - #include "Decoder.h" -#include "Event.h" +#include "EventFrame.h" +#include "qpid/framing/ClusterConnectionDeliverCloseBody.h" #include "qpid/framing/Buffer.h" -#include "qpid/ptr_map.h" +#include "qpid/framing/AMQFrame.h" + namespace qpid { namespace cluster { -using namespace framing; - -Decoder::Decoder(const Handler& h, ConnectionMap& cm) : handler(h), connections(cm) {} - -void Decoder::decode(const EventHeader& eh, const void* data) { - ConnectionId id = eh.getConnectionId(); - Map::iterator i = map.find(id); - if (i == map.end()) { - std::pair<Map::iterator, bool> ib = map.insert(id, new ConnectionDecoder(handler)); - i = ib.first; +void Decoder::decode(const EventHeader& eh, const char* data) { + assert(eh.getType() == DATA); // Only handle connection data events. + const char* cp = static_cast<const char*>(data); + framing::Buffer buf(const_cast<char*>(cp), eh.getSize()); + framing::FrameDecoder& decoder = map[eh.getConnectionId()]; + if (decoder.decode(buf)) { // Decoded a frame + framing::AMQFrame frame(decoder.getFrame()); + while (decoder.decode(buf)) { + process(EventFrame(eh, frame)); + frame = decoder.getFrame(); + } + // Set read-credit on the last frame ending in this event. + // Credit will be given when this frame is processed. + process(EventFrame(eh, frame, 1)); } - ptr_map_ptr(i)->decode(eh, data, connections); + else { + // We must give 1 unit read credit per event. + // This event does not complete any frames so + // send an empty frame with the read credit. + process(EventFrame(eh, framing::AMQFrame(), 1)); + } } -void Decoder::erase(const ConnectionId& c) { - Map::iterator i = map.find(c); - if (i != map.end()) - map.erase(i); +void Decoder::process(const EventFrame& ef) { + //need to check that this is not the empty frame mentioned above + if (ef.frame.getBody() && ef.frame.getMethod() && ef.frame.getMethod()->isA<framing::ClusterConnectionDeliverCloseBody>()) + map.erase(ef.connectionId); + callback(ef); } }} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/Decoder.h b/qpid/cpp/src/qpid/cluster/Decoder.h index 50f6afa491..acde4258a2 100644 --- a/qpid/cpp/src/qpid/cluster/Decoder.h +++ b/qpid/cpp/src/qpid/cluster/Decoder.h @@ -22,44 +22,36 @@ * */ -#include "ConnectionDecoder.h" #include "types.h" -#include <boost/ptr_container/ptr_map.hpp> +#include "qpid/framing/FrameDecoder.h" +#include <boost/function.hpp> +#include <map> namespace qpid { namespace cluster { +class EventFrame; class EventHeader; -class ConnectionMap; /** - * Holds a map of ConnectionDecoders. Decodes Events into EventFrames - * and forwards EventFrames to a handler. - * - * THREAD UNSAFE: Called sequentially with un-decoded cluster events from CPG. + * A map of decoders for connections. */ class Decoder { public: - typedef boost::function<void(const EventFrame&)> Handler; - - Decoder(const Handler& h, ConnectionMap&); + typedef boost::function<void(const EventFrame&)> FrameHandler; - /** Takes EventHeader + data rather than Event so that the caller can - * pass a pointer to connection data or a CPG buffer directly without copy. - */ - void decode(const EventHeader& eh, const void* data); - - /** Erase the decoder for a connection. */ + Decoder(FrameHandler fh) : callback(fh) {} + void decode(const EventHeader& eh, const char* data); void erase(const ConnectionId&); + framing::FrameDecoder& get(const ConnectionId& c) { return map[c]; } private: - typedef boost::ptr_map<ConnectionId, ConnectionDecoder> Map; - Handler handler; + typedef std::map<ConnectionId, framing::FrameDecoder> Map; Map map; - ConnectionMap& connections; + void process(const EventFrame&); + FrameHandler callback; }; - }} // namespace qpid::cluster #endif /*!QPID_CLUSTER_DECODER_H*/ diff --git a/qpid/cpp/src/qpid/cluster/Event.cpp b/qpid/cpp/src/qpid/cluster/Event.cpp index e30b961b3e..1cb010c266 100644 --- a/qpid/cpp/src/qpid/cluster/Event.cpp +++ b/qpid/cpp/src/qpid/cluster/Event.cpp @@ -23,6 +23,7 @@ #include "Cpg.h" #include "qpid/framing/Buffer.h" #include "qpid/framing/AMQFrame.h" +#include "qpid/assert.h" #include <ostream> #include <iterator> #include <algorithm> @@ -31,6 +32,7 @@ namespace qpid { namespace cluster { using framing::Buffer; +using framing::AMQFrame; const size_t EventHeader::HEADER_SIZE = sizeof(uint8_t) + // type @@ -42,7 +44,7 @@ const size_t EventHeader::HEADER_SIZE = ; EventHeader::EventHeader(EventType t, const ConnectionId& c, size_t s) - : type(t), connectionId(c), size(s), sequence(0) {} + : type(t), connectionId(c), size(s) {} Event::Event() {} @@ -57,7 +59,7 @@ void EventHeader::decode(const MemberId& m, framing::Buffer& buf) { type = (EventType)buf.getOctet(); if(type != DATA && type != CONTROL) throw Exception("Invalid multicast event type"); - connectionId = ConnectionId(m, reinterpret_cast<Connection*>(buf.getLongLong())); + connectionId = ConnectionId(m, buf.getLongLong()); size = buf.getLong(); #ifdef QPID_LATENCY_METRIC latency_metric_timestamp = buf.getLongLong(); @@ -74,14 +76,17 @@ Event Event::decodeCopy(const MemberId& m, framing::Buffer& buf) { return e; } -Event Event::control(const framing::AMQBody& body, const ConnectionId& cid) { - framing::AMQFrame f(body); +Event Event::control(const framing::AMQFrame& f, const ConnectionId& cid) { Event e(CONTROL, cid, f.encodedSize()); Buffer buf(e); f.encode(buf); return e; } +Event Event::control(const framing::AMQBody& body, const ConnectionId& cid) { + return control(framing::AMQFrame(body), cid); +} + iovec Event::toIovec() { encodeHeader(); iovec iov = { const_cast<char*>(getStore()), getStoreSize() }; @@ -90,7 +95,7 @@ iovec Event::toIovec() { void EventHeader::encode(Buffer& b) const { b.putOctet(type); - b.putLongLong(reinterpret_cast<uint64_t>(connectionId.getPointer())); + b.putLongLong(connectionId.getNumber()); b.putLong(size); #ifdef QPID_LATENCY_METRIC b.putLongLong(latency_metric_timestamp); @@ -108,12 +113,22 @@ Event::operator Buffer() const { return Buffer(const_cast<char*>(getData()), getSize()); } +AMQFrame Event::getFrame() const { + assert(type == CONTROL); + Buffer buf(*this); + AMQFrame frame; + QPID_ASSERT(frame.decode(buf)); + return frame; +} + static const char* EVENT_TYPE_NAMES[] = { "data", "control" }; +std::ostream& operator << (std::ostream& o, EventType t) { + return o << EVENT_TYPE_NAMES[t]; +} + std::ostream& operator << (std::ostream& o, const EventHeader& e) { - o << "[event " << e.getConnectionId() << "/" << e.getSequence() - << " " << EVENT_TYPE_NAMES[e.getType()] - << " " << e.getSize() << " bytes]"; + o << "Event[" << e.getConnectionId() << " " << e.getType() << " " << e.getSize() << " bytes]"; return o; } diff --git a/qpid/cpp/src/qpid/cluster/Event.h b/qpid/cpp/src/qpid/cluster/Event.h index f1de248f89..e05ad60bcf 100644 --- a/qpid/cpp/src/qpid/cluster/Event.h +++ b/qpid/cpp/src/qpid/cluster/Event.h @@ -24,6 +24,7 @@ #include "types.h" #include "qpid/RefCountedBuffer.h" +#include "qpid/framing/AMQFrame.h" #include "qpid/sys/LatencyMetric.h" #include <sys/uio.h> // For iovec #include <iosfwd> @@ -34,6 +35,7 @@ namespace qpid { namespace framing { class AMQBody; +class AMQFrame; class Buffer; } @@ -55,11 +57,9 @@ class EventHeader : public ::qpid::sys::LatencyMetricTimestamp { /** Size of header + payload. */ size_t getStoreSize() { return size + HEADER_SIZE; } - uint64_t getSequence() const { return sequence; } - void setSequence(uint64_t n) { sequence = n; } - - bool isCluster() const { return connectionId.getPointer() == 0; } - bool isConnection() const { return connectionId.getPointer() != 0; } + bool isCluster() const { return connectionId.getNumber() == 0; } + bool isConnection() const { return connectionId.getNumber() != 0; } + bool isControl() const { return type == CONTROL; } protected: static const size_t HEADER_SIZE; @@ -67,7 +67,6 @@ class EventHeader : public ::qpid::sys::LatencyMetricTimestamp { EventType type; ConnectionId connectionId; size_t size; - uint64_t sequence; }; /** @@ -83,8 +82,11 @@ class Event : public EventHeader { /** Create an event copied from delivered data. */ static Event decodeCopy(const MemberId& m, framing::Buffer&); - /** Create an event containing a control */ + /** Create a control event. */ static Event control(const framing::AMQBody&, const ConnectionId&); + + /** Create a control event. */ + static Event control(const framing::AMQFrame&, const ConnectionId&); // Data excluding header. char* getData() { return store + HEADER_SIZE; } @@ -93,6 +95,8 @@ class Event : public EventHeader { // Store including header char* getStore() { return store; } const char* getStore() const { return store; } + + framing::AMQFrame getFrame() const; operator framing::Buffer() const; @@ -105,6 +109,7 @@ class Event : public EventHeader { }; std::ostream& operator << (std::ostream&, const EventHeader&); + }} // namespace qpid::cluster #endif /*!QPID_CLUSTER_EVENT_H*/ diff --git a/qpid/cpp/src/qpid/cluster/EventFrame.cpp b/qpid/cpp/src/qpid/cluster/EventFrame.cpp index ba01c170dd..9350c801f5 100644 --- a/qpid/cpp/src/qpid/cluster/EventFrame.cpp +++ b/qpid/cpp/src/qpid/cluster/EventFrame.cpp @@ -24,16 +24,20 @@ namespace qpid { namespace cluster { -EventFrame::EventFrame() : sequence(0) {} +EventFrame::EventFrame() {} EventFrame::EventFrame(const EventHeader& e, const framing::AMQFrame& f, int rc) - : connectionId(e.getConnectionId()), frame(f), sequence(e.getSequence()), readCredit(rc) + : connectionId(e.getConnectionId()), frame(f), readCredit(rc), type(e.getType()) { QPID_LATENCY_INIT(frame); } std::ostream& operator<<(std::ostream& o, const EventFrame& e) { - return o << e.connectionId << "/" << e.sequence << " " << e.frame << " rc=" << e.readCredit; + if (e.frame.getBody()) o << e.frame; + else o << "null-frame"; + o << " " << e.type << " " << e.connectionId; + if (e.readCredit) o << " read-credit=" << e.readCredit; + return o; } }} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/EventFrame.h b/qpid/cpp/src/qpid/cluster/EventFrame.h index 7f33cedb5b..d6ff58dd38 100644 --- a/qpid/cpp/src/qpid/cluster/EventFrame.h +++ b/qpid/cpp/src/qpid/cluster/EventFrame.h @@ -42,22 +42,15 @@ struct EventFrame EventFrame(const EventHeader& e, const framing::AMQFrame& f, int rc=0); - bool isCluster() const { return !connectionId.getPointer(); } - bool isConnection() const { return connectionId.getPointer(); } + bool isCluster() const { return connectionId.getNumber() == 0; } + bool isConnection() const { return connectionId.getNumber() != 0; } bool isLastInEvent() const { return readCredit; } - // True if this frame follows immediately after frame e. - bool follows(const EventFrame& e) const { - return sequence == e.sequence || (sequence == e.sequence+1 && e.readCredit); - } - - bool operator<(const EventFrame& e) const { return sequence < e.sequence; } - ConnectionId connectionId; framing::AMQFrame frame; - uint64_t sequence; - int readCredit; // last frame in an event, give credit when processed. + int readCredit; ///< last frame in an event, give credit when processed. + EventType type; }; std::ostream& operator<<(std::ostream& o, const EventFrame& e); diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp index 690acfc3ad..409180c499 100644 --- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp +++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp @@ -30,48 +30,46 @@ namespace qpid { namespace cluster { -ExpiryPolicy::ExpiryPolicy(const boost::function<bool()> & f, Multicaster& m, const MemberId& id, broker::Timer& t) - : expiredPolicy(new Expired), isLeader(f), mcast(m), memberId(id), timer(t) {} - -namespace { -uint64_t clusterId(const broker::Message& m) { - assert(m.getFrames().begin() != m.getFrames().end()); - return m.getFrames().begin()->getClusterId(); -} +ExpiryPolicy::ExpiryPolicy(Multicaster& m, const MemberId& id, broker::Timer& t) + : expiryId(0), expiredPolicy(new Expired), mcast(m), memberId(id), timer(t) {} struct ExpiryTask : public broker::TimerTask { ExpiryTask(const boost::intrusive_ptr<ExpiryPolicy>& policy, uint64_t id, sys::AbsTime when) - : TimerTask(when), expiryPolicy(policy), messageId(id) {} - void fire() { expiryPolicy->sendExpire(messageId); } + : TimerTask(when), expiryPolicy(policy), expiryId(id) {} + void fire() { expiryPolicy->sendExpire(expiryId); } boost::intrusive_ptr<ExpiryPolicy> expiryPolicy; - const uint64_t messageId; + const uint64_t expiryId; }; -} void ExpiryPolicy::willExpire(broker::Message& m) { - timer.add(new ExpiryTask(this, clusterId(m), m.getExpiration())); + uint64_t id = expiryId++; + assert(unexpiredById.find(id) == unexpiredById.end()); + assert(unexpiredByMessage.find(&m) == unexpiredByMessage.end()); + unexpiredById[id] = &m; + unexpiredByMessage[&m] = id; + timer.add(new ExpiryTask(this, id, m.getExpiration())); } bool ExpiryPolicy::hasExpired(broker::Message& m) { - sys::Mutex::ScopedLock l(lock); - IdSet::iterator i = expired.find(clusterId(m)); - if (i != expired.end()) { - expired.erase(i); - const_cast<broker::Message&>(m).setExpiryPolicy(expiredPolicy); // hasExpired() == true; - return true; - } - return false; + return unexpiredByMessage.find(&m) == unexpiredByMessage.end(); } void ExpiryPolicy::sendExpire(uint64_t id) { - sys::Mutex::ScopedLock l(lock); - if (isLeader()) - mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId); + mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId); } void ExpiryPolicy::deliverExpire(uint64_t id) { - sys::Mutex::ScopedLock l(lock); - expired.insert(id); + IdMessageMap::iterator i = unexpiredById.find(id); + if (i != unexpiredById.end()) { + i->second->setExpiryPolicy(expiredPolicy); // hasExpired() == true; + unexpiredByMessage.erase(i->second); + unexpiredById.erase(i); + } +} + +boost::optional<uint64_t> ExpiryPolicy::getId(broker::Message& m) { + MessageIdMap::iterator i = unexpiredByMessage.find(&m); + return i == unexpiredByMessage.end() ? boost::optional<uint64_t>() : i->second; } bool ExpiryPolicy::Expired::hasExpired(broker::Message&) { return true; } diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h index 7fb63c731e..9f8b1a9236 100644 --- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h +++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h @@ -27,11 +27,15 @@ #include "qpid/sys/Mutex.h" #include <boost/function.hpp> #include <boost/intrusive_ptr.hpp> -#include <set> +#include <boost/optional.hpp> +#include <map> namespace qpid { -namespace broker { class Timer; } +namespace broker { +class Timer; +class Message; +} namespace cluster { class Multicaster; @@ -42,7 +46,7 @@ class Multicaster; class ExpiryPolicy : public broker::ExpiryPolicy { public: - ExpiryPolicy(const boost::function<bool()> & isLeader, Multicaster&, const MemberId&, broker::Timer&); + ExpiryPolicy(Multicaster&, const MemberId&, broker::Timer&); void willExpire(broker::Message&); @@ -54,18 +58,24 @@ class ExpiryPolicy : public broker::ExpiryPolicy // Cluster delivers expiry notice. void deliverExpire(uint64_t); + void setId(uint64_t id) { expiryId = id; } + uint64_t getId() const { return expiryId; } + + boost::optional<uint64_t> getId(broker::Message&); + private: - sys::Mutex lock; - typedef std::set<uint64_t> IdSet; + typedef std::map<broker::Message*, uint64_t> MessageIdMap; + typedef std::map<uint64_t, broker::Message*> IdMessageMap; struct Expired : public broker::ExpiryPolicy { bool hasExpired(broker::Message&); void willExpire(broker::Message&); }; - IdSet expired; + MessageIdMap unexpiredByMessage; + IdMessageMap unexpiredById; + uint64_t expiryId; boost::intrusive_ptr<Expired> expiredPolicy; - boost::function<bool()> isLeader; Multicaster& mcast; MemberId memberId; broker::Timer& timer; diff --git a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.h b/qpid/cpp/src/qpid/cluster/LockedConnectionMap.h index 449387c1cc..8b2f6dae8e 100644 --- a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.h +++ b/qpid/cpp/src/qpid/cluster/LockedConnectionMap.h @@ -1,5 +1,5 @@ -#ifndef QPID_CLUSTER_CONNECTIONDECODER_H -#define QPID_CLUSTER_CONNECTIONDECODER_H +#ifndef QPID_CLUSTER_LOCKEDCONNECTIONMAP_H +#define QPID_CLUSTER_LOCKEDCONNECTIONMAP_H /* * @@ -22,40 +22,41 @@ * */ -#include "qpid/framing/FrameDecoder.h" -#include <boost/function.hpp> +#include "types.h" +#include "qpid/sys/Mutex.h" +#include "Connection.h" namespace qpid { namespace cluster { -class EventHeader; -class EventFrame; -class ConnectionMap; - /** - * Decodes delivered connection data Event's as EventFrame's for a - * connection replica, local or shadow. Manages state for frame - * fragments and flow control. - * - * THREAD UNSAFE: connection events are decoded in sequence. + * Thread safe map of connections. */ -class ConnectionDecoder +class LockedConnectionMap { public: - typedef boost::function<void(const EventFrame&)> Handler; - - ConnectionDecoder(const Handler& h); - - /** Takes EventHeader + data rather than Event so that the caller can - * pass a pointer to connection data or a CPG buffer directly without copy. - */ - void decode(const EventHeader& eh, const void* data, ConnectionMap& connections); + void insert(const ConnectionPtr& c) { + sys::Mutex::ScopedLock l(lock); + map[c->getId()] = c; + } + + ConnectionPtr getErase(const ConnectionId& c) { + sys::Mutex::ScopedLock l(lock); + Map::iterator i = map.find(c); + if (i != map.end()) { + ConnectionPtr cp = i->second; + map.erase(i); + return cp; + } + else + return 0; + } private: - Handler handler; - framing::FrameDecoder decoder; + typedef std::map<ConnectionId, ConnectionPtr> Map; + mutable sys::Mutex lock; + Map map; }; - }} // namespace qpid::cluster -#endif /*!QPID_CLUSTER_CONNECTIONDECODER_H*/ +#endif /*!QPID_CLUSTER_LOCKEDCONNECTIONMAP_H*/ diff --git a/qpid/cpp/src/qpid/sys/posix/PollableCondition.h b/qpid/cpp/src/qpid/cluster/McastFrameHandler.h index 4ec277b0ec..5127c31c84 100644 --- a/qpid/cpp/src/qpid/sys/posix/PollableCondition.h +++ b/qpid/cpp/src/qpid/cluster/McastFrameHandler.h @@ -1,5 +1,5 @@ -#ifndef QPID_SYS_POSIX_POLLABLECONDITION_H -#define QPID_SYS_POSIX_POLLABLECONDITION_H +#ifndef QPID_CLUSTER_MCASTFRAMEHANDLER_H +#define QPID_CLUSTER_MCASTFRAMEHANDLER_H /* * @@ -22,35 +22,25 @@ * */ -#include "qpid/sys/IOHandle.h" +#include "types.h" +#include "Multicaster.h" +#include "qpid/framing/FrameHandler.h" namespace qpid { -namespace sys { +namespace cluster { /** - * A pollable condition to integrate in-process conditions with IO - * conditions in a polling loop. - * - * Setting the condition makes it readable for a poller. - * - * Writable/disconnected conditions are undefined and should not be - * polled for. + * A frame handler that multicasts frames as CONTROL events. */ -class PollableCondition : public sys::IOHandle { +class McastFrameHandler : public framing::FrameHandler +{ public: - PollableCondition(); - - /** Set the condition, triggers readable in a poller. */ - void set(); - - /** Get the current state of the condition, then clear it. - *@return The state of the condition before it was cleared. - */ - bool clear(); - + McastFrameHandler(Multicaster& m, const ConnectionId& cid) : mcast(m), connection(cid) {} + void handle(framing::AMQFrame& frame) { mcast.mcastControl(frame, connection); } private: - int writeFd; + Multicaster& mcast; + ConnectionId connection; }; -}} // namespace qpid::sys +}} // namespace qpid::cluster -#endif /*!QPID_SYS_POSIX_POLLABLECONDITION_H*/ +#endif /*!QPID_CLUSTER_MCASTFRAMEHANDLER_H*/ diff --git a/qpid/cpp/src/qpid/cluster/Multicaster.cpp b/qpid/cpp/src/qpid/cluster/Multicaster.cpp index 239b3f5f35..f0738ab08f 100644 --- a/qpid/cpp/src/qpid/cluster/Multicaster.cpp +++ b/qpid/cpp/src/qpid/cluster/Multicaster.cpp @@ -24,6 +24,7 @@ #include "qpid/log/Statement.h" #include "qpid/sys/LatencyMetric.h" #include "qpid/framing/AMQBody.h" +#include "qpid/framing/AMQFrame.h" namespace qpid { namespace cluster { @@ -43,6 +44,11 @@ void Multicaster::mcastControl(const framing::AMQBody& body, const ConnectionId& mcast(Event::control(body, id)); } +void Multicaster::mcastControl(const framing::AMQFrame& frame, const ConnectionId& id) { + QPID_LOG(trace, "MCAST " << id << ": " << frame); + mcast(Event::control(frame, id)); +} + void Multicaster::mcastBuffer(const char* data, size_t size, const ConnectionId& id) { Event e(DATA, id, size); memcpy(e.getData(), data, size); diff --git a/qpid/cpp/src/qpid/cluster/Multicaster.h b/qpid/cpp/src/qpid/cluster/Multicaster.h index 1dfee47bd5..d1c3115977 100644 --- a/qpid/cpp/src/qpid/cluster/Multicaster.h +++ b/qpid/cpp/src/qpid/cluster/Multicaster.h @@ -50,6 +50,7 @@ class Multicaster boost::function<void()> onError ); void mcastControl(const framing::AMQBody& controlBody, const ConnectionId&); + void mcastControl(const framing::AMQFrame& controlFrame, const ConnectionId&); void mcastBuffer(const char*, size_t, const ConnectionId&); void mcast(const Event& e); /** End holding mode, held events are mcast */ diff --git a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp index 45a369eea9..cd42446016 100644 --- a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp +++ b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp @@ -70,17 +70,12 @@ void OutputInterceptor::giveReadCredit(int32_t credit) { // Called in write thread when the IO layer has no more data to write. // We do nothing in the write thread, we run doOutput only on delivery // of doOutput requests. -bool OutputInterceptor::doOutput() { - QPID_LOG(trace, parent << " write idle."); - return false; -} +bool OutputInterceptor::doOutput() { return false; } // Delivery of doOutput allows us to run the real connection doOutput() // which tranfers frames to the codec for writing. // void OutputInterceptor::deliverDoOutput(size_t requested) { - QPID_LATENCY_RECORD("deliver do-output", *this); - QPID_LATENCY_CLEAR(*this); size_t buf = getBuffered(); if (parent.isLocal()) writeEstimate.delivered(requested, sent, buf); // Update the estimate. @@ -91,9 +86,7 @@ void OutputInterceptor::deliverDoOutput(size_t requested) { moreOutput = parent.getBrokerConnection().doOutput(); } while (sent < requested && moreOutput); sent += buf; // Include buffered data in the sent total. - - QPID_LOG(trace, "Delivered doOutput: requested=" << requested << " output=" << sent << " more=" << moreOutput); - + QPID_LOG(trace, parent << " delivereDoOutput: requested=" << requested << " sent=" << sent << " more=" << moreOutput); if (parent.isLocal() && moreOutput) { QPID_LOG(trace, parent << " deliverDoOutput - sending doOutput, more output available."); sendDoOutput(); diff --git a/qpid/cpp/src/qpid/cluster/PollableQueue.h b/qpid/cpp/src/qpid/cluster/PollableQueue.h index e0422e2449..a44c39ad85 100644 --- a/qpid/cpp/src/qpid/cluster/PollableQueue.h +++ b/qpid/cpp/src/qpid/cluster/PollableQueue.h @@ -52,6 +52,8 @@ template <class T> class PollableQueue : public sys::PollableQueue<T> { } catch (const std::exception& e) { QPID_LOG(error, message << ": " << e.what()); + values.clear(); + this->stop(); error(); } } diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp index 18746ccb7e..97eae7efa3 100644 --- a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp +++ b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp @@ -22,6 +22,8 @@ #include "Cluster.h" #include "ClusterMap.h" #include "Connection.h" +#include "Decoder.h" +#include "ExpiryPolicy.h" #include "qpid/client/SessionBase_0_10Access.h" #include "qpid/client/ConnectionAccess.h" #include "qpid/broker/Broker.h" @@ -86,33 +88,40 @@ 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, uint64_t frameId_, - const Cluster::Connections& cons, + 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, const client::ConnectionSettings& cs ) : updaterId(updater), updateeId(updatee), updateeUrl(url), updaterBroker(broker), map(m), - frameId(frameId_), connections(cons), + expiry(expiry_), connections(cons), decoder(decoder_), connection(catchUpConnection()), shadowConnection(catchUpConnection()), - done(ok), failed(fail) + done(ok), failed(fail), connectionSettings(cs) { connection.open(url, cs); - session = connection.newSession("update_shared"); + session = connection.newSession(UPDATE); } UpdateClient::~UpdateClient() {} // Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges. -const std::string UpdateClient::UPDATE("qpid.qpid-update"); +const std::string UpdateClient::UPDATE("qpid.cluster-update"); + +void UpdateClient::run() { + try { + update(); + done(); + } catch (const std::exception& e) { + failed(e); + } + delete this; +} void UpdateClient::update() { QPID_LOG(debug, updaterId << " updating state to " << updateeId << " at " << updateeUrl); Broker& b = updaterBroker; b.getExchanges().eachExchange(boost::bind(&UpdateClient::updateExchange, this, _1)); - - // Update exchange is used to route messages to the proper queue without modifying routing key. - session.exchangeDeclare(arg::exchange=UPDATE, arg::type="fanout", arg::autoDelete=true); b.getQueues().eachQueue(boost::bind(&UpdateClient::updateQueue, this, _1)); // Update queue is used to transfer acquired messages that are no longer on their original queue. session.queueDeclare(arg::queue=UPDATE, arg::autoDelete=true); @@ -121,25 +130,15 @@ void UpdateClient::update() { std::for_each(connections.begin(), connections.end(), boost::bind(&UpdateClient::updateConnection, this, _1)); + ClusterConnectionProxy(session).expiryId(expiry.getId()); ClusterConnectionMembershipBody membership; map.toMethodBody(membership); - membership.setFrameId(frameId); AMQFrame frame(membership); client::ConnectionAccess::getImpl(connection)->handle(frame); connection.close(); QPID_LOG(debug, updaterId << " updated state to " << updateeId << " at " << updateeUrl); } -void UpdateClient::run() { - try { - update(); - done(); - } catch (const std::exception& e) { - failed(e); - } - delete this; -} - namespace { template <class T> std::string encode(const T& t) { std::string encoded; @@ -152,8 +151,7 @@ template <class T> std::string encode(const T& t) { void UpdateClient::updateExchange(const boost::shared_ptr<Exchange>& ex) { QPID_LOG(debug, updaterId << " updating exchange " << ex->getName()); - ClusterConnectionProxy proxy(session); - proxy.exchange(encode(*ex)); + ClusterConnectionProxy(session).exchange(encode(*ex)); } /** Bind a queue to the update exchange and update messges to it @@ -164,24 +162,40 @@ class MessageUpdater { bool haveLastPos; framing::SequenceNumber lastPos; client::AsyncSession session; - + ExpiryPolicy& expiry; + public: - MessageUpdater(const string& q, const client::AsyncSession s) : queue(q), haveLastPos(false), session(s) { + MessageUpdater(const string& q, const client::AsyncSession s, ExpiryPolicy& expiry_) : queue(q), haveLastPos(false), session(s), expiry(expiry_) { session.exchangeBind(queue, UpdateClient::UPDATE); } ~MessageUpdater() { - session.exchangeUnbind(queue, UpdateClient::UPDATE); + try { + session.exchangeUnbind(queue, UpdateClient::UPDATE); + } + catch (const std::exception& e) { + // Don't throw in a destructor. + QPID_LOG(error, "Unbinding update queue " << queue << ": " << e.what()); + } } void updateQueuedMessage(const broker::QueuedMessage& message) { + // Send the queue position if necessary. if (!haveLastPos || message.position - lastPos != 1) { ClusterConnectionProxy(session).queuePosition(queue, message.position.getValue()-1); haveLastPos = true; } lastPos = message.position; + + // Send the expiry ID if necessary. + if (message.payload->getProperties<DeliveryProperties>()->getTtl()) { + boost::optional<uint64_t> expiryId = expiry.getId(*message.payload); + if (!expiryId) return; // Message already expired, don't replicate. + ClusterConnectionProxy(session).expiryId(*expiryId); + } + SessionBase_0_10Access sb(session); framing::MessageTransferBody transfer( framing::ProtocolVersion(), UpdateClient::UPDATE, message::ACCEPT_MODE_NONE, message::ACQUIRE_MODE_PRE_ACQUIRED); @@ -204,16 +218,13 @@ class MessageUpdater { void updateMessage(const boost::intrusive_ptr<broker::Message>& message) { updateQueuedMessage(broker::QueuedMessage(0, message, haveLastPos? lastPos.getValue()+1 : 1)); } - - }; - void UpdateClient::updateQueue(const boost::shared_ptr<Queue>& q) { QPID_LOG(debug, updaterId << " updating queue " << q->getName()); ClusterConnectionProxy proxy(session); proxy.queue(encode(*q)); - MessageUpdater updater(q->getName(), session); + MessageUpdater updater(q->getName(), session, expiry); q->eachMessage(boost::bind(&MessageUpdater::updateQueuedMessage, &updater, _1)); q->eachBinding(boost::bind(&UpdateClient::updateBinding, this, q->getName(), _1)); } @@ -228,13 +239,16 @@ void UpdateClient::updateConnection(const boost::intrusive_ptr<Connection>& upda shadowConnection = catchUpConnection(); broker::Connection& bc = updateConnection->getBrokerConnection(); - // FIXME aconway 2008-10-20: What authentication info to use on reconnect? - shadowConnection.open(updateeUrl, bc.getUserId(), ""/*password*/, "/"/*vhost*/, bc.getFrameMax()); + connectionSettings.maxFrameSize = bc.getFrameMax(); + shadowConnection.open(updateeUrl, connectionSettings); bc.eachSessionHandler(boost::bind(&UpdateClient::updateSession, this, _1)); + // Safe to use decoder here because we are stalled for update. + std::pair<const char*, size_t> fragment = decoder.get(updateConnection->getId()).getFragment(); ClusterConnectionProxy(shadowConnection).shadowReady( updateConnection->getId().getMember(), - reinterpret_cast<uint64_t>(updateConnection->getId().getPointer()), - updateConnection->getBrokerConnection().getUserId() + updateConnection->getId().getNumber(), + bc.getUserId(), + string(fragment.first, fragment.second) ); shadowConnection.close(); QPID_LOG(debug, updaterId << " updated connection " << *updateConnection); @@ -269,7 +283,7 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) { SequenceNumber received = ss->receiverGetReceived().command; if (inProgress) --received; - + // Reset command-sequence state. proxy.sessionState( ss->senderGetReplayPoint().command, @@ -285,9 +299,6 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) { if (inProgress) { inProgress->getFrames().map(simpl->out); } - - // FIXME aconway 2008-09-23: update session replay list. - QPID_LOG(debug, updaterId << " updated session " << sh.getSession()->getId()); } @@ -322,7 +333,7 @@ void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) { // If the message is acquired then it is no longer on the // updatees queue, put it on the update queue for updatee to pick up. // - MessageUpdater(UPDATE, shadowSession).updateQueuedMessage(dr.getMessage()); + MessageUpdater(UPDATE, shadowSession, expiry).updateQueuedMessage(dr.getMessage()); } ClusterConnectionProxy(shadowSession).deliveryRecord( dr.getQueue()->getName(), @@ -341,8 +352,8 @@ void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) { class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater { public: - TxOpUpdater(UpdateClient& dc, client::AsyncSession s) - : MessageUpdater(UpdateClient::UPDATE, s), parent(dc), session(s), proxy(s) {} + TxOpUpdater(UpdateClient& dc, client::AsyncSession s, ExpiryPolicy& expiry) + : MessageUpdater(UpdateClient::UPDATE, s, expiry), parent(dc), session(s), proxy(s) {} void operator()(const broker::DtxAck& ) { throw InternalErrorException("DTX transactions not currently supported by cluster."); @@ -385,7 +396,7 @@ void UpdateClient::updateTxState(broker::SemanticState& s) { broker::TxBuffer::shared_ptr txBuffer = s.getTxBuffer(); if (txBuffer) { proxy.txStart(); - TxOpUpdater updater(*this, shadowSession); + TxOpUpdater updater(*this, shadowSession, expiry); txBuffer->accept(updater); proxy.txEnd(); } diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.h b/qpid/cpp/src/qpid/cluster/UpdateClient.h index 23f647c820..23d061b7e4 100644 --- a/qpid/cpp/src/qpid/cluster/UpdateClient.h +++ b/qpid/cpp/src/qpid/cluster/UpdateClient.h @@ -46,6 +46,7 @@ class SessionHandler; class DeliveryRecord; class SessionState; class SemanticState; +class Decoder; } // namespace broker @@ -54,6 +55,8 @@ namespace cluster { class Cluster; class Connection; class ClusterMap; +class Decoder; +class ExpiryPolicy; /** * A client that updates the contents of a local broker to a remote one using AMQP. @@ -63,8 +66,8 @@ class UpdateClient : public sys::Runnable { static const std::string UPDATE; // Name for special update queue and exchange. UpdateClient(const MemberId& updater, const MemberId& updatee, const Url&, - broker::Broker& donor, const ClusterMap& map, uint64_t sequence, - const std::vector<boost::intrusive_ptr<Connection> >& , + 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& @@ -92,12 +95,14 @@ class UpdateClient : public sys::Runnable { Url updateeUrl; broker::Broker& updaterBroker; ClusterMap map; - uint64_t frameId; + ExpiryPolicy& expiry; std::vector<boost::intrusive_ptr<Connection> > connections; + Decoder& decoder; client::Connection connection, shadowConnection; client::AsyncSession session, shadowSession; boost::function<void()> done; boost::function<void(const std::exception& e)> failed; + client::ConnectionSettings connectionSettings; }; }} // namespace qpid::cluster diff --git a/qpid/cpp/src/qpid/cluster/UpdateExchange.h b/qpid/cpp/src/qpid/cluster/UpdateExchange.h new file mode 100644 index 0000000000..7a4a484c8a --- /dev/null +++ b/qpid/cpp/src/qpid/cluster/UpdateExchange.h @@ -0,0 +1,45 @@ +#ifndef QPID_CLUSTER_UPDATEEXCHANGE_H +#define QPID_CLUSTER_UPDATEEXCHANGE_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 "UpdateClient.h" +#include "qpid/broker/FanOutExchange.h" + + +namespace qpid { +namespace cluster { + +/** + * A keyless exchange (like fanout exchange) that does not modify deliver-properties.exchange + * on messages. + */ +class UpdateExchange : public broker::FanOutExchange +{ + public: + UpdateExchange(management::Manageable* parent) : broker::Exchange(UpdateClient::UPDATE, parent), broker::FanOutExchange(UpdateClient::UPDATE, parent) {} + void setProperties(const boost::intrusive_ptr<broker::Message>&) {} +}; + +}} // namespace qpid::cluster + +#endif /*!QPID_CLUSTER_UPDATEEXCHANGE_H*/ diff --git a/qpid/cpp/src/qpid/cluster/types.h b/qpid/cpp/src/qpid/cluster/types.h index d1d6fdc427..c19152e4d8 100644 --- a/qpid/cpp/src/qpid/cluster/types.h +++ b/qpid/cpp/src/qpid/cluster/types.h @@ -68,16 +68,17 @@ inline bool operator==(const cpg_address& caddr, const MemberId& id) { return id std::ostream& operator<<(std::ostream&, const MemberId&); -struct ConnectionId : public std::pair<MemberId, Connection*> { - ConnectionId(const MemberId& m=MemberId(), Connection* c=0) : std::pair<MemberId, Connection*> (m,c) {} - ConnectionId(uint64_t m, uint64_t c) - : std::pair<MemberId, Connection*>(MemberId(m), reinterpret_cast<Connection*>(c)) {} +struct ConnectionId : public std::pair<MemberId, uint64_t> { + ConnectionId(const MemberId& m=MemberId(), uint64_t c=0) : std::pair<MemberId, uint64_t> (m,c) {} + ConnectionId(uint64_t m, uint64_t c) : std::pair<MemberId, uint64_t>(MemberId(m), c) {} MemberId getMember() const { return first; } - Connection* getPointer() const { return second; } + uint64_t getNumber() const { return second; } }; std::ostream& operator<<(std::ostream&, const ConnectionId&); +std::ostream& operator<<(std::ostream&, EventType); + }} // namespace qpid::cluster #endif /*!QPID_CLUSTER_TYPES_H*/ diff --git a/qpid/cpp/src/qpid/console/Agent.h b/qpid/cpp/src/qpid/console/Agent.h index 3307a1b44b..884d4c92bd 100644 --- a/qpid/cpp/src/qpid/console/Agent.h +++ b/qpid/cpp/src/qpid/console/Agent.h @@ -22,6 +22,7 @@ #define _QPID_CONSOLE_AGENT_H_ #include "Broker.h" +#include "ConsoleImportExport.h" namespace qpid { namespace console { @@ -30,7 +31,7 @@ namespace console { * * \ingroup qmfconsoleapi */ - class Agent { + class QPID_CONSOLE_EXTERN Agent { public: typedef std::vector<Agent*> Vector; @@ -49,7 +50,7 @@ namespace console { const std::string label; }; - std::ostream& operator<<(std::ostream& o, const Agent& agent); + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Agent& agent); } } diff --git a/qpid/cpp/src/qpid/console/Broker.h b/qpid/cpp/src/qpid/console/Broker.h index 9df2380dff..ddbd973dfe 100644 --- a/qpid/cpp/src/qpid/console/Broker.h +++ b/qpid/cpp/src/qpid/console/Broker.h @@ -21,6 +21,7 @@ #ifndef _QPID_CONSOLE_BROKER_H_ #define _QPID_CONSOLE_BROKER_H_ +#include "ConsoleImportExport.h" #include "qpid/client/Connection.h" #include "qpid/client/ConnectionSettings.h" #include "qpid/client/SubscriptionManager.h" @@ -50,8 +51,9 @@ namespace console { */ class Broker : public client::MessageListener { public: - Broker(SessionManager& sm, client::ConnectionSettings& settings); - ~Broker(); + QPID_CONSOLE_EXTERN Broker(SessionManager& sm, + client::ConnectionSettings& settings); + QPID_CONSOLE_EXTERN ~Broker(); bool isConnected() const { return connected; } const std::string& getError() const { return error; } @@ -61,7 +63,7 @@ namespace console { void addBinding(const std::string& key) { connThreadBody.bindExchange("qpid.management", key); } - std::string getUrl() const; + QPID_CONSOLE_EXTERN std::string getUrl() const; private: friend class SessionManager; @@ -120,10 +122,10 @@ namespace console { void setBrokerId(const framing::Uuid& id) { brokerId = id; } void appendAgents(std::vector<Agent*>& agents) const; - friend std::ostream& operator<<(std::ostream& o, const Broker& k); + friend QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Broker& k); }; - std::ostream& operator<<(std::ostream& o, const Broker& k); + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Broker& k); } } diff --git a/qpid/cpp/src/qpid/console/ClassKey.cpp b/qpid/cpp/src/qpid/console/ClassKey.cpp index 1780b03f94..b97eb3ca44 100644 --- a/qpid/cpp/src/qpid/console/ClassKey.cpp +++ b/qpid/cpp/src/qpid/console/ClassKey.cpp @@ -21,6 +21,7 @@ #include "ClassKey.h" #include <string.h> +#include <cstdio> using namespace std; using namespace qpid::console; diff --git a/qpid/cpp/src/qpid/console/ClassKey.h b/qpid/cpp/src/qpid/console/ClassKey.h index f6617e22d5..821b01c4ef 100644 --- a/qpid/cpp/src/qpid/console/ClassKey.h +++ b/qpid/cpp/src/qpid/console/ClassKey.h @@ -22,6 +22,7 @@ #define _QPID_CONSOLE_CLASSKEY_H_ #include <string> +#include "ConsoleImportExport.h" #include "Package.h" #include "qpid/framing/Buffer.h" @@ -32,7 +33,7 @@ namespace console { * * \ingroup qmfconsoleapi */ - class ClassKey { + class QPID_CONSOLE_EXTERN ClassKey { public: static const int HASH_SIZE = 16; @@ -57,7 +58,7 @@ namespace console { uint8_t hash[HASH_SIZE]; }; - std::ostream& operator<<(std::ostream& o, const ClassKey& k); + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ClassKey& k); } } diff --git a/qpid/cpp/src/qpid/console/ConsoleImportExport.h b/qpid/cpp/src/qpid/console/ConsoleImportExport.h new file mode 100644 index 0000000000..e2d0af9db3 --- /dev/null +++ b/qpid/cpp/src/qpid/console/ConsoleImportExport.h @@ -0,0 +1,33 @@ +#ifndef QPID_CONSOLE_IMPORT_EXPORT_H +#define QPID_CONSOLE_IMPORT_EXPORT_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. + */ + +#if defined(WIN32) && !defined(QPID_DECLARE_STATIC) +#if defined(CONSOLE_EXPORT) +#define QPID_CONSOLE_EXTERN __declspec(dllexport) +#else +#define QPID_CONSOLE_EXTERN __declspec(dllimport) +#endif +#else +#define QPID_CONSOLE_EXTERN +#endif + +#endif diff --git a/qpid/cpp/src/qpid/console/ConsoleListener.h b/qpid/cpp/src/qpid/console/ConsoleListener.h index d0db6034f6..d661c63120 100644 --- a/qpid/cpp/src/qpid/console/ConsoleListener.h +++ b/qpid/cpp/src/qpid/console/ConsoleListener.h @@ -22,6 +22,7 @@ #define _QPID_CONSOLE_CONSOLE_LISTENER_H_ #include <string> +#include "ConsoleImportExport.h" #include "Broker.h" #include "ClassKey.h" #include "Object.h" @@ -36,7 +37,7 @@ namespace console { * * \ingroup qmfconsoleapi */ - class ConsoleListener{ + class QPID_CONSOLE_EXTERN ConsoleListener{ public: virtual ~ConsoleListener() {}; diff --git a/qpid/cpp/src/qpid/console/Event.h b/qpid/cpp/src/qpid/console/Event.h index 14f5a64716..4d51708965 100644 --- a/qpid/cpp/src/qpid/console/Event.h +++ b/qpid/cpp/src/qpid/console/Event.h @@ -21,6 +21,7 @@ #ifndef _QPID_CONSOLE_EVENT_H_ #define _QPID_CONSOLE_EVENT_H_ +#include "ConsoleImportExport.h" #include "Object.h" #include "qpid/framing/Uuid.h" #include "qpid/framing/FieldTable.h" @@ -46,26 +47,28 @@ namespace console { SEV_WARNING = 4, SEV_NOTICE = 5, SEV_INFO = 6, SEV_DEBUG = 7 } Severity; - Event(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer); + QPID_CONSOLE_EXTERN Event(Broker* broker, + SchemaClass* schemaClass, + framing::Buffer& buffer); Broker* getBroker() const { return broker; } - const ClassKey& getClassKey() const; + QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const; SchemaClass* getSchema() const { return schema; } const Object::AttributeMap& getAttributes() const { return attributes; } uint64_t getTimestamp() const { return timestamp; } uint8_t getSeverity() const { return severity; } - std::string getSeverityString() const; + QPID_CONSOLE_EXTERN std::string getSeverityString() const; - ObjectId attrRef(const std::string& key) const; - uint32_t attrUint(const std::string& key) const; - int32_t attrInt(const std::string& key) const; - uint64_t attrUint64(const std::string& key) const; - int64_t attrInt64(const std::string& key) const; - std::string attrString(const std::string& key) const; - bool attrBool(const std::string& key) const; - float attrFloat(const std::string& key) const; - double attrDouble(const std::string& key) const; - framing::Uuid attrUuid(const std::string& key) const; - framing::FieldTable attrMap(const std::string& key) const; + QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const; + QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const; + QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const; + QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const; + QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const; + QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const; + QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const; + QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const; + QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const; private: Broker* broker; @@ -75,7 +78,7 @@ namespace console { Object::AttributeMap attributes; }; - std::ostream& operator<<(std::ostream& o, const Event& event); + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Event& event); } } diff --git a/qpid/cpp/src/qpid/console/Object.h b/qpid/cpp/src/qpid/console/Object.h index 2c6993fc8a..d2fb09ecca 100644 --- a/qpid/cpp/src/qpid/console/Object.h +++ b/qpid/cpp/src/qpid/console/Object.h @@ -21,6 +21,7 @@ #ifndef _QPID_CONSOLE_OBJECT_H_ #define _QPID_CONSOLE_OBJECT_H_ +#include "ConsoleImportExport.h" #include "ObjectId.h" #include "qpid/framing/Uuid.h" #include "qpid/framing/FieldTable.h" @@ -55,47 +56,50 @@ namespace console { public: typedef std::vector<Object> Vector; struct AttributeMap : public std::map<std::string, boost::shared_ptr<Value> > { - void addRef(const std::string& key, const ObjectId& val); - void addUint(const std::string& key, uint32_t val); - void addInt(const std::string& key, int32_t val); - void addUint64(const std::string& key, uint64_t val); - void addInt64(const std::string& key, int64_t val); - void addString(const std::string& key, const std::string& val); - void addBool(const std::string& key, bool val); - void addFloat(const std::string& key, float val); - void addDouble(const std::string& key, double val); - void addUuid(const std::string& key, const framing::Uuid& val); - void addMap(const std::string& key, const framing::FieldTable& val); + QPID_CONSOLE_EXTERN void addRef(const std::string& key, const ObjectId& val); + QPID_CONSOLE_EXTERN void addUint(const std::string& key, uint32_t val); + QPID_CONSOLE_EXTERN void addInt(const std::string& key, int32_t val); + QPID_CONSOLE_EXTERN void addUint64(const std::string& key, uint64_t val); + QPID_CONSOLE_EXTERN void addInt64(const std::string& key, int64_t val); + QPID_CONSOLE_EXTERN void addString(const std::string& key, const std::string& val); + QPID_CONSOLE_EXTERN void addBool(const std::string& key, bool val); + QPID_CONSOLE_EXTERN void addFloat(const std::string& key, float val); + QPID_CONSOLE_EXTERN void addDouble(const std::string& key, double val); + QPID_CONSOLE_EXTERN void addUuid(const std::string& key, const framing::Uuid& val); + QPID_CONSOLE_EXTERN void addMap(const std::string& key, const framing::FieldTable& val); }; - Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat); - ~Object(); + QPID_CONSOLE_EXTERN Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat); + QPID_CONSOLE_EXTERN ~Object(); Broker* getBroker() const { return broker; } const ObjectId& getObjectId() const { return objectId; } - const ClassKey& getClassKey() const; + QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const; SchemaClass* getSchema() const { return schema; } uint64_t getCurrentTime() const { return currentTime; } uint64_t getCreateTime() const { return createTime; } uint64_t getDeleteTime() const { return deleteTime; } bool isDeleted() const { return deleteTime != 0; } - std::string getIndex() const; - void mergeUpdate(const Object& updated); + QPID_CONSOLE_EXTERN std::string getIndex() const; + QPID_CONSOLE_EXTERN void mergeUpdate(const Object& updated); const AttributeMap& getAttributes() const { return attributes; } - void invokeMethod(const std::string name, const AttributeMap& args, MethodResponse& result); - void handleMethodResp(framing::Buffer& buffer, uint32_t sequence); + QPID_CONSOLE_EXTERN void invokeMethod(const std::string name, + const AttributeMap& args, + MethodResponse& result); + QPID_CONSOLE_EXTERN void handleMethodResp(framing::Buffer& buffer, + uint32_t sequence); - ObjectId attrRef(const std::string& key) const; - uint32_t attrUint(const std::string& key) const; - int32_t attrInt(const std::string& key) const; - uint64_t attrUint64(const std::string& key) const; - int64_t attrInt64(const std::string& key) const; - std::string attrString(const std::string& key) const; - bool attrBool(const std::string& key) const; - float attrFloat(const std::string& key) const; - double attrDouble(const std::string& key) const; - framing::Uuid attrUuid(const std::string& key) const; - framing::FieldTable attrMap(const std::string& key) const; + QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const; + QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const; + QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const; + QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const; + QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const; + QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const; + QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const; + QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const; + QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const; private: Broker* broker; @@ -111,7 +115,7 @@ namespace console { void parsePresenceMasks(framing::Buffer& buffer, std::set<std::string>& excludeList); }; - std::ostream& operator<<(std::ostream& o, const Object& object); + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Object& object); } } diff --git a/qpid/cpp/src/qpid/console/ObjectId.h b/qpid/cpp/src/qpid/console/ObjectId.h index 73304ca306..ac0e8d8b03 100644 --- a/qpid/cpp/src/qpid/console/ObjectId.h +++ b/qpid/cpp/src/qpid/console/ObjectId.h @@ -22,6 +22,7 @@ #define _QPID_CONSOLE_OBJECTID_H #include <iostream> +#include "ConsoleImportExport.h" #include "qpid/sys/IntegerTypes.h" namespace qpid { @@ -34,7 +35,7 @@ namespace console { * * \ingroup qmfconsoleapi */ - class ObjectId { + class QPID_CONSOLE_EXTERN ObjectId { public: ObjectId() : first(0), second(0) {} ObjectId(framing::Buffer& buffer); @@ -61,7 +62,7 @@ namespace console { uint64_t second; }; - std::ostream& operator<<(std::ostream& o, const ObjectId& id); + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ObjectId& id); } } diff --git a/qpid/cpp/src/qpid/console/Package.h b/qpid/cpp/src/qpid/console/Package.h index 18203cb807..3cc63c8b75 100644 --- a/qpid/cpp/src/qpid/console/Package.h +++ b/qpid/cpp/src/qpid/console/Package.h @@ -23,6 +23,7 @@ #include <string> #include <map> +#include "ConsoleImportExport.h" #include "qpid/sys/IntegerTypes.h" namespace qpid { diff --git a/qpid/cpp/src/qpid/console/SequenceManager.h b/qpid/cpp/src/qpid/console/SequenceManager.h index c7a8c20fe6..5a041f530b 100644 --- a/qpid/cpp/src/qpid/console/SequenceManager.h +++ b/qpid/cpp/src/qpid/console/SequenceManager.h @@ -21,6 +21,7 @@ #ifndef _QPID_CONSOLE_SEQUENCEMANAGER_H_ #define _QPID_CONSOLE_SEQUENCEMANAGER_H_ +#include "ConsoleImportExport.h" #include "qpid/sys/Mutex.h" #include <map> #include <string> @@ -38,8 +39,8 @@ namespace console { typedef std::set<uint32_t> set; SequenceManager() : sequence(0) {} - uint32_t reserve(const std::string& context = ""); - std::string release(uint32_t seq); + QPID_CONSOLE_EXTERN uint32_t reserve(const std::string& context = ""); + QPID_CONSOLE_EXTERN std::string release(uint32_t seq); private: sys::Mutex lock; diff --git a/qpid/cpp/src/qpid/console/SessionManager.h b/qpid/cpp/src/qpid/console/SessionManager.h index ab6e111caa..4341fe317c 100644 --- a/qpid/cpp/src/qpid/console/SessionManager.h +++ b/qpid/cpp/src/qpid/console/SessionManager.h @@ -22,6 +22,7 @@ * */ +#include "ConsoleImportExport.h" #include "Broker.h" #include "Package.h" #include "SequenceManager.h" @@ -80,8 +81,8 @@ class SessionManager * and bindClass methods. If userBindings is false, the listener will receive * updates for all object classes. */ - SessionManager(ConsoleListener* listener = 0, - Settings settings = Settings()); + QPID_CONSOLE_EXTERN SessionManager(ConsoleListener* listener = 0, + Settings settings = Settings()); /** Connect a broker to the console session * @@ -89,32 +90,33 @@ class SessionManager *@return broker object if operation is successful * an exception shall be thrown. */ - Broker* addBroker(client::ConnectionSettings& settings); + QPID_CONSOLE_EXTERN Broker* addBroker(client::ConnectionSettings& settings); /** Disconnect a broker from the console session * *@param broker The broker object returned from an earlier call to addBroker. */ - void delBroker(Broker* broker); + QPID_CONSOLE_EXTERN void delBroker(Broker* broker); /** Get a list of known management packages * *@param packages Vector of package names returned by the session manager. */ - void getPackages(NameVector& packages); + QPID_CONSOLE_EXTERN void getPackages(NameVector& packages); /** Get a list of class keys associated with a package * *@param classKeys List of class keys returned by the session manager. *@param packageName Name of package being queried. */ - void getClasses(KeyVector& classKeys, const std::string& packageName); + QPID_CONSOLE_EXTERN void getClasses(KeyVector& classKeys, + const std::string& packageName); /** Get the schema of a class given its class key * *@param classKey Class key of the desired schema. */ - SchemaClass& getSchema(const ClassKey& classKey); + QPID_CONSOLE_EXTERN SchemaClass& getSchema(const ClassKey& classKey); /** Request that updates be received for all classes within a package * @@ -123,7 +125,7 @@ class SessionManager * *@param packageName Name of the package to which to bind. */ - void bindPackage(const std::string& packageName); + QPID_CONSOLE_EXTERN void bindPackage(const std::string& packageName); /** Request update to be received for a particular class * @@ -132,8 +134,9 @@ class SessionManager * *@param classKey Class key of class to which to bind. */ - void bindClass(const ClassKey& classKey); - void bindClass(const std::string& packageName, const std::string& className); + QPID_CONSOLE_EXTERN void bindClass(const ClassKey& classKey); + QPID_CONSOLE_EXTERN void bindClass(const std::string& packageName, + const std::string& className); /** Get a list of qmf agents known to the session manager. * @@ -141,7 +144,8 @@ class SessionManager *@param broker Return agents registered with this broker only. If NULL, return agents * from all connected brokers. */ - void getAgents(Agent::Vector& agents, Broker* broker = 0); + QPID_CONSOLE_EXTERN void getAgents(Agent::Vector& agents, + Broker* broker = 0); /** Get objects from agents. There are four variants of this method with different ways of * specifying from which class objects are being queried. @@ -153,8 +157,10 @@ class SessionManager *@param broker Restrict the query to this broker, or all brokers if NULL. *@param agent Restrict the query to this agent, or all agents if NULL. */ - void getObjects(Object::Vector& objects, const std::string& className, - Broker* broker = 0, Agent* agent = 0); + QPID_CONSOLE_EXTERN void getObjects(Object::Vector& objects, + const std::string& className, + Broker* broker = 0, + Agent* agent = 0); //void getObjects(Object::Vector& objects, const ClassKey& classKey, // Broker* broker = 0, Agent* agent = 0); //void getObjects(Object::Vector& objects, const ObjectId& objectId, diff --git a/qpid/cpp/src/qpid/framing/AMQBody.h b/qpid/cpp/src/qpid/framing/AMQBody.h index 9e66b9738f..60ac2d3b7e 100644 --- a/qpid/cpp/src/qpid/framing/AMQBody.h +++ b/qpid/cpp/src/qpid/framing/AMQBody.h @@ -26,6 +26,7 @@ #include "qpid/framing/BodyFactory.h" #include <boost/intrusive_ptr.hpp> #include <ostream> +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -48,7 +49,7 @@ struct AMQBodyConstVisitor { class AMQBody : public RefCounted { public: AMQBody() {} - virtual ~AMQBody(); + QPID_COMMON_EXTERN virtual ~AMQBody(); // Make AMQBody copyable even though RefCounted. AMQBody(const AMQBody&) : RefCounted() {} @@ -71,7 +72,7 @@ class AMQBody : public RefCounted { virtual boost::intrusive_ptr<AMQBody> clone() const = 0; }; -std::ostream& operator<<(std::ostream& out, const AMQBody& body) ; +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const AMQBody& body) ; enum BodyTypes { METHOD_BODY = 1, diff --git a/qpid/cpp/src/qpid/framing/AMQContentBody.h b/qpid/cpp/src/qpid/framing/AMQContentBody.h index a81cf36168..9606ae5ec5 100644 --- a/qpid/cpp/src/qpid/framing/AMQContentBody.h +++ b/qpid/cpp/src/qpid/framing/AMQContentBody.h @@ -21,6 +21,7 @@ #include "amqp_types.h" #include "AMQBody.h" #include "Buffer.h" +#include "qpid/CommonImportExport.h" #ifndef _AMQContentBody_ #define _AMQContentBody_ @@ -33,18 +34,18 @@ class AMQContentBody : public AMQBody string data; public: - AMQContentBody(); - AMQContentBody(const string& data); + QPID_COMMON_EXTERN AMQContentBody(); + QPID_COMMON_EXTERN AMQContentBody(const string& data); inline virtual ~AMQContentBody(){} - inline uint8_t type() const { return CONTENT_BODY; }; - inline const string& getData() const { return data; } - inline string& getData() { return data; } - uint32_t encodedSize() const; - void encode(Buffer& buffer) const; - void decode(Buffer& buffer, uint32_t size); - void print(std::ostream& out) const; - void accept(AMQBodyConstVisitor& v) const { v.visit(*this); } - boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); } + QPID_COMMON_EXTERN inline uint8_t type() const { return CONTENT_BODY; }; + QPID_COMMON_EXTERN inline const string& getData() const { return data; } + QPID_COMMON_EXTERN inline string& getData() { return data; } + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size); + QPID_COMMON_EXTERN void print(std::ostream& out) const; + QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor& v) const { v.visit(*this); } + QPID_COMMON_EXTERN boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); } }; } diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.cpp b/qpid/cpp/src/qpid/framing/AMQFrame.cpp index 80c8e0b56d..9473b2a513 100644 --- a/qpid/cpp/src/qpid/framing/AMQFrame.cpp +++ b/qpid/cpp/src/qpid/framing/AMQFrame.cpp @@ -41,7 +41,7 @@ AMQFrame::AMQFrame(const boost::intrusive_ptr<AMQBody>& b) : body(b) { init(); } AMQFrame::AMQFrame(const AMQBody& b) : body(b.clone()) { init(); } -AMQFrame::~AMQFrame() {} +AMQFrame::~AMQFrame() { init(); } AMQBody* AMQFrame::getBody() { // Non-const AMQBody* may be used to modify the body. diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.h b/qpid/cpp/src/qpid/framing/AMQFrame.h index 028d0c1d8a..34319e7ed4 100644 --- a/qpid/cpp/src/qpid/framing/AMQFrame.h +++ b/qpid/cpp/src/qpid/framing/AMQFrame.h @@ -29,6 +29,7 @@ #include "qpid/sys/LatencyMetric.h" #include <boost/intrusive_ptr.hpp> #include <boost/cast.hpp> +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -36,15 +37,15 @@ namespace framing { class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp { public: - AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0); - AMQFrame(const AMQBody& b); - ~AMQFrame(); + QPID_COMMON_EXTERN AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0); + QPID_COMMON_EXTERN AMQFrame(const AMQBody& b); + QPID_COMMON_EXTERN ~AMQFrame(); ChannelId getChannel() const { return channel; } void setChannel(ChannelId c) { channel = c; } - AMQBody* getBody(); - const AMQBody* getBody() const; + QPID_COMMON_EXTERN AMQBody* getBody(); + QPID_COMMON_EXTERN const AMQBody* getBody() const; AMQMethodBody* getMethod() { return getBody()->getMethod(); } const AMQMethodBody* getMethod() const { return getBody()->getMethod(); } @@ -59,9 +60,9 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp return boost::polymorphic_downcast<const T*>(getBody()); } - void encode(Buffer& buffer) const; - bool decode(Buffer& buffer); - uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN bool decode(Buffer& buffer); + QPID_COMMON_EXTERN uint32_t encodedSize() const; // 0-10 terminology: first/last frame (in segment) first/last segment (in assembly) @@ -88,13 +89,10 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp void setEos(bool isEos) { eos = isEos; } static uint16_t DECODE_SIZE_MIN; - static uint32_t frameOverhead(); + QPID_COMMON_EXTERN static uint32_t frameOverhead(); /** Must point to at least DECODE_SIZE_MIN bytes of data */ static uint16_t decodeSize(char* data); - uint64_t getClusterId() const { return clusterId; } - void setClusterId(uint64_t id) { clusterId = id; } - private: void init(); @@ -106,10 +104,9 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp bool bos : 1; bool eos : 1; mutable uint32_t encodedSizeCache; - uint64_t clusterId; // Used to identify frames in a clustered broekr. }; -std::ostream& operator<<(std::ostream&, const AMQFrame&); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const AMQFrame&); }} // namespace qpid::framing diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h index 9846544949..b8099f2e51 100644 --- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h +++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h @@ -26,6 +26,7 @@ #include "Buffer.h" #include "qpid/framing/DeliveryProperties.h" #include "qpid/framing/MessageProperties.h" +#include "qpid/CommonImportExport.h" #include <iostream> #include <boost/optional.hpp> @@ -83,12 +84,12 @@ public: inline uint8_t type() const { return HEADER_BODY; } - uint32_t encodedSize() const; - void encode(Buffer& buffer) const; - void decode(Buffer& buffer, uint32_t size); - uint64_t getContentLength() const; - void print(std::ostream& out) const; - void accept(AMQBodyConstVisitor&) const; + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size); + QPID_COMMON_EXTERN uint64_t getContentLength() const; + QPID_COMMON_EXTERN void print(std::ostream& out) const; + QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor&) const; template <class T> T* get(bool create) { boost::optional<T>& p=properties.OptProps<T>::props; diff --git a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h index 3fb41c128e..5d3f633576 100644 --- a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h +++ b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h @@ -21,6 +21,7 @@ #include "amqp_types.h" #include "AMQBody.h" #include "Buffer.h" +#include "qpid/CommonImportExport.h" #ifndef _AMQHeartbeatBody_ #define _AMQHeartbeatBody_ @@ -31,12 +32,12 @@ namespace framing { class AMQHeartbeatBody : public AMQBody { public: - virtual ~AMQHeartbeatBody(); + QPID_COMMON_EXTERN virtual ~AMQHeartbeatBody(); inline uint32_t encodedSize() const { return 0; } inline uint8_t type() const { return HEARTBEAT_BODY; } inline void encode(Buffer& ) const {} inline void decode(Buffer& , uint32_t /*size*/) {} - virtual void print(std::ostream& out) const; + QPID_COMMON_EXTERN virtual void print(std::ostream& out) const; void accept(AMQBodyConstVisitor& v) const { v.visit(*this); } boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); } }; diff --git a/qpid/cpp/src/qpid/framing/AMQMethodBody.h b/qpid/cpp/src/qpid/framing/AMQMethodBody.h index cc7489ddd9..a38726b0fc 100644 --- a/qpid/cpp/src/qpid/framing/AMQMethodBody.h +++ b/qpid/cpp/src/qpid/framing/AMQMethodBody.h @@ -25,7 +25,7 @@ #include "AMQBody.h" #include "qpid/framing/ProtocolVersion.h" #include "qpid/shared_ptr.h" - +#include "qpid/CommonImportExport.h" #include <ostream> #include <assert.h> @@ -40,7 +40,7 @@ class MethodBodyConstVisitor; class AMQMethodBody : public AMQBody { public: AMQMethodBody() {} - virtual ~AMQMethodBody(); + QPID_COMMON_EXTERN virtual ~AMQMethodBody(); virtual void accept(MethodBodyConstVisitor&) const = 0; diff --git a/qpid/cpp/src/qpid/framing/AccumulatedAck.h b/qpid/cpp/src/qpid/framing/AccumulatedAck.h index ea78b797e0..ede73897c7 100644 --- a/qpid/cpp/src/qpid/framing/AccumulatedAck.h +++ b/qpid/cpp/src/qpid/framing/AccumulatedAck.h @@ -27,6 +27,7 @@ #include <ostream> #include "SequenceNumber.h" #include "SequenceNumberSet.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -58,17 +59,17 @@ namespace qpid { */ std::list<Range> ranges; - explicit AccumulatedAck(SequenceNumber r = SequenceNumber()); - void update(SequenceNumber firstTag, SequenceNumber lastTag); - void consolidate(); - void clear(); - bool covers(SequenceNumber tag) const; + QPID_COMMON_EXTERN explicit AccumulatedAck(SequenceNumber r = SequenceNumber()); + QPID_COMMON_EXTERN void update(SequenceNumber firstTag, SequenceNumber lastTag); + QPID_COMMON_EXTERN void consolidate(); + QPID_COMMON_EXTERN void clear(); + QPID_COMMON_EXTERN bool covers(SequenceNumber tag) const; void collectRanges(SequenceNumberSet& set) const; - void update(const SequenceNumber cumulative, const SequenceNumberSet& range); + QPID_COMMON_EXTERN void update(const SequenceNumber cumulative, const SequenceNumberSet& range); void operator()(SequenceNumber first, SequenceNumber last) { update(first, last); } }; - std::ostream& operator<<(std::ostream&, const Range&); - std::ostream& operator<<(std::ostream&, const AccumulatedAck&); + QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const Range&); + QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const AccumulatedAck&); } } diff --git a/qpid/cpp/src/qpid/framing/Array.h b/qpid/cpp/src/qpid/framing/Array.h index 183fcb6d5c..0b6b704ed2 100644 --- a/qpid/cpp/src/qpid/framing/Array.h +++ b/qpid/cpp/src/qpid/framing/Array.h @@ -24,6 +24,7 @@ #include <boost/shared_ptr.hpp> #include <iostream> #include <vector> +#include "qpid/CommonImportExport.h" #ifndef _Array_ #define _Array_ @@ -41,38 +42,38 @@ class Array typedef ValueVector::const_iterator const_iterator; typedef ValueVector::iterator iterator; - uint32_t encodedSize() const; - void encode(Buffer& buffer) const; - void decode(Buffer& buffer); + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer); - int count() const; - bool operator==(const Array& other) const; + QPID_COMMON_EXTERN int count() const; + QPID_COMMON_EXTERN bool operator==(const Array& other) const; - Array(); - Array(TypeCode type); - Array(uint8_t type); + QPID_COMMON_EXTERN Array(); + QPID_COMMON_EXTERN Array(TypeCode type); + QPID_COMMON_EXTERN Array(uint8_t type); //creates a longstr array - Array(const std::vector<std::string>& in); + QPID_COMMON_EXTERN Array(const std::vector<std::string>& in); - TypeCode getType() const { return type; } + QPID_COMMON_EXTERN TypeCode getType() const { return type; } // std collection interface. - const_iterator begin() const { return values.begin(); } - const_iterator end() const { return values.end(); } - iterator begin() { return values.begin(); } - iterator end(){ return values.end(); } - - ValuePtr front() const { return values.front(); } - ValuePtr back() const { return values.back(); } - size_t size() const { return values.size(); } - - void insert(iterator i, ValuePtr value); - void erase(iterator i) { values.erase(i); } - void push_back(ValuePtr value) { values.insert(end(), value); } - void pop_back() { values.pop_back(); } + QPID_COMMON_EXTERN const_iterator begin() const { return values.begin(); } + QPID_COMMON_EXTERN const_iterator end() const { return values.end(); } + QPID_COMMON_EXTERN iterator begin() { return values.begin(); } + QPID_COMMON_EXTERN iterator end(){ return values.end(); } + + QPID_COMMON_EXTERN ValuePtr front() const { return values.front(); } + QPID_COMMON_EXTERN ValuePtr back() const { return values.back(); } + QPID_COMMON_EXTERN size_t size() const { return values.size(); } + + QPID_COMMON_EXTERN void insert(iterator i, ValuePtr value); + QPID_COMMON_EXTERN void erase(iterator i) { values.erase(i); } + QPID_COMMON_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); } + QPID_COMMON_EXTERN void pop_back() { values.pop_back(); } // Non-std interface - void add(ValuePtr value) { push_back(value); } + QPID_COMMON_EXTERN void add(ValuePtr value) { push_back(value); } template <class T> void collect(std::vector<T>& out) const @@ -86,7 +87,7 @@ class Array TypeCode type; ValueVector values; - friend std::ostream& operator<<(std::ostream& out, const Array& body); + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const Array& body); }; } diff --git a/qpid/cpp/src/qpid/framing/Buffer.h b/qpid/cpp/src/qpid/framing/Buffer.h index 828e6e963a..57fb1e32a0 100644 --- a/qpid/cpp/src/qpid/framing/Buffer.h +++ b/qpid/cpp/src/qpid/framing/Buffer.h @@ -20,6 +20,7 @@ */ #include "amqp_types.h" #include "qpid/Exception.h" +#include "qpid/CommonImportExport.h" #include <boost/iterator/iterator_facade.hpp> #ifndef _Buffer_ @@ -66,65 +67,65 @@ class Buffer friend class Iterator; - Buffer(char* data=0, uint32_t size=0); + QPID_COMMON_EXTERN Buffer(char* data=0, uint32_t size=0); - void record(); - void restore(bool reRecord = false); - void reset(); + QPID_COMMON_EXTERN void record(); + QPID_COMMON_EXTERN void restore(bool reRecord = false); + QPID_COMMON_EXTERN void reset(); - uint32_t available() { return size - position; } - uint32_t getSize() { return size; } - uint32_t getPosition() { return position; } - Iterator getIterator() { return Iterator(*this); } - char* getPointer() { return data; } + QPID_COMMON_EXTERN uint32_t available() { return size - position; } + QPID_COMMON_EXTERN uint32_t getSize() { return size; } + QPID_COMMON_EXTERN uint32_t getPosition() { return position; } + QPID_COMMON_EXTERN Iterator getIterator() { return Iterator(*this); } + QPID_COMMON_EXTERN char* getPointer() { return data; } - void putOctet(uint8_t i); - void putShort(uint16_t i); - void putLong(uint32_t i); - void putLongLong(uint64_t i); - void putInt8(int8_t i); - void putInt16(int16_t i); - void putInt32(int32_t i); - void putInt64(int64_t i); - void putFloat(float f); - void putDouble(double f); - void putBin128(uint8_t* b); - - uint8_t getOctet(); - uint16_t getShort(); - uint32_t getLong(); - uint64_t getLongLong(); - int8_t getInt8(); - int16_t getInt16(); - int32_t getInt32(); - int64_t getInt64(); - float getFloat(); - double getDouble(); + QPID_COMMON_EXTERN void putOctet(uint8_t i); + QPID_COMMON_EXTERN void putShort(uint16_t i); + QPID_COMMON_EXTERN void putLong(uint32_t i); + QPID_COMMON_EXTERN void putLongLong(uint64_t i); + QPID_COMMON_EXTERN void putInt8(int8_t i); + QPID_COMMON_EXTERN void putInt16(int16_t i); + QPID_COMMON_EXTERN void putInt32(int32_t i); + QPID_COMMON_EXTERN void putInt64(int64_t i); + QPID_COMMON_EXTERN void putFloat(float f); + QPID_COMMON_EXTERN void putDouble(double f); + QPID_COMMON_EXTERN void putBin128(uint8_t* b); + + QPID_COMMON_EXTERN uint8_t getOctet(); + QPID_COMMON_EXTERN uint16_t getShort(); + QPID_COMMON_EXTERN uint32_t getLong(); + QPID_COMMON_EXTERN uint64_t getLongLong(); + QPID_COMMON_EXTERN int8_t getInt8(); + QPID_COMMON_EXTERN int16_t getInt16(); + QPID_COMMON_EXTERN int32_t getInt32(); + QPID_COMMON_EXTERN int64_t getInt64(); + QPID_COMMON_EXTERN float getFloat(); + QPID_COMMON_EXTERN double getDouble(); template <int n> - uint64_t getUInt(); + QPID_COMMON_EXTERN uint64_t getUInt(); template <int n> - void putUInt(uint64_t); + QPID_COMMON_EXTERN void putUInt(uint64_t); - void putShortString(const string& s); - void putMediumString(const string& s); - void putLongString(const string& s); - void getShortString(string& s); - void getMediumString(string& s); - void getLongString(string& s); - void getBin128(uint8_t* b); + QPID_COMMON_EXTERN void putShortString(const string& s); + QPID_COMMON_EXTERN void putMediumString(const string& s); + QPID_COMMON_EXTERN void putLongString(const string& s); + QPID_COMMON_EXTERN void getShortString(string& s); + QPID_COMMON_EXTERN void getMediumString(string& s); + QPID_COMMON_EXTERN void getLongString(string& s); + QPID_COMMON_EXTERN void getBin128(uint8_t* b); - void putRawData(const string& s); - void getRawData(string& s, uint32_t size); + QPID_COMMON_EXTERN void putRawData(const string& s); + QPID_COMMON_EXTERN void getRawData(string& s, uint32_t size); - void putRawData(const uint8_t* data, size_t size); - void getRawData(uint8_t* data, size_t size); + QPID_COMMON_EXTERN void putRawData(const uint8_t* data, size_t size); + QPID_COMMON_EXTERN void getRawData(uint8_t* data, size_t size); template <class T> void put(const T& data) { data.encode(*this); } template <class T> void get(T& data) { data.decode(*this); } - void dump(std::ostream&) const; + QPID_COMMON_EXTERN void dump(std::ostream&) const; }; std::ostream& operator<<(std::ostream&, const Buffer&); diff --git a/qpid/cpp/src/qpid/framing/FieldTable.h b/qpid/cpp/src/qpid/framing/FieldTable.h index 9e1214a28c..a07568559f 100644 --- a/qpid/cpp/src/qpid/framing/FieldTable.h +++ b/qpid/cpp/src/qpid/framing/FieldTable.h @@ -23,6 +23,7 @@ #include <boost/shared_ptr.hpp> #include <map> #include "amqp_types.h" +#include "qpid/CommonImportExport.h" #ifndef _FieldTable_ #define _FieldTable_ @@ -51,45 +52,45 @@ class FieldTable typedef std::map<std::string, ValuePtr> ValueMap; typedef ValueMap::iterator iterator; - FieldTable() {}; - FieldTable(const FieldTable& ft); - ~FieldTable(); - FieldTable& operator=(const FieldTable& ft); - uint32_t encodedSize() const; - void encode(Buffer& buffer) const; - void decode(Buffer& buffer); - - int count() const; - void set(const std::string& name, const ValuePtr& value); - ValuePtr get(const std::string& name) const; - bool isSet(const std::string& name) const { return get(name).get() != 0; } - - void setString(const std::string& name, const std::string& value); - void setInt(const std::string& name, const int value); - void setInt64(const std::string& name, const int64_t value); - void setTimestamp(const std::string& name, const uint64_t value); - void setUInt64(const std::string& name, const uint64_t value); - void setTable(const std::string& name, const FieldTable& value); - void setArray(const std::string& name, const Array& value); - void setFloat(const std::string& name, const float value); - void setDouble(const std::string& name, const double value); + QPID_COMMON_EXTERN FieldTable() {}; + QPID_COMMON_EXTERN FieldTable(const FieldTable& ft); + QPID_COMMON_EXTERN ~FieldTable(); + QPID_COMMON_EXTERN FieldTable& operator=(const FieldTable& ft); + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer); + + QPID_COMMON_EXTERN int count() const; + QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value); + QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const; + QPID_COMMON_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; } + + QPID_COMMON_EXTERN void setString(const std::string& name, const std::string& value); + QPID_COMMON_EXTERN void setInt(const std::string& name, const int value); + QPID_COMMON_EXTERN void setInt64(const std::string& name, const int64_t value); + QPID_COMMON_EXTERN void setTimestamp(const std::string& name, const uint64_t value); + QPID_COMMON_EXTERN void setUInt64(const std::string& name, const uint64_t value); + QPID_COMMON_EXTERN void setTable(const std::string& name, const FieldTable& value); + QPID_COMMON_EXTERN void setArray(const std::string& name, const Array& value); + QPID_COMMON_EXTERN void setFloat(const std::string& name, const float value); + QPID_COMMON_EXTERN void setDouble(const std::string& name, const double value); //void setDecimal(string& name, xxx& value); - int getAsInt(const std::string& name) const; - uint64_t getAsUInt64(const std::string& name) const; - int64_t getAsInt64(const std::string& name) const; - std::string getAsString(const std::string& name) const; + QPID_COMMON_EXTERN int getAsInt(const std::string& name) const; + QPID_COMMON_EXTERN uint64_t getAsUInt64(const std::string& name) const; + QPID_COMMON_EXTERN int64_t getAsInt64(const std::string& name) const; + QPID_COMMON_EXTERN std::string getAsString(const std::string& name) const; - bool getTable(const std::string& name, FieldTable& value) const; - bool getArray(const std::string& name, Array& value) const; - bool getFloat(const std::string& name, float& value) const; - bool getDouble(const std::string& name, double& value) const; + QPID_COMMON_EXTERN bool getTable(const std::string& name, FieldTable& value) const; + QPID_COMMON_EXTERN bool getArray(const std::string& name, Array& value) const; + QPID_COMMON_EXTERN bool getFloat(const std::string& name, float& value) const; + QPID_COMMON_EXTERN bool getDouble(const std::string& name, double& value) const; //bool getTimestamp(const std::string& name, uint64_t& value) const; //bool getDecimal(string& name, xxx& value); - void erase(const std::string& name); + QPID_COMMON_EXTERN void erase(const std::string& name); - bool operator==(const FieldTable& other) const; + QPID_COMMON_EXTERN bool operator==(const FieldTable& other) const; // Map-like interface. // TODO: may need to duplicate into versions that return mutable iterator @@ -107,7 +108,7 @@ class FieldTable private: ValueMap values; - friend std::ostream& operator<<(std::ostream& out, const FieldTable& body); + QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream& out, const FieldTable& body); }; //class FieldNotFoundException{}; diff --git a/qpid/cpp/src/qpid/framing/FieldValue.h b/qpid/cpp/src/qpid/framing/FieldValue.h index 29760619e5..0f27700ac8 100644 --- a/qpid/cpp/src/qpid/framing/FieldValue.h +++ b/qpid/cpp/src/qpid/framing/FieldValue.h @@ -25,6 +25,7 @@ #include "amqp_types.h" #include "Buffer.h" #include "FieldTable.h" +#include "qpid/CommonImportExport.h" #include "assert.h" @@ -87,8 +88,8 @@ class FieldValue { bool empty() const { return data.get() == 0; } void encode(Buffer& buffer); void decode(Buffer& buffer); - bool operator==(const FieldValue&) const; - bool operator!=(const FieldValue& v) const { return !(*this == v); } + QPID_COMMON_EXTERN bool operator==(const FieldValue&) const; + QPID_COMMON_EXTERN bool operator!=(const FieldValue& v) const { return !(*this == v); } void print(std::ostream& out) const; @@ -244,28 +245,28 @@ class EncodedValue : public FieldValue::Data { class Str8Value : public FieldValue { public: - Str8Value(const std::string& v); + QPID_COMMON_EXTERN Str8Value(const std::string& v); }; class Str16Value : public FieldValue { public: - Str16Value(const std::string& v); + QPID_COMMON_EXTERN Str16Value(const std::string& v); }; class Struct32Value : public FieldValue { public: - Struct32Value(const std::string& v); + QPID_COMMON_EXTERN Struct32Value(const std::string& v); }; class FloatValue : public FieldValue { public: - FloatValue(float f); + QPID_COMMON_EXTERN FloatValue(float f); }; class DoubleValue : public FieldValue { public: - DoubleValue(double f); + QPID_COMMON_EXTERN DoubleValue(double f); }; /* @@ -273,32 +274,32 @@ class DoubleValue : public FieldValue */ class IntegerValue : public FieldValue { public: - IntegerValue(int v); + QPID_COMMON_EXTERN IntegerValue(int v); }; class TimeValue : public FieldValue { public: - TimeValue(uint64_t v); + QPID_COMMON_EXTERN TimeValue(uint64_t v); }; class Integer64Value : public FieldValue { public: - Integer64Value(int64_t v); + QPID_COMMON_EXTERN Integer64Value(int64_t v); }; class Unsigned64Value : public FieldValue { public: - Unsigned64Value(uint64_t v); + QPID_COMMON_EXTERN Unsigned64Value(uint64_t v); }; class FieldTableValue : public FieldValue { public: - FieldTableValue(const FieldTable&); + QPID_COMMON_EXTERN FieldTableValue(const FieldTable&); }; class ArrayValue : public FieldValue { public: - ArrayValue(const Array&); + QPID_COMMON_EXTERN ArrayValue(const Array&); }; template <class T> diff --git a/qpid/cpp/src/qpid/framing/FrameDecoder.cpp b/qpid/cpp/src/qpid/framing/FrameDecoder.cpp index cbdac181e9..1e73ee1e51 100644 --- a/qpid/cpp/src/qpid/framing/FrameDecoder.cpp +++ b/qpid/cpp/src/qpid/framing/FrameDecoder.cpp @@ -21,8 +21,9 @@ #include "FrameDecoder.h" #include "Buffer.h" #include "qpid/log/Statement.h" -#include <algorithm> #include "qpid/framing/reply_exceptions.h" +#include <algorithm> +#include <string.h> namespace qpid { namespace framing { @@ -67,4 +68,13 @@ bool FrameDecoder::decode(Buffer& buffer) { return false; } +void FrameDecoder::setFragment(const char* data, size_t size) { + fragment.resize(size); + ::memcpy(&fragment[0], data, size); +} + +std::pair<const char*, size_t> FrameDecoder::getFragment() const { + return std::pair<const char*, size_t>(&fragment[0], fragment.size()); +} + }} // namespace qpid::framing diff --git a/qpid/cpp/src/qpid/framing/FrameDecoder.h b/qpid/cpp/src/qpid/framing/FrameDecoder.h index 7f974dadc3..961cc666a9 100644 --- a/qpid/cpp/src/qpid/framing/FrameDecoder.h +++ b/qpid/cpp/src/qpid/framing/FrameDecoder.h @@ -35,9 +35,16 @@ class FrameDecoder { public: bool decode(Buffer& buffer); - AMQFrame frame; + const AMQFrame& getFrame() const { return frame; } + AMQFrame& getFrame() { return frame; } + + void setFragment(const char*, size_t); + std::pair<const char*, size_t> getFragment() const; + private: std::vector<char> fragment; + AMQFrame frame; + }; }} // namespace qpid::framing diff --git a/qpid/cpp/src/qpid/framing/FrameSet.h b/qpid/cpp/src/qpid/framing/FrameSet.h index b13ca16e97..e3e8727600 100644 --- a/qpid/cpp/src/qpid/framing/FrameSet.h +++ b/qpid/cpp/src/qpid/framing/FrameSet.h @@ -23,6 +23,7 @@ #include "qpid/framing/amqp_framing.h" #include "qpid/framing/AMQFrame.h" #include "qpid/framing/SequenceNumber.h" +#include "qpid/CommonImportExport.h" #ifndef _FrameSet_ #define _FrameSet_ @@ -44,20 +45,20 @@ class FrameSet public: typedef boost::shared_ptr<FrameSet> shared_ptr; - FrameSet(const SequenceNumber& id); - void append(const AMQFrame& part); - bool isComplete() const; + QPID_COMMON_EXTERN FrameSet(const SequenceNumber& id); + QPID_COMMON_EXTERN void append(const AMQFrame& part); + QPID_COMMON_EXTERN bool isComplete() const; - uint64_t getContentSize() const; + QPID_COMMON_EXTERN uint64_t getContentSize() const; - void getContent(std::string&) const; - std::string getContent() const; + QPID_COMMON_EXTERN void getContent(std::string&) const; + QPID_COMMON_EXTERN std::string getContent() const; bool isContentBearing() const; - const AMQMethodBody* getMethod() const; - const AMQHeaderBody* getHeaders() const; - AMQHeaderBody* getHeaders(); + QPID_COMMON_EXTERN const AMQMethodBody* getMethod() const; + QPID_COMMON_EXTERN const AMQHeaderBody* getHeaders() const; + QPID_COMMON_EXTERN AMQHeaderBody* getHeaders(); template <class T> bool isA() const { const AMQMethodBody* method = getMethod(); diff --git a/qpid/cpp/src/qpid/framing/ProtocolInitiation.h b/qpid/cpp/src/qpid/framing/ProtocolInitiation.h index 6584fee55c..7a82b3575f 100644 --- a/qpid/cpp/src/qpid/framing/ProtocolInitiation.h +++ b/qpid/cpp/src/qpid/framing/ProtocolInitiation.h @@ -22,6 +22,7 @@ #include "Buffer.h" #include "AMQDataBlock.h" #include "ProtocolVersion.h" +#include "qpid/CommonImportExport.h" #ifndef _ProtocolInitiation_ #define _ProtocolInitiation_ @@ -35,12 +36,12 @@ private: ProtocolVersion version; public: - ProtocolInitiation(); - ProtocolInitiation(uint8_t major, uint8_t minor); - ProtocolInitiation(ProtocolVersion p); - virtual ~ProtocolInitiation(); - virtual void encode(Buffer& buffer) const; - virtual bool decode(Buffer& buffer); + QPID_COMMON_EXTERN ProtocolInitiation(); + QPID_COMMON_EXTERN ProtocolInitiation(uint8_t major, uint8_t minor); + QPID_COMMON_EXTERN ProtocolInitiation(ProtocolVersion p); + QPID_COMMON_EXTERN virtual ~ProtocolInitiation(); + QPID_COMMON_EXTERN virtual void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN virtual bool decode(Buffer& buffer); inline virtual uint32_t encodedSize() const { return 8; } inline uint8_t getMajor() const { return version.getMajor(); } inline uint8_t getMinor() const { return version.getMinor(); } @@ -48,7 +49,7 @@ public: bool operator==(ProtocolVersion v) const { return v == getVersion(); } }; -std::ostream& operator<<(std::ostream& o, const framing::ProtocolInitiation& pi); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const framing::ProtocolInitiation& pi); } diff --git a/qpid/cpp/src/qpid/framing/ProtocolVersion.h b/qpid/cpp/src/qpid/framing/ProtocolVersion.h index 9a7ebec491..681c9daf21 100644 --- a/qpid/cpp/src/qpid/framing/ProtocolVersion.h +++ b/qpid/cpp/src/qpid/framing/ProtocolVersion.h @@ -22,6 +22,7 @@ #define _ProtocolVersion_ #include "amqp_types.h" +#include "qpid/CommonImportExport.h" namespace qpid { @@ -38,16 +39,16 @@ public: explicit ProtocolVersion(uint8_t _major=0, uint8_t _minor=0) : major_(_major), minor_(_minor) {} - uint8_t getMajor() const { return major_; } - void setMajor(uint8_t major) { major_ = major; } - uint8_t getMinor() const { return minor_; } - void setMinor(uint8_t minor) { minor_ = minor; } - const std::string toString() const; + QPID_COMMON_EXTERN uint8_t getMajor() const { return major_; } + QPID_COMMON_EXTERN void setMajor(uint8_t major) { major_ = major; } + QPID_COMMON_EXTERN uint8_t getMinor() const { return minor_; } + QPID_COMMON_EXTERN void setMinor(uint8_t minor) { minor_ = minor; } + QPID_COMMON_EXTERN const std::string toString() const; - ProtocolVersion& operator=(ProtocolVersion p); + QPID_COMMON_EXTERN ProtocolVersion& operator=(ProtocolVersion p); - bool operator==(ProtocolVersion p) const; - bool operator!=(ProtocolVersion p) const { return ! (*this == p); } + QPID_COMMON_EXTERN bool operator==(ProtocolVersion p) const; + QPID_COMMON_EXTERN bool operator!=(ProtocolVersion p) const { return ! (*this == p); } }; } // namespace framing diff --git a/qpid/cpp/src/qpid/framing/Proxy.h b/qpid/cpp/src/qpid/framing/Proxy.h index 5e2c886af2..a9a6ce981e 100644 --- a/qpid/cpp/src/qpid/framing/Proxy.h +++ b/qpid/cpp/src/qpid/framing/Proxy.h @@ -22,6 +22,8 @@ #include "FrameHandler.h" #include "ProtocolVersion.h" +#include "qpid/CommonImportExport.h" + namespace qpid { namespace framing { @@ -37,19 +39,19 @@ class Proxy { Proxy& proxy; public: - ScopedSync(Proxy& p); - ~ScopedSync(); + QPID_COMMON_EXTERN ScopedSync(Proxy& p); + QPID_COMMON_EXTERN ~ScopedSync(); }; - Proxy(FrameHandler& h); - virtual ~Proxy(); + QPID_COMMON_EXTERN Proxy(FrameHandler& h); + QPID_COMMON_EXTERN virtual ~Proxy(); - void send(const AMQBody&); + QPID_COMMON_EXTERN void send(const AMQBody&); - ProtocolVersion getVersion() const; + QPID_COMMON_EXTERN ProtocolVersion getVersion() const; - FrameHandler& getHandler(); - void setHandler(FrameHandler&); + QPID_COMMON_EXTERN FrameHandler& getHandler(); + QPID_COMMON_EXTERN void setHandler(FrameHandler&); private: FrameHandler* out; bool sync; diff --git a/qpid/cpp/src/qpid/framing/SendContent.h b/qpid/cpp/src/qpid/framing/SendContent.h index dcd5202b3e..745c948c9e 100644 --- a/qpid/cpp/src/qpid/framing/SendContent.h +++ b/qpid/cpp/src/qpid/framing/SendContent.h @@ -22,6 +22,7 @@ #include "qpid/framing/amqp_framing.h" #include "qpid/framing/AMQFrame.h" #include "qpid/framing/FrameHandler.h" +#include "qpid/CommonImportExport.h" #ifndef _SendContent_ #define _SendContent_ @@ -44,8 +45,8 @@ class SendContent void sendFragment(const AMQContentBody& body, uint32_t offset, uint16_t size, bool first, bool last) const; void setFlags(AMQFrame& f, bool first, bool last) const; public: - SendContent(FrameHandler& _handler, uint16_t _maxFrameSize, uint frameCount); - void operator()(const AMQFrame& f); + QPID_COMMON_EXTERN SendContent(FrameHandler& _handler, uint16_t _maxFrameSize, uint frameCount); + QPID_COMMON_EXTERN void operator()(const AMQFrame& f); }; } diff --git a/qpid/cpp/src/qpid/framing/SequenceNumber.h b/qpid/cpp/src/qpid/framing/SequenceNumber.h index 930e146863..3b18ce1360 100644 --- a/qpid/cpp/src/qpid/framing/SequenceNumber.h +++ b/qpid/cpp/src/qpid/framing/SequenceNumber.h @@ -23,6 +23,7 @@ #include "amqp_types.h" #include <iosfwd> +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -37,22 +38,22 @@ class SequenceNumber int32_t value; public: - SequenceNumber(); - SequenceNumber(uint32_t v); + QPID_COMMON_EXTERN SequenceNumber(); + QPID_COMMON_EXTERN SequenceNumber(uint32_t v); - SequenceNumber& operator++();//prefix ++ - const SequenceNumber operator++(int);//postfix ++ - SequenceNumber& operator--();//prefix ++ - bool operator==(const SequenceNumber& other) const; - bool operator!=(const SequenceNumber& other) const; - bool operator<(const SequenceNumber& other) const; - bool operator>(const SequenceNumber& other) const; - bool operator<=(const SequenceNumber& other) const; - bool operator>=(const SequenceNumber& other) const; + QPID_COMMON_EXTERN SequenceNumber& operator++();//prefix ++ + QPID_COMMON_EXTERN const SequenceNumber operator++(int);//postfix ++ + QPID_COMMON_EXTERN SequenceNumber& operator--();//prefix ++ + QPID_COMMON_EXTERN bool operator==(const SequenceNumber& other) const; + QPID_COMMON_EXTERN bool operator!=(const SequenceNumber& other) const; + QPID_COMMON_EXTERN bool operator<(const SequenceNumber& other) const; + QPID_COMMON_EXTERN bool operator>(const SequenceNumber& other) const; + QPID_COMMON_EXTERN bool operator<=(const SequenceNumber& other) const; + QPID_COMMON_EXTERN bool operator>=(const SequenceNumber& other) const; uint32_t getValue() const { return (uint32_t) value; } operator uint32_t() const { return (uint32_t) value; } - friend int32_t operator-(const SequenceNumber& a, const SequenceNumber& b); + QPID_COMMON_EXTERN friend int32_t operator-(const SequenceNumber& a, const SequenceNumber& b); void encode(Buffer& buffer) const; void decode(Buffer& buffer); @@ -67,7 +68,7 @@ struct Window SequenceNumber lwm; }; -std::ostream& operator<<(std::ostream& o, const SequenceNumber& n); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const SequenceNumber& n); }} // namespace qpid::framing diff --git a/qpid/cpp/src/qpid/framing/SequenceNumberSet.h b/qpid/cpp/src/qpid/framing/SequenceNumberSet.h index 666307f9d9..8e023ba535 100644 --- a/qpid/cpp/src/qpid/framing/SequenceNumberSet.h +++ b/qpid/cpp/src/qpid/framing/SequenceNumberSet.h @@ -27,6 +27,7 @@ #include "SequenceNumber.h" #include "qpid/framing/reply_exceptions.h" #include "qpid/InlineVector.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -41,8 +42,8 @@ public: void encode(Buffer& buffer) const; void decode(Buffer& buffer); uint32_t encodedSize() const; - SequenceNumberSet condense() const; - void addRange(const SequenceNumber& start, const SequenceNumber& end); + QPID_COMMON_EXTERN SequenceNumberSet condense() const; + QPID_COMMON_EXTERN void addRange(const SequenceNumber& start, const SequenceNumber& end); template <class T> void processRanges(T& t) const @@ -58,7 +59,7 @@ public: } } - friend std::ostream& operator<<(std::ostream&, const SequenceNumberSet&); + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceNumberSet&); }; diff --git a/qpid/cpp/src/qpid/framing/SequenceSet.h b/qpid/cpp/src/qpid/framing/SequenceSet.h index 57b9c2c8e1..a5ee6cd649 100644 --- a/qpid/cpp/src/qpid/framing/SequenceSet.h +++ b/qpid/cpp/src/qpid/framing/SequenceSet.h @@ -23,6 +23,7 @@ #include "SequenceNumber.h" #include "qpid/RangeSet.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -41,13 +42,13 @@ class SequenceSet : public RangeSet<SequenceNumber> { void decode(Buffer& buffer); uint32_t encodedSize() const; - bool contains(const SequenceNumber& s) const; - void add(const SequenceNumber& s); - void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range - void add(const SequenceSet& set); - void remove(const SequenceNumber& s); - void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range - void remove(const SequenceSet& set); + QPID_COMMON_EXTERN bool contains(const SequenceNumber& s) const; + QPID_COMMON_EXTERN void add(const SequenceNumber& s); + QPID_COMMON_EXTERN void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range + QPID_COMMON_EXTERN void add(const SequenceSet& set); + QPID_COMMON_EXTERN void remove(const SequenceNumber& s); + QPID_COMMON_EXTERN void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range + QPID_COMMON_EXTERN void remove(const SequenceSet& set); template <class T> void for_each(T& t) const { for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++) @@ -59,7 +60,7 @@ class SequenceSet : public RangeSet<SequenceNumber> { t(i->first(), i->last()); } - friend std::ostream& operator<<(std::ostream&, const SequenceSet&); + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceSet&); }; }} // namespace qpid::framing diff --git a/qpid/cpp/src/qpid/framing/StructHelper.h b/qpid/cpp/src/qpid/framing/StructHelper.h index e3dce4f5ec..89f556ad3c 100644 --- a/qpid/cpp/src/qpid/framing/StructHelper.h +++ b/qpid/cpp/src/qpid/framing/StructHelper.h @@ -22,6 +22,7 @@ #define _StructHelper_ #include "qpid/Exception.h" +#include "qpid/CommonImportExport.h" #include "Buffer.h" #include <stdlib.h> // For alloca diff --git a/qpid/cpp/src/qpid/framing/TransferContent.h b/qpid/cpp/src/qpid/framing/TransferContent.h index e3f6666fa4..236a0b6d93 100644 --- a/qpid/cpp/src/qpid/framing/TransferContent.h +++ b/qpid/cpp/src/qpid/framing/TransferContent.h @@ -26,6 +26,7 @@ #include "qpid/Exception.h" #include "qpid/framing/MessageProperties.h" #include "qpid/framing/DeliveryProperties.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace framing { @@ -36,27 +37,27 @@ class TransferContent : public MethodContent AMQHeaderBody header; std::string data; public: - TransferContent(const std::string& data = std::string(), const std::string& key=std::string()); + QPID_COMMON_EXTERN TransferContent(const std::string& data = std::string(), const std::string& key=std::string()); ///@internal - AMQHeaderBody getHeader() const; + QPID_COMMON_EXTERN AMQHeaderBody getHeader() const; - void setData(const std::string&); - const std::string& getData() const; - std::string& getData(); + QPID_COMMON_EXTERN void setData(const std::string&); + QPID_COMMON_EXTERN const std::string& getData() const; + QPID_COMMON_EXTERN std::string& getData(); - void appendData(const std::string&); + QPID_COMMON_EXTERN void appendData(const std::string&); - bool hasMessageProperties() const; - MessageProperties& getMessageProperties(); - const MessageProperties& getMessageProperties() const; + QPID_COMMON_EXTERN bool hasMessageProperties() const; + QPID_COMMON_EXTERN MessageProperties& getMessageProperties(); + QPID_COMMON_EXTERN const MessageProperties& getMessageProperties() const; - bool hasDeliveryProperties() const; - DeliveryProperties& getDeliveryProperties(); - const DeliveryProperties& getDeliveryProperties() const; + QPID_COMMON_EXTERN bool hasDeliveryProperties() const; + QPID_COMMON_EXTERN DeliveryProperties& getDeliveryProperties(); + QPID_COMMON_EXTERN const DeliveryProperties& getDeliveryProperties() const; ///@internal - void populate(const FrameSet& frameset); + QPID_COMMON_EXTERN void populate(const FrameSet& frameset); }; }} diff --git a/qpid/cpp/src/qpid/framing/Uuid.h b/qpid/cpp/src/qpid/framing/Uuid.h index 2fcbb5a261..fe0c32dc0b 100644 --- a/qpid/cpp/src/qpid/framing/Uuid.h +++ b/qpid/cpp/src/qpid/framing/Uuid.h @@ -19,7 +19,9 @@ * */ +#include "qpid/CommonImportExport.h" #include "qpid/sys/uuid.h" +#include "qpid/sys/IntegerTypes.h" #include <boost/array.hpp> @@ -63,12 +65,12 @@ struct Uuid : public boost::array<uint8_t, 16> { // Default op= and copy ctor are fine. // boost::array gives us ==, < etc. - void encode(framing::Buffer& buf) const; - void decode(framing::Buffer& buf); - uint32_t encodedSize() const { return size(); } + QPID_COMMON_EXTERN void encode(framing::Buffer& buf) const; + QPID_COMMON_EXTERN void decode(framing::Buffer& buf); + QPID_COMMON_EXTERN uint32_t encodedSize() const { return size(); } /** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ - std::string str() const; + QPID_COMMON_EXTERN std::string str() const; template <class S> void serialize(S& s) { s.raw(begin(), size()); @@ -76,10 +78,10 @@ struct Uuid : public boost::array<uint8_t, 16> { }; /** Print in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ -std::ostream& operator<<(std::ostream&, Uuid); +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, Uuid); /** Read from format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ -std::istream& operator>>(std::istream&, Uuid&); +QPID_COMMON_EXTERN std::istream& operator>>(std::istream&, Uuid&); }} // namespace qpid::framing diff --git a/qpid/cpp/src/qpid/log/Logger.h b/qpid/cpp/src/qpid/log/Logger.h index 539c1c851b..0cbd7685d6 100644 --- a/qpid/cpp/src/qpid/log/Logger.h +++ b/qpid/cpp/src/qpid/log/Logger.h @@ -18,6 +18,7 @@ #include <boost/ptr_container/ptr_vector.hpp> #include <boost/noncopyable.hpp> #include <set> +#include "qpid/CommonImportExport.h" namespace qpid { namespace log { @@ -48,48 +49,48 @@ class Logger : private boost::noncopyable { */ class Output { public: - Output(); - virtual ~Output(); + QPID_COMMON_EXTERN Output(); + QPID_COMMON_EXTERN virtual ~Output(); /** Receives the statemnt of origin and formatted message to log. */ virtual void log(const Statement&, const std::string&) =0; }; - static Logger& instance(); + QPID_COMMON_EXTERN static Logger& instance(); - Logger(); - ~Logger(); + QPID_COMMON_EXTERN Logger(); + QPID_COMMON_EXTERN ~Logger(); /** Select the messages to be logged. */ - void select(const Selector& s); + QPID_COMMON_EXTERN void select(const Selector& s); /** Set the formatting flags, bitwise OR of FormatFlag values. */ - void format(int formatFlags); + QPID_COMMON_EXTERN void format(int formatFlags); /** Set format flags from options object. *@returns computed flags. */ - int format(const Options&); + QPID_COMMON_EXTERN int format(const Options&); /** Configure logger from Options */ - void configure(const Options& o); + QPID_COMMON_EXTERN void configure(const Options& o); /** Add a statement. */ - void add(Statement& s); + QPID_COMMON_EXTERN void add(Statement& s); /** Log a message. */ - void log(const Statement&, const std::string&); + QPID_COMMON_EXTERN void log(const Statement&, const std::string&); /** Add an output destination for messages */ - void output(std::auto_ptr<Output> out); + QPID_COMMON_EXTERN void output(std::auto_ptr<Output> out); /** Set a prefix for all messages */ - void setPrefix(const std::string& prefix); + QPID_COMMON_EXTERN void setPrefix(const std::string& prefix); /** Reset the logger. */ - void clear(); + QPID_COMMON_EXTERN void clear(); /** Get the options used to configure the logger. */ - const Options& getOptions() const { return options; } + QPID_COMMON_EXTERN const Options& getOptions() const { return options; } private: diff --git a/qpid/cpp/src/qpid/log/Options.h b/qpid/cpp/src/qpid/log/Options.h index 8a3c352d14..5e7bd433af 100644 --- a/qpid/cpp/src/qpid/log/Options.h +++ b/qpid/cpp/src/qpid/log/Options.h @@ -19,6 +19,7 @@ * */ #include "qpid/Options.h" +#include "qpid/CommonImportExport.h" #include "SinkOptions.h" #include <iosfwd> #include <memory> @@ -29,11 +30,11 @@ namespace log { /** Logging options for config parser. */ struct Options : public qpid::Options { /** Pass argv[0] for use in syslog output */ - Options(const std::string& argv0_=std::string(), + QPID_COMMON_EXTERN Options(const std::string& argv0_=std::string(), const std::string& name_="Logging options"); - Options(const Options &); + QPID_COMMON_EXTERN Options(const Options &); - Options& operator=(const Options&); + QPID_COMMON_EXTERN Options& operator=(const Options&); std::string argv0; std::string name; diff --git a/qpid/cpp/src/qpid/log/OstreamOutput.h b/qpid/cpp/src/qpid/log/OstreamOutput.h index 8bbfc8c38b..8df38468ad 100644 --- a/qpid/cpp/src/qpid/log/OstreamOutput.h +++ b/qpid/cpp/src/qpid/log/OstreamOutput.h @@ -26,8 +26,8 @@ namespace log { */ class OstreamOutput : public qpid::log::Logger::Output { public: - OstreamOutput(std::ostream& o); - OstreamOutput(const std::string& file); + QPID_COMMON_EXTERN OstreamOutput(std::ostream& o); + QPID_COMMON_EXTERN OstreamOutput(const std::string& file); virtual void log(const Statement&, const std::string& m); diff --git a/qpid/cpp/src/qpid/log/Selector.cpp b/qpid/cpp/src/qpid/log/Selector.cpp index 4d1c5b6e0c..0a629edc3e 100644 --- a/qpid/cpp/src/qpid/log/Selector.cpp +++ b/qpid/cpp/src/qpid/log/Selector.cpp @@ -20,6 +20,7 @@ #include "Options.h" #include <boost/bind.hpp> #include <algorithm> +#include <string.h> namespace qpid { namespace log { diff --git a/qpid/cpp/src/qpid/log/Selector.h b/qpid/cpp/src/qpid/log/Selector.h index 705abfeb5d..070ffd4abf 100644 --- a/qpid/cpp/src/qpid/log/Selector.h +++ b/qpid/cpp/src/qpid/log/Selector.h @@ -20,6 +20,7 @@ */ #include "Statement.h" +#include "qpid/CommonImportExport.h" #include <vector> namespace qpid { @@ -37,7 +38,7 @@ class Selector { Selector() {} /** Set selector from Options */ - Selector(const Options&); + QPID_COMMON_EXTERN Selector(const Options&); /** Equavlient to: Selector s; s.enable(l, s) */ Selector(Level l, const std::string& s=std::string()) { @@ -54,10 +55,10 @@ class Selector { } /** Enable based on a 'level[+]:file' string */ - void enable(const std::string& enableStr); + QPID_COMMON_EXTERN void enable(const std::string& enableStr); /** True if level is enabled for file. */ - bool isEnabled(Level level, const char* function); + QPID_COMMON_EXTERN bool isEnabled(Level level, const char* function); private: std::vector<std::string> substrings[LevelTraits::COUNT]; diff --git a/qpid/cpp/src/qpid/log/Statement.h b/qpid/cpp/src/qpid/log/Statement.h index 3c67b04b20..445f635cdd 100644 --- a/qpid/cpp/src/qpid/log/Statement.h +++ b/qpid/cpp/src/qpid/log/Statement.h @@ -20,7 +20,7 @@ */ #include "qpid/Msg.h" - +#include "qpid/CommonImportExport.h" #include <boost/current_function.hpp> namespace qpid { @@ -63,10 +63,10 @@ struct Statement { const char* function; Level level; - void log(const std::string& message); + QPID_COMMON_EXTERN void log(const std::string& message); struct Initializer { - Initializer(Statement& s); + QPID_COMMON_EXTERN Initializer(Statement& s); Statement& statement; }; }; diff --git a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp index 9d51358e2e..985cb32c5c 100644 --- a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp +++ b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp @@ -42,10 +42,14 @@ public: struct NameValue { const char* name; int value; }; NameValue nameValue[] = { { "AUTH", LOG_AUTH }, +#ifdef HAVE_LOG_AUTHPRIV { "AUTHPRIV", LOG_AUTHPRIV }, +#endif { "CRON", LOG_CRON }, { "DAEMON", LOG_DAEMON }, +#ifdef HAVE_LOG_FTP { "FTP", LOG_FTP }, +#endif { "KERN", LOG_KERN }, { "LOCAL0", LOG_LOCAL0 }, { "LOCAL1", LOG_LOCAL1 }, @@ -72,7 +76,7 @@ public: int value(const string& name) const { string key(name); - transform(key.begin(), key.end(), key.begin(), ::toupper); + std::transform(key.begin(), key.end(), key.begin(), ::toupper); ByName::const_iterator i = byName.find(key); if (i == byName.end()) throw Exception("Not a valid syslog facility: " + name); diff --git a/qpid/cpp/src/qpid/log/windows/SinkOptions.h b/qpid/cpp/src/qpid/log/windows/SinkOptions.h index d14e9352be..605822fd46 100644 --- a/qpid/cpp/src/qpid/log/windows/SinkOptions.h +++ b/qpid/cpp/src/qpid/log/windows/SinkOptions.h @@ -27,20 +27,20 @@ namespace log { namespace windows { struct SinkOptions : public qpid::log::SinkOptions { - SinkOptions(const std::string& argv0); + QPID_COMMON_EXTERN SinkOptions(const std::string& argv0); virtual ~SinkOptions() {} - virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs); + QPID_COMMON_EXTERN virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs); // This allows the caller to indicate that there's no normal outputs // available. For example, when running as a service. In these cases, the // platform's "syslog"-type output should replace the default stderr // unless some other sink has been selected. - virtual void detached(void); + QPID_COMMON_EXTERN virtual void detached(void); // The Logger acting on these options calls setup() to request any // Sinks be set up and fed back to the logger. - virtual void setup(qpid::log::Logger *logger); + QPID_COMMON_EXTERN virtual void setup(qpid::log::Logger *logger); bool logToStderr; bool logToStdout; diff --git a/qpid/cpp/src/qpid/management/Manageable.h b/qpid/cpp/src/qpid/management/Manageable.h index b4d80d8fad..ededa6141e 100644 --- a/qpid/cpp/src/qpid/management/Manageable.h +++ b/qpid/cpp/src/qpid/management/Manageable.h @@ -23,11 +23,12 @@ #include "ManagementObject.h" #include "Args.h" #include <string> +#include "qpid/CommonImportExport.h" namespace qpid { namespace management { -class Manageable +class QPID_COMMON_EXTERN Manageable { public: diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.cpp b/qpid/cpp/src/qpid/management/ManagementBroker.cpp index 0f96e97fb0..19300ef1af 100644 --- a/qpid/cpp/src/qpid/management/ManagementBroker.cpp +++ b/qpid/cpp/src/qpid/management/ManagementBroker.cpp @@ -80,7 +80,7 @@ ManagementBroker::RemoteAgent::~RemoteAgent () } ManagementBroker::ManagementBroker () : - threadPoolSize(1), interval(10), broker(0) + threadPoolSize(1), interval(10), broker(0), startTime(uint64_t(Duration(now()))) { nextObjectId = 1; brokerBank = 1; @@ -346,6 +346,9 @@ void ManagementBroker::periodicProcessing (void) string routingKey; list<pair<ObjectId, ManagementObject*> > deleteList; + uint64_t uptime = uint64_t(Duration(now())) - startTime; + static_cast<_qmf::Broker*>(broker->GetManagementObject())->set_uptime(uptime); + moveNewObjectsLH(); if (clientWasAdded) { @@ -515,6 +518,7 @@ void ManagementBroker::handleMethodRequestLH (Buffer& inBuffer, string replyToKe else try { outBuffer.record(); + Mutex::ScopedUnlock u(userLock); iter->second->doMethod(methodName, inBuffer, outBuffer); } catch(exception& e) { outBuffer.restore(); @@ -844,6 +848,9 @@ void ManagementBroker::handleGetQueryLH (Buffer& inBuffer, string replyToKey, ui Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; + if (object->getConfigChanged() || object->getInstChanged()) + object->setUpdateTime(); + encodeHeader(outBuffer, 'g', sequence); object->writeProperties(outBuffer); object->writeStatistics(outBuffer, true); @@ -865,6 +872,9 @@ void ManagementBroker::handleGetQueryLH (Buffer& inBuffer, string replyToKey, ui Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE); uint32_t outLen; + if (object->getConfigChanged() || object->getInstChanged()) + object->setUpdateTime(); + encodeHeader(outBuffer, 'g', sequence); object->writeProperties(outBuffer); object->writeStatistics(outBuffer, true); diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.h b/qpid/cpp/src/qpid/management/ManagementBroker.h index f65d6a345e..a57f73be15 100644 --- a/qpid/cpp/src/qpid/management/ManagementBroker.h +++ b/qpid/cpp/src/qpid/management/ManagementBroker.h @@ -182,6 +182,7 @@ private: uint32_t nextRemoteBank; uint32_t nextRequestSequence; bool clientWasAdded; + const uint64_t startTime; std::auto_ptr<IdAllocator> allocator; diff --git a/qpid/cpp/src/qpid/management/ManagementObject.h b/qpid/cpp/src/qpid/management/ManagementObject.h index fbdad347b8..498169318d 100644 --- a/qpid/cpp/src/qpid/management/ManagementObject.h +++ b/qpid/cpp/src/qpid/management/ManagementObject.h @@ -25,6 +25,7 @@ #include "qpid/sys/Time.h" #include "qpid/sys/Mutex.h" #include <qpid/framing/Buffer.h> +#include "qpid/CommonImportExport.h" #include <map> namespace qpid { @@ -41,7 +42,7 @@ private: uint64_t first; public: AgentAttachment() : first(0) {} - void setBanks(uint32_t broker, uint32_t bank); + QPID_COMMON_EXTERN void setBanks(uint32_t broker, uint32_t bank); uint64_t getFirst() const { return first; } }; @@ -53,17 +54,17 @@ protected: uint64_t second; void fromString(const std::string&); public: - ObjectId() : agent(0), first(0), second(0) {} - ObjectId(framing::Buffer& buf) : agent(0) { decode(buf); } - ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint32_t bank, uint64_t object); - ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq, uint64_t object); - ObjectId(std::istream&); - ObjectId(const std::string&); - bool operator==(const ObjectId &other) const; - bool operator<(const ObjectId &other) const; - void encode(framing::Buffer& buffer); - void decode(framing::Buffer& buffer); - friend std::ostream& operator<<(std::ostream&, const ObjectId&); + QPID_COMMON_EXTERN ObjectId() : agent(0), first(0), second(0) {} + QPID_COMMON_EXTERN ObjectId(framing::Buffer& buf) : agent(0) { decode(buf); } + QPID_COMMON_EXTERN ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint32_t bank, uint64_t object); + QPID_COMMON_EXTERN ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq, uint64_t object); + QPID_COMMON_EXTERN ObjectId(std::istream&); + QPID_COMMON_EXTERN ObjectId(const std::string&); + QPID_COMMON_EXTERN bool operator==(const ObjectId &other) const; + QPID_COMMON_EXTERN bool operator<(const ObjectId &other) const; + QPID_COMMON_EXTERN void encode(framing::Buffer& buffer); + QPID_COMMON_EXTERN void decode(framing::Buffer& buffer); + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const ObjectId&); }; class ManagementItem { @@ -128,8 +129,8 @@ class ManagementObject : public ManagementItem static int nextThreadIndex; bool forcePublish; - int getThreadIndex(); - void writeTimestamps(qpid::framing::Buffer& buf); + QPID_COMMON_EXTERN int getThreadIndex(); + QPID_COMMON_EXTERN void writeTimestamps(qpid::framing::Buffer& buf); public: typedef void (*writeSchemaCall_t) (qpid::framing::Buffer&); @@ -148,7 +149,7 @@ class ManagementObject : public ManagementItem virtual void doMethod(std::string& methodName, qpid::framing::Buffer& inBuf, qpid::framing::Buffer& outBuf) = 0; - virtual void setReference(ObjectId objectId); + QPID_COMMON_EXTERN virtual void setReference(ObjectId objectId); virtual std::string& getClassName() const = 0; virtual std::string& getPackageName() const = 0; diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp index 2d8af3b052..60d5fffc0b 100644 --- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp +++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp @@ -21,6 +21,7 @@ #include "ReplicatingEventListener.h" #include "constants.h" #include "qpid/broker/Broker.h" +#include "qpid/broker/DeliverableMessage.h" #include "qpid/broker/QueueEvents.h" #include "qpid/framing/AMQFrame.h" #include "qpid/framing/FrameHandler.h" @@ -57,11 +58,12 @@ void ReplicatingEventListener::deliverDequeueMessage(const QueuedMessage& dequeu { FieldTable headers; headers.setString(REPLICATION_TARGET_QUEUE, dequeued.queue->getName()); - headers.setInt(REPLICATION_EVENT_SEQNO, ++sequence); headers.setInt(REPLICATION_EVENT_TYPE, DEQUEUE); headers.setInt(DEQUEUED_MESSAGE_POSITION, dequeued.position); boost::intrusive_ptr<Message> msg(createMessage(headers)); - queue->deliver(msg); + DeliveryProperties* props = msg->getFrames().getHeaders()->get<DeliveryProperties>(true); + props->setRoutingKey(dequeued.queue->getName()); + route(msg); } void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueued) @@ -69,11 +71,27 @@ void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueu boost::intrusive_ptr<Message> msg(cloneMessage(*(enqueued.queue), enqueued.payload)); FieldTable& headers = msg->getProperties<MessageProperties>()->getApplicationHeaders(); headers.setString(REPLICATION_TARGET_QUEUE, enqueued.queue->getName()); - headers.setInt(REPLICATION_EVENT_SEQNO, ++sequence); headers.setInt(REPLICATION_EVENT_TYPE, ENQUEUE); - queue->deliver(msg); + route(msg); } +void ReplicatingEventListener::route(boost::intrusive_ptr<qpid::broker::Message> msg) +{ + try { + if (exchange) { + DeliverableMessage deliverable(msg); + exchange->route(deliverable, msg->getRoutingKey(), msg->getApplicationHeaders()); + } else if (queue) { + queue->deliver(msg); + } else { + QPID_LOG(error, "Cannot route replication event, neither replication queue nor exchange configured"); + } + } catch (const std::exception& e) { + QPID_LOG(error, "Error enqueing replication event: " << e.what()); + } +} + + boost::intrusive_ptr<Message> ReplicatingEventListener::createMessage(const FieldTable& headers) { boost::intrusive_ptr<Message> msg(new Message()); @@ -129,30 +147,49 @@ Options* ReplicatingEventListener::getOptions() void ReplicatingEventListener::initialize(Plugin::Target& target) { - Broker* broker = dynamic_cast<broker::Broker*>(&target); - if (broker && !options.queue.empty()) { - if (options.createQueue) { - queue = broker->getQueues().declare(options.queue).first; - } else { - queue = broker->getQueues().find(options.queue); - } - if (queue) { - QueueEvents::EventListener callback = boost::bind(&ReplicatingEventListener::handle, this, _1); - broker->getQueueEvents().registerListener(options.name, callback); - QPID_LOG(info, "Registered replicating queue event listener"); - } else { - QPID_LOG(error, "Replication queue named '" << options.queue << "' does not exist; replication plugin disabled."); - } - } + Broker* broker = dynamic_cast<broker::Broker*>(&target); + if (broker) { + broker->addFinalizer(boost::bind(&ReplicatingEventListener::shutdown, this)); + if (!options.exchange.empty()) { + if (!options.queue.empty()) { + QPID_LOG(warning, "Replication queue option ignored as replication exchange has been specified"); + } + try { + exchange = broker->getExchanges().declare(options.exchange, options.exchangeType).first; + } catch (const UnknownExchangeTypeException&) { + QPID_LOG(error, "Replication disabled due to invalid type: " << options.exchangeType); + } + } else if (!options.queue.empty()) { + if (options.createQueue) { + queue = broker->getQueues().declare(options.queue).first; + } else { + queue = broker->getQueues().find(options.queue); + } + if (queue) { + queue->insertSequenceNumbers(REPLICATION_EVENT_SEQNO); + } else { + QPID_LOG(error, "Replication queue named '" << options.queue << "' does not exist; replication plugin disabled."); + } + } + if (queue || exchange) { + QueueEvents::EventListener callback = boost::bind(&ReplicatingEventListener::handle, this, _1); + broker->getQueueEvents().registerListener(options.name, callback); + QPID_LOG(info, "Registered replicating queue event listener"); + } + } } void ReplicatingEventListener::earlyInitialize(Target&) {} +void ReplicatingEventListener::shutdown() { queue.reset(); exchange.reset(); } ReplicatingEventListener::PluginOptions::PluginOptions() : Options("Queue Replication Options"), - name("replicator"), + exchangeType("direct"), + name("replicator"), createQueue(false) { addOptions() + ("replication-exchange-name", optValue(exchange, "EXCHANGE"), "Exchange to which events for other queues are routed") + ("replication-exchange-type", optValue(exchangeType, "direct|topic etc"), "Type of exchange to use") ("replication-queue", optValue(queue, "QUEUE"), "Queue on which events for other queues are recorded") ("replication-listener-name", optValue(name, "NAME"), "name by which to register the replicating event listener") ("create-replication-queue", optValue(createQueue), "if set, the replication will be created if it does not exist"); diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h index 7616c7ac8a..74418d00e6 100644 --- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h +++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h @@ -24,6 +24,7 @@ #include "qpid/Plugin.h" #include "qpid/Options.h" +#include "qpid/broker/Exchange.h" #include "qpid/broker/Message.h" #include "qpid/broker/Queue.h" #include "qpid/broker/QueueEvents.h" @@ -50,6 +51,8 @@ class ReplicatingEventListener : public Plugin struct PluginOptions : public Options { std::string queue; + std::string exchange; + std::string exchangeType; std::string name; bool createQueue; @@ -58,10 +61,12 @@ class ReplicatingEventListener : public Plugin PluginOptions options; qpid::broker::Queue::shared_ptr queue; - qpid::framing::SequenceNumber sequence; + qpid::broker::Exchange::shared_ptr exchange; void deliverDequeueMessage(const qpid::broker::QueuedMessage& enqueued); void deliverEnqueueMessage(const qpid::broker::QueuedMessage& enqueued); + void route(boost::intrusive_ptr<qpid::broker::Message>); + void shutdown(); boost::intrusive_ptr<qpid::broker::Message> createMessage(const qpid::framing::FieldTable& headers); boost::intrusive_ptr<qpid::broker::Message> cloneMessage(qpid::broker::Queue& queue, diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp index 639cfb5d2e..29cdf21bc6 100644 --- a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp +++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp @@ -34,11 +34,13 @@ using namespace qpid::broker; using namespace qpid::framing; using namespace qpid::replication::constants; +const std::string SEQUENCE_VALUE("qpid.replication-event.sequence"); ReplicationExchange::ReplicationExchange(const std::string& name, bool durable, const FieldTable& args, QueueRegistry& qr, Manageable* parent) - : Exchange(name, durable, args, parent), queues(qr), init(false) {} + : Exchange(name, durable, args, parent), queues(qr), sequence(args.getAsInt64(SEQUENCE_VALUE)), init(false) + {} std::string ReplicationExchange::getType() const { return typeName; } @@ -68,31 +70,39 @@ void ReplicationExchange::handleEnqueueEvent(const FieldTable* args, Deliverable { std::string queueName = args->getAsString(REPLICATION_TARGET_QUEUE); Queue::shared_ptr queue = queues.find(queueName); - FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders(); - headers.erase(REPLICATION_TARGET_QUEUE); - headers.erase(REPLICATION_EVENT_SEQNO); - headers.erase(REPLICATION_EVENT_TYPE); - msg.deliverTo(queue); - QPID_LOG(debug, "Enqueued replicated message onto " << queue); + if (queue) { + FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders(); + headers.erase(REPLICATION_TARGET_QUEUE); + headers.erase(REPLICATION_EVENT_SEQNO); + headers.erase(REPLICATION_EVENT_TYPE); + msg.deliverTo(queue); + QPID_LOG(debug, "Enqueued replicated message onto " << queueName); + } else { + QPID_LOG(error, "Cannot enqueue replicated message. Queue " << queueName << " does not exist"); + } } void ReplicationExchange::handleDequeueEvent(const FieldTable* args) { std::string queueName = args->getAsString(REPLICATION_TARGET_QUEUE); Queue::shared_ptr queue = queues.find(queueName); - SequenceNumber position(args->getAsInt(DEQUEUED_MESSAGE_POSITION)); - - QueuedMessage dequeued; - if (queue->acquireMessageAt(position, dequeued)) { - queue->dequeue(0, dequeued); - QPID_LOG(debug, "Processed replicated 'dequeue' event from " << queueName << " at position " << position); + if (queue) { + SequenceNumber position(args->getAsInt(DEQUEUED_MESSAGE_POSITION)); + QueuedMessage dequeued; + if (queue->acquireMessageAt(position, dequeued)) { + queue->dequeue(0, dequeued); + QPID_LOG(debug, "Processed replicated 'dequeue' event from " << queueName << " at position " << position); + } else { + QPID_LOG(warning, "Could not acquire message " << position << " from " << queueName); + } } else { - QPID_LOG(warning, "Could not acquire message " << position << " from " << queueName); + QPID_LOG(error, "Cannot process replicated 'dequeue' event. Queue " << queueName << " does not exist"); } } bool ReplicationExchange::isDuplicate(const FieldTable* args) { + if (!args->get(REPLICATION_EVENT_SEQNO)) return false; SequenceNumber seqno(args->getAsInt(REPLICATION_EVENT_SEQNO)); if (!init) { init = true; @@ -128,6 +138,13 @@ bool ReplicationExchange::isBound(Queue::shared_ptr /*queue*/, const string* con const std::string ReplicationExchange::typeName("replication"); +void ReplicationExchange::encode(Buffer& buffer) const +{ + args.setInt64(std::string(SEQUENCE_VALUE), sequence); + Exchange::encode(buffer); +} + + struct ReplicationExchangePlugin : Plugin { Broker* broker; diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.h b/qpid/cpp/src/qpid/replication/ReplicationExchange.h index 897e4a954e..4cc45ed5f5 100644 --- a/qpid/cpp/src/qpid/replication/ReplicationExchange.h +++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.h @@ -22,6 +22,7 @@ * */ #include "qpid/broker/Exchange.h" +#include "qpid/framing/Buffer.h" #include "qpid/framing/SequenceNumber.h" namespace qpid { @@ -58,6 +59,7 @@ class ReplicationExchange : public qpid::broker::Exchange bool isDuplicate(const qpid::framing::FieldTable* args); void handleEnqueueEvent(const qpid::framing::FieldTable* args, qpid::broker::Deliverable& msg); void handleDequeueEvent(const qpid::framing::FieldTable* args); + void encode(framing::Buffer& buffer) const; }; }} // namespace qpid::replication diff --git a/qpid/cpp/src/qpid/sys/AggregateOutput.h b/qpid/cpp/src/qpid/sys/AggregateOutput.h index 1cda4456b4..fcd0d4c2f7 100644 --- a/qpid/cpp/src/qpid/sys/AggregateOutput.h +++ b/qpid/cpp/src/qpid/sys/AggregateOutput.h @@ -24,6 +24,7 @@ #include "Mutex.h" #include "OutputControl.h" #include "OutputTask.h" +#include "qpid/CommonImportExport.h" #include <algorithm> #include <vector> @@ -42,15 +43,15 @@ namespace sys { public: AggregateOutput(OutputControl& c) : next(0), control(c) {}; //this may be called on any thread - void activateOutput(); - void giveReadCredit(int32_t); + QPID_COMMON_EXTERN void activateOutput(); + QPID_COMMON_EXTERN void giveReadCredit(int32_t); //all the following will be called on the same thread - bool doOutput(); - bool hasOutput(); - void addOutputTask(OutputTask* t); - void removeOutputTask(OutputTask* t); - void removeAll(); + QPID_COMMON_EXTERN bool doOutput(); + QPID_COMMON_EXTERN bool hasOutput(); + QPID_COMMON_EXTERN void addOutputTask(OutputTask* t); + QPID_COMMON_EXTERN void removeOutputTask(OutputTask* t); + QPID_COMMON_EXTERN void removeAll(); /** Apply f to each OutputTask* in the tasks list */ template <class F> void eachOutput(F f) { diff --git a/qpid/cpp/src/qpid/sys/AsynchIO.h b/qpid/cpp/src/qpid/sys/AsynchIO.h index ffd4436c2a..fb02183359 100644 --- a/qpid/cpp/src/qpid/sys/AsynchIO.h +++ b/qpid/cpp/src/qpid/sys/AsynchIO.h @@ -22,7 +22,7 @@ */ #include "qpid/sys/IntegerTypes.h" - +#include "qpid/CommonImportExport.h" #include <boost/function.hpp> #include <boost/shared_ptr.hpp> @@ -45,9 +45,9 @@ private: AsynchAcceptorPrivate* impl; public: - AsynchAcceptor(const Socket& s, Callback callback); - ~AsynchAcceptor(); - void start(boost::shared_ptr<Poller> poller); + QPID_COMMON_EXTERN AsynchAcceptor(const Socket& s, Callback callback); + QPID_COMMON_EXTERN ~AsynchAcceptor(); + QPID_COMMON_EXTERN void start(boost::shared_ptr<Poller> poller); }; /* @@ -65,7 +65,7 @@ public: // create a correctly typed object. The platform code also manages // deletes. To correctly manage heaps when needed, the allocate and // delete should both be done from the same class/library. - static AsynchConnector* create(const Socket& s, + QPID_COMMON_EXTERN static AsynchConnector* create(const Socket& s, boost::shared_ptr<Poller> poller, std::string hostname, uint16_t port, @@ -121,7 +121,7 @@ public: // create a correctly typed object. The platform code also manages // deletes. To correctly manage heaps when needed, the allocate and // delete should both be done from the same class/library. - static AsynchIO* create(const Socket& s, + QPID_COMMON_EXTERN static AsynchIO* create(const Socket& s, ReadCallback rCb, EofCallback eofCb, DisconnectCallback disCb, diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp b/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp index 3bc05e4bf9..6b7e7b5145 100644 --- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp +++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp @@ -84,10 +84,11 @@ void AsynchIOHandler::giveReadCredit(int32_t credit) { // Check whether we started in the don't about credit state if (readCredit.boolCompareAndSwap(InfiniteCredit, credit)) return; - else if (readCredit.fetchAndAdd(credit) != 0) - return; - // Lock and retest credit to make sure we don't race with decreasing credit + // TODO In theory should be able to use an atomic operation before taking the lock + // but in practice there seems to be an unexplained race in that case ScopedLock<Mutex> l(creditLock); + if (readCredit.fetchAndAdd(credit) != 0) + return; assert(readCredit.get() >= 0); if (readCredit.get() != 0) aio->startReading(); @@ -141,9 +142,10 @@ bool AsynchIOHandler::readbuff(AsynchIO& , AsynchIO::BufferBase* buff) { } // Check here for read credit if (readCredit.get() != InfiniteCredit) { + // TODO In theory should be able to use an atomic operation before taking the lock + // but in practice there seems to be an unexplained race in that case + ScopedLock<Mutex> l(creditLock); if (--readCredit == 0) { - // Lock and retest credit to make sure we don't race with increasing credit - ScopedLock<Mutex> l(creditLock); assert(readCredit.get() >= 0); if (readCredit.get() == 0) { aio->stopReading(); diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h index fa020fbce4..9f1d043b62 100644 --- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h +++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h @@ -25,6 +25,7 @@ #include "ConnectionCodec.h" #include "AtomicValue.h" #include "Mutex.h" +#include "qpid/CommonImportExport.h" namespace qpid { @@ -52,26 +53,26 @@ class AsynchIOHandler : public OutputControl { void write(const framing::ProtocolInitiation&); public: - AsynchIOHandler(std::string id, ConnectionCodec::Factory* f); - ~AsynchIOHandler(); - void init(AsynchIO* a, int numBuffs); + QPID_COMMON_EXTERN AsynchIOHandler(std::string id, ConnectionCodec::Factory* f); + QPID_COMMON_EXTERN ~AsynchIOHandler(); + QPID_COMMON_EXTERN void init(AsynchIO* a, int numBuffs); - void setClient() { isClient = true; } + QPID_COMMON_EXTERN void setClient() { isClient = true; } // Output side - void close(); - void activateOutput(); - void giveReadCredit(int32_t credit); + QPID_COMMON_EXTERN void close(); + QPID_COMMON_EXTERN void activateOutput(); + QPID_COMMON_EXTERN void giveReadCredit(int32_t credit); // Input side - bool readbuff(AsynchIO& aio, AsynchIOBufferBase* buff); - void eof(AsynchIO& aio); - void disconnect(AsynchIO& aio); + QPID_COMMON_EXTERN bool readbuff(AsynchIO& aio, AsynchIOBufferBase* buff); + QPID_COMMON_EXTERN void eof(AsynchIO& aio); + QPID_COMMON_EXTERN void disconnect(AsynchIO& aio); // Notifications - void nobuffs(AsynchIO& aio); - void idle(AsynchIO& aio); - void closedSocket(AsynchIO& aio, const Socket& s); + QPID_COMMON_EXTERN void nobuffs(AsynchIO& aio); + QPID_COMMON_EXTERN void idle(AsynchIO& aio); + QPID_COMMON_EXTERN void closedSocket(AsynchIO& aio, const Socket& s); }; }} // namespace qpid::sys diff --git a/qpid/cpp/src/qpid/sys/Codec.h b/qpid/cpp/src/qpid/sys/Codec.h index f9645f554e..ace721fbcc 100644 --- a/qpid/cpp/src/qpid/sys/Codec.h +++ b/qpid/cpp/src/qpid/sys/Codec.h @@ -38,11 +38,11 @@ class Codec * @return may be less than size if there was incomplete * data at the end of the buffer. */ - virtual size_t decode(const char* buffer, size_t size) = 0; + virtual std::size_t decode(const char* buffer, std::size_t size) = 0; /** Encode into buffer, return number of bytes encoded */ - virtual size_t encode(const char* buffer, size_t size) = 0; + virtual std::size_t encode(const char* buffer, std::size_t size) = 0; /** Return true if we have data to encode */ virtual bool canEncode() = 0; diff --git a/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h b/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h index df6de89982..32809d86a1 100644 --- a/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h +++ b/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h @@ -30,7 +30,7 @@ namespace sys { /** * A ConnectionOutputHandler that delegates to another * ConnectionOutputHandler. Allows the "real" ConnectionOutputHandler - * to be changed modified without updating all the pointers/references + * to be changed without updating all the pointers/references * using the ConnectionOutputHandlerPtr */ class ConnectionOutputHandlerPtr : public ConnectionOutputHandler diff --git a/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h b/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h index a09ee9d441..577a475afd 100644 --- a/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h +++ b/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h @@ -80,7 +80,7 @@ public: bool add_unless(T& t, F f) { Mutex::ScopedLock l(lock); - if (array && find_if(array->begin(), array->end(), f) != array->end()) { + if (array && std::find_if(array->begin(), array->end(), f) != array->end()) { return false; } else { ArrayPtr copy(array ? new std::vector<T>(*array) : new std::vector<T>()); diff --git a/qpid/cpp/src/qpid/sys/DispatchHandle.cpp b/qpid/cpp/src/qpid/sys/DispatchHandle.cpp index cbdee7eda6..cd7dec7fa6 100644 --- a/qpid/cpp/src/qpid/sys/DispatchHandle.cpp +++ b/qpid/cpp/src/qpid/sys/DispatchHandle.cpp @@ -21,6 +21,8 @@ #include "DispatchHandle.h" +#include <algorithm> + #include <boost/cast.hpp> #include <assert.h> @@ -29,7 +31,6 @@ namespace qpid { namespace sys { DispatchHandle::~DispatchHandle() { - stopWatch(); } void DispatchHandle::startWatch(Poller::shared_ptr poller0) { @@ -37,13 +38,21 @@ void DispatchHandle::startWatch(Poller::shared_ptr poller0) { bool w = writableCallback; ScopedLock<Mutex> lock(stateLock); - assert(state == IDLE); + assert(state == IDLE || state == DELAYED_IDLE); // If no callbacks set then do nothing (that is what we were asked to do!) // TODO: Maybe this should be an assert instead if (!r && !w) { - state = INACTIVE; - return; + switch (state) { + case IDLE: + state = INACTIVE; + return; + case DELAYED_IDLE: + state = DELAYED_INACTIVE; + return; + default: + assert(state == IDLE || state == DELAYED_IDLE); + } } Poller::Direction d = r ? @@ -53,9 +62,20 @@ void DispatchHandle::startWatch(Poller::shared_ptr poller0) { poller = poller0; poller->addFd(*this, d); - state = r ? - (w ? ACTIVE_RW : ACTIVE_R) : - ACTIVE_W; + switch (state) { + case IDLE: + state = r ? + (w ? ACTIVE_RW : ACTIVE_R) : + ACTIVE_W; + return; + case DELAYED_IDLE: + state = r ? + (w ? DELAYED_RW : DELAYED_R) : + DELAYED_W; + return; + default: + assert(state == IDLE || state == DELAYED_IDLE); + } } void DispatchHandle::rewatch() { @@ -93,6 +113,8 @@ void DispatchHandle::rewatch() { case ACTIVE_RW: // Don't need to do anything already waiting for readable/writable break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } } @@ -130,6 +152,8 @@ void DispatchHandle::rewatchRead() { poller->modFd(*this, Poller::INOUT); state = ACTIVE_RW; break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } } @@ -167,6 +191,8 @@ void DispatchHandle::rewatchWrite() { case ACTIVE_RW: // Nothing to do: already waiting for writable break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } } @@ -203,6 +229,8 @@ void DispatchHandle::unwatchRead() { case ACTIVE_W: case INACTIVE: break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } } @@ -239,6 +267,8 @@ void DispatchHandle::unwatchWrite() { case ACTIVE_R: case INACTIVE: break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } } @@ -261,6 +291,8 @@ void DispatchHandle::unwatch() { poller->modFd(*this, Poller::NONE); state = INACTIVE; break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } } @@ -280,47 +312,72 @@ void DispatchHandle::stopWatch() { default: state = IDLE; break; + case ACTIVE_DELETE: + assert(state != ACTIVE_DELETE); } assert(poller); poller->delFd(*this); poller.reset(); } +// If we are already in the IDLE state we can't do the callback as we might +// race to delete and callback at the same time +// TODO: might be able to fix this by adding a new state, but would make +// the state machine even more complex void DispatchHandle::call(Callback iCb) { assert(iCb); ScopedLock<Mutex> lock(stateLock); - interruptedCallbacks.push(iCb); - - (void) poller->interrupt(*this); + switch (state) { + case IDLE: + case ACTIVE_DELETE: + assert(false); + return; + default: + interruptedCallbacks.push(iCb); + assert(poller); + (void) poller->interrupt(*this); + } } // The slightly strange switch structure // is to ensure that the lock is released before // we do the delete void DispatchHandle::doDelete() { - // Ensure that we're no longer watching anything - stopWatch(); - - // If we're in the middle of a callback defer the delete { ScopedLock<Mutex> lock(stateLock); + // Ensure that we're no longer watching anything switch (state) { + case DELAYED_R: + case DELAYED_W: + case DELAYED_RW: + case DELAYED_INACTIVE: + assert(poller); + poller->delFd(*this); + poller.reset(); + // Fallthrough case DELAYED_IDLE: - case DELAYED_DELETE: state = DELAYED_DELETE; + // Fallthrough + case DELAYED_DELETE: + case ACTIVE_DELETE: return; case IDLE: break; default: - // Can only get out of stopWatch() in DELAYED_IDLE/DELAYED_DELETE/IDLE states - assert(false); + state = ACTIVE_DELETE; + assert(poller); + (void) poller->interrupt(*this); + poller->delFd(*this); + return; } } - // If we're not then do it right away + // If we're IDLE we can do this right away delete this; } void DispatchHandle::processEvent(Poller::EventType type) { + CallbackQueue callbacks; + // Note that we are now doing the callbacks { ScopedLock<Mutex> lock(stateLock); @@ -336,6 +393,16 @@ void DispatchHandle::processEvent(Poller::EventType type) { case ACTIVE_RW: state = DELAYED_RW; break; + case ACTIVE_DELETE: + // Need to make sure we clean up any pending callbacks in this case + std::swap(callbacks, interruptedCallbacks); + goto saybyebye; + // Can get here in idle if we are stopped in a different thread + // just after we return with this handle in Poller::wait + case IDLE: + // Can get here in INACTIVE if a non connection thread unwatches + // whilst we were stuck in the above lock + case INACTIVE: // Can only get here in a DELAYED_* state in the rare case // that we're already here for reading and we get activated for // writing and we can write (it might be possible the other way @@ -348,9 +415,9 @@ void DispatchHandle::processEvent(Poller::EventType type) { case DELAYED_IDLE: case DELAYED_DELETE: return; - default: - assert(false); } + + std::swap(callbacks, interruptedCallbacks); } // Do callbacks - whilst we are doing the callbacks we are prevented from processing @@ -378,8 +445,8 @@ void DispatchHandle::processEvent(Poller::EventType type) { break; case Poller::INTERRUPTED: { - ScopedLock<Mutex> lock(stateLock); - assert(interruptedCallbacks.size() > 0); + // We could only be interrupted if we also had a callback to do + assert(callbacks.size() > 0); // We'll actually do the interrupt below } break; @@ -387,16 +454,18 @@ void DispatchHandle::processEvent(Poller::EventType type) { assert(false); } - { - ScopedLock<Mutex> lock(stateLock); - // If we've got a pending interrupt do it now - while (interruptedCallbacks.size() > 0) { - Callback cb = interruptedCallbacks.front(); + // If we have any callbacks do them now - + // (because we use a copy from before the previous callbacks we won't + // do anything yet that was just added) + while (callbacks.size() > 0) { + Callback cb = callbacks.front(); assert(cb); cb(*this); - interruptedCallbacks.pop(); + callbacks.pop(); } + { + ScopedLock<Mutex> lock(stateLock); // If any of the callbacks re-enabled reading/writing then actually // do it now switch (state) { @@ -425,7 +494,9 @@ void DispatchHandle::processEvent(Poller::EventType type) { case DELAYED_DELETE: break; } - } + } + +saybyebye: delete this; } diff --git a/qpid/cpp/src/qpid/sys/DispatchHandle.h b/qpid/cpp/src/qpid/sys/DispatchHandle.h index ffcbd80f7e..bc9f98775e 100644 --- a/qpid/cpp/src/qpid/sys/DispatchHandle.h +++ b/qpid/cpp/src/qpid/sys/DispatchHandle.h @@ -24,7 +24,7 @@ #include "Poller.h" #include "Mutex.h" - +#include "qpid/CommonImportExport.h" #include <boost/function.hpp> #include <queue> @@ -65,6 +65,7 @@ private: Mutex stateLock; enum { IDLE, INACTIVE, ACTIVE_R, ACTIVE_W, ACTIVE_RW, + ACTIVE_DELETE, DELAYED_IDLE, DELAYED_INACTIVE, DELAYED_R, DELAYED_W, DELAYED_RW, DELAYED_DELETE } state; @@ -82,7 +83,7 @@ public: *@param wCb Callback called when the handle is writable. *@param dCb Callback called when the handle is disconnected. */ - DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) : + QPID_COMMON_EXTERN DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) : PollerHandle(h), readableCallback(rCb), writableCallback(wCb), @@ -90,42 +91,42 @@ public: state(IDLE) {} - ~DispatchHandle(); + QPID_COMMON_EXTERN ~DispatchHandle(); /** Add this DispatchHandle to the poller to be watched. */ - void startWatch(Poller::shared_ptr poller); + QPID_COMMON_EXTERN void startWatch(Poller::shared_ptr poller); /** Resume watching for all non-0 callbacks. */ - void rewatch(); + QPID_COMMON_EXTERN void rewatch(); /** Resume watching for read only. */ - void rewatchRead(); + QPID_COMMON_EXTERN void rewatchRead(); /** Resume watching for write only. */ - void rewatchWrite(); + QPID_COMMON_EXTERN void rewatchWrite(); /** Stop watching temporarily. The DispatchHandle remains associated with the poller and can be re-activated using rewatch. */ - void unwatch(); + QPID_COMMON_EXTERN void unwatch(); /** Stop watching for read */ - void unwatchRead(); + QPID_COMMON_EXTERN void unwatchRead(); /** Stop watching for write */ - void unwatchWrite(); + QPID_COMMON_EXTERN void unwatchWrite(); /** Stop watching permanently. Disassociates from the poller. */ - void stopWatch(); + QPID_COMMON_EXTERN void stopWatch(); /** Interrupt watching this handle and make a serialised callback that respects the * same exclusivity guarantees as the other callbacks */ - void call(Callback iCb); + QPID_COMMON_EXTERN void call(Callback iCb); protected: /** Override to get extra processing done when the DispatchHandle is deleted. */ - void doDelete(); + QPID_COMMON_EXTERN void doDelete(); private: - void processEvent(Poller::EventType dir); + QPID_COMMON_EXTERN void processEvent(Poller::EventType dir); }; class DispatchHandleRef { diff --git a/qpid/cpp/src/qpid/sys/Dispatcher.h b/qpid/cpp/src/qpid/sys/Dispatcher.h index f7c9e8d731..2f3ed10901 100644 --- a/qpid/cpp/src/qpid/sys/Dispatcher.h +++ b/qpid/cpp/src/qpid/sys/Dispatcher.h @@ -24,6 +24,7 @@ #include "Poller.h" #include "Runnable.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace sys { @@ -32,10 +33,10 @@ class Dispatcher : public Runnable { const Poller::shared_ptr poller; public: - Dispatcher(Poller::shared_ptr poller); - ~Dispatcher(); + QPID_COMMON_EXTERN Dispatcher(Poller::shared_ptr poller); + QPID_COMMON_EXTERN ~Dispatcher(); - void run(); + QPID_COMMON_EXTERN void run(); }; }} diff --git a/qpid/cpp/src/qpid/sys/IOHandle.h b/qpid/cpp/src/qpid/sys/IOHandle.h index 0bf2abbafa..656e5e1efd 100644 --- a/qpid/cpp/src/qpid/sys/IOHandle.h +++ b/qpid/cpp/src/qpid/sys/IOHandle.h @@ -22,6 +22,8 @@ * */ +#include "qpid/CommonImportExport.h" + namespace qpid { namespace sys { @@ -50,8 +52,8 @@ class IOHandle { protected: IOHandlePrivate* const impl; - IOHandle(IOHandlePrivate*); - virtual ~IOHandle(); + IOHandle(IOHandlePrivate*); + QPID_COMMON_EXTERN virtual ~IOHandle(); }; }} diff --git a/qpid/cpp/src/qpid/sys/PollableCondition.h b/qpid/cpp/src/qpid/sys/PollableCondition.h index 56d38f90da..f49fb22cb4 100644 --- a/qpid/cpp/src/qpid/sys/PollableCondition.h +++ b/qpid/cpp/src/qpid/sys/PollableCondition.h @@ -22,7 +22,58 @@ * */ -// Currently only has a posix implementation, add #ifdefs for other platforms as needed. -#include "posix/PollableCondition.h" +#include "qpid/sys/Poller.h" +#include "qpid/CommonImportExport.h" +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> + + +namespace qpid { +namespace sys { + +class PollableConditionPrivate; + +class PollableCondition { +public: + typedef boost::function1<void, PollableCondition&> Callback; + + QPID_COMMON_EXTERN PollableCondition(const Callback& cb, + const boost::shared_ptr<sys::Poller>& poller); + + QPID_COMMON_EXTERN ~PollableCondition(); + + /** + * Set the condition. Triggers callback to Callback from Poller. + * When callback is made, condition is suspended. Call rearm() to + * resume reacting to the condition. + */ + QPID_COMMON_EXTERN void set(); + + /** + * Get the current state of the condition, then clear it. + * + * @return The state of the condition before it was cleared. + */ + QPID_COMMON_EXTERN bool clear(); + + /** + * Temporarily suspend the ability for the poller to react to the + * condition. It can be rearm()ed later. + */ + QPID_COMMON_EXTERN void disarm(); + + /** + * Reset the ability for the poller to react to the condition. + */ + QPID_COMMON_EXTERN void rearm(); + + private: + PollableConditionPrivate *impl; + + Callback callback; + boost::shared_ptr<sys::Poller> poller; +}; + +}} // namespace qpid::sys #endif /*!QPID_SYS_POLLABLECONDITION_H*/ diff --git a/qpid/cpp/src/qpid/sys/PollableQueue.h b/qpid/cpp/src/qpid/sys/PollableQueue.h index b5ff98c2c7..f8acf0a5f6 100644 --- a/qpid/cpp/src/qpid/sys/PollableQueue.h +++ b/qpid/cpp/src/qpid/sys/PollableQueue.h @@ -23,8 +23,6 @@ */ #include "qpid/sys/PollableCondition.h" -#include "qpid/sys/Dispatcher.h" -#include "qpid/sys/DispatchHandle.h" #include "qpid/sys/Monitor.h" #include "qpid/sys/Thread.h" #include <boost/function.hpp> @@ -38,9 +36,10 @@ namespace sys { class Poller; /** - * A queue that can be polled by sys::Poller. Any thread can push to - * the queue, on wakeup the poller thread processes all items on the - * queue by passing them to a callback in a batch. + * A queue whose item processing is dispatched by sys::Poller. + * Any thread can push to the queue; items pushed trigger an event the Poller + * recognizes. When a Poller I/O thread dispatches the event, a + * user-specified callback is invoked with all items on the queue. */ template <class T> class PollableQueue { @@ -50,12 +49,21 @@ class PollableQueue { /** * Callback to process a batch of items from the queue. - * @param values to process, any items remaining after call are put back on the queue. + * + * @param values Queue of values to process. Any items remaining + * on return from Callback are put back on the queue. */ - typedef boost::function<void (Queue& values)> Callback; + typedef boost::function<void (Queue&)> Callback; - /** When the queue is selected by the poller, values are passed to callback cb. */ - PollableQueue(const Callback& cb, const boost::shared_ptr<sys::Poller>& poller); + /** + * Constructor; sets necessary parameters. + * + * @param cb Callback that will be called to process items on the + * queue. Will be called from a Poller I/O thread. + * @param poller Poller to use for dispatching queue events. + */ + PollableQueue(const Callback& cb, + const boost::shared_ptr<sys::Poller>& poller); ~PollableQueue(); @@ -85,14 +93,12 @@ class PollableQueue { typedef sys::Monitor::ScopedLock ScopedLock; typedef sys::Monitor::ScopedUnlock ScopedUnlock; - void dispatch(sys::DispatchHandle&); + void dispatch(PollableCondition& cond); void process(); mutable sys::Monitor lock; Callback callback; - boost::shared_ptr<sys::Poller> poller; PollableCondition condition; - DispatchHandleRef handle; Queue queue, batch; Thread dispatcher; bool stopped; @@ -100,11 +106,10 @@ class PollableQueue { template <class T> PollableQueue<T>::PollableQueue( const Callback& cb, const boost::shared_ptr<sys::Poller>& p) - : callback(cb), poller(p), - handle(condition, boost::bind(&PollableQueue<T>::dispatch, this, _1), 0, 0), stopped(true) + : callback(cb), + condition(boost::bind(&PollableQueue<T>::dispatch, this, _1), p), + stopped(true) { - handle.startWatch(poller); - handle.unwatch(); } template <class T> void PollableQueue<T>::start() { @@ -112,11 +117,10 @@ template <class T> void PollableQueue<T>::start() { if (!stopped) return; stopped = false; if (!queue.empty()) condition.set(); - handle.rewatch(); + condition.rearm(); } template <class T> PollableQueue<T>::~PollableQueue() { - handle.stopWatch(); } template <class T> void PollableQueue<T>::push(const T& t) { @@ -125,15 +129,15 @@ template <class T> void PollableQueue<T>::push(const T& t) { queue.push_back(t); } -template <class T> void PollableQueue<T>::dispatch(sys::DispatchHandle& h) { +template <class T> void PollableQueue<T>::dispatch(PollableCondition& cond) { ScopedLock l(lock); assert(dispatcher.id() == 0); dispatcher = Thread::current(); process(); dispatcher = Thread(); - if (queue.empty()) condition.clear(); + if (queue.empty()) cond.clear(); if (stopped) lock.notifyAll(); - else h.rewatch(); + else cond.rearm(); } template <class T> void PollableQueue<T>::process() { @@ -159,7 +163,7 @@ template <class T> void PollableQueue<T>::shutdown() { template <class T> void PollableQueue<T>::stop() { ScopedLock l(lock); if (stopped) return; - handle.unwatch(); + condition.disarm(); stopped = true; // Avoid deadlock if stop is called from the dispatch thread while (dispatcher.id() && dispatcher.id() != Thread::current().id()) diff --git a/qpid/cpp/src/qpid/sys/Poller.h b/qpid/cpp/src/qpid/sys/Poller.h index 8e9f67fefd..825ad8bfed 100644 --- a/qpid/cpp/src/qpid/sys/Poller.h +++ b/qpid/cpp/src/qpid/sys/Poller.h @@ -24,7 +24,7 @@ #include "Time.h" #include "Runnable.h" - +#include "qpid/CommonImportExport.h" #include <boost/shared_ptr.hpp> namespace qpid { @@ -74,10 +74,10 @@ public: void process(); }; - Poller(); - ~Poller(); + QPID_COMMON_EXTERN Poller(); + QPID_COMMON_EXTERN ~Poller(); /** Note: this function is async-signal safe */ - void shutdown(); + QPID_COMMON_EXTERN void shutdown(); // Interrupt waiting for a specific poller handle // returns true if we could interrupt the handle @@ -86,18 +86,19 @@ public: // with the handle and the INTERRUPTED event type // if it returns false then the handle is not being monitored by the poller // - This can either be because it has just received an event which has been - // reported and has not been reenabled since. Or because it was removed - // from the monitoring set - bool interrupt(PollerHandle& handle); + // reported and has not been reenabled since. + // - Because it was removed from the monitoring set + // - Or because it is already being interrupted + QPID_COMMON_EXTERN bool interrupt(PollerHandle& handle); // Poller run loop - void run(); + QPID_COMMON_EXTERN void run(); - void addFd(PollerHandle& handle, Direction dir); - void delFd(PollerHandle& handle); - void modFd(PollerHandle& handle, Direction dir); - void rearmFd(PollerHandle& handle); - Event wait(Duration timeout = TIME_INFINITE); + QPID_COMMON_EXTERN void addFd(PollerHandle& handle, Direction dir); + QPID_COMMON_EXTERN void delFd(PollerHandle& handle); + QPID_COMMON_EXTERN void modFd(PollerHandle& handle, Direction dir); + QPID_COMMON_EXTERN void rearmFd(PollerHandle& handle); + QPID_COMMON_EXTERN Event wait(Duration timeout = TIME_INFINITE); }; /** @@ -110,11 +111,11 @@ class PollerHandle { friend struct Poller::Event; PollerHandlePrivate* const impl; - virtual void processEvent(Poller::EventType) {}; + QPID_COMMON_EXTERN virtual void processEvent(Poller::EventType) {}; public: - PollerHandle(const IOHandle& h); - virtual ~PollerHandle(); + QPID_COMMON_EXTERN PollerHandle(const IOHandle& h); + QPID_COMMON_EXTERN virtual ~PollerHandle(); }; inline void Poller::Event::process() { diff --git a/qpid/cpp/src/qpid/sys/Runnable.h b/qpid/cpp/src/qpid/sys/Runnable.h index fb3927c612..4bf43c93d1 100644 --- a/qpid/cpp/src/qpid/sys/Runnable.h +++ b/qpid/cpp/src/qpid/sys/Runnable.h @@ -22,6 +22,7 @@ */ #include <boost/function.hpp> +#include "qpid/CommonImportExport.h" namespace qpid { namespace sys { @@ -35,7 +36,7 @@ class Runnable /** Type to represent a runnable as a Functor */ typedef boost::function0<void> Functor; - virtual ~Runnable(); + QPID_COMMON_EXTERN virtual ~Runnable(); /** Derived classes override run(). */ virtual void run() = 0; diff --git a/qpid/cpp/src/qpid/sys/Shlib.h b/qpid/cpp/src/qpid/sys/Shlib.h index a6d94b42d4..7f66cfec14 100644 --- a/qpid/cpp/src/qpid/sys/Shlib.h +++ b/qpid/cpp/src/qpid/sys/Shlib.h @@ -21,7 +21,8 @@ * under the License. * */ - + +#include "qpid/CommonImportExport.h" #include <boost/noncopyable.hpp> #include <iostream> @@ -40,10 +41,10 @@ class Shlib { Shlib(const std::string& libname) { load(libname.c_str()); } /** Unload shared library. */ - void unload(); + QPID_COMMON_EXTERN void unload(); /** Look up symbol. */ - void* getSymbol(const char* symbol); + QPID_COMMON_EXTERN void* getSymbol(const char* symbol); /** Look up symbol in shared library, cast it to the desired * pointer type, void* by default. @@ -57,7 +58,7 @@ class Shlib { private: void* handle; - void load(const char* libname); + QPID_COMMON_EXTERN void load(const char* libname); }; /** A shared library handle that unloads the shlib in it's dtor */ @@ -66,7 +67,7 @@ class AutoShlib : public Shlib { /** Load shared library */ AutoShlib(const std::string& libname) : Shlib(libname) {} /** Calls unload() */ - ~AutoShlib() throw(); + QPID_COMMON_EXTERN ~AutoShlib() throw(); }; diff --git a/qpid/cpp/src/qpid/sys/Socket.h b/qpid/cpp/src/qpid/sys/Socket.h index ae48b8104d..e6555f5774 100644 --- a/qpid/cpp/src/qpid/sys/Socket.h +++ b/qpid/cpp/src/qpid/sys/Socket.h @@ -24,11 +24,9 @@ #include "IOHandle.h" #include "qpid/sys/IntegerTypes.h" - +#include "qpid/CommonImportExport.h" #include <string> -struct sockaddr; - namespace qpid { namespace sys { @@ -38,7 +36,7 @@ class Socket : public IOHandle { public: /** Create a socket wrapper for descriptor. */ - Socket(); + QPID_COMMON_EXTERN Socket(); /** Create an initialized TCP socket */ void createTcp() const; @@ -49,21 +47,21 @@ public: /** Set socket non blocking */ void setNonblocking() const; - void connect(const std::string& host, uint16_t port) const; + QPID_COMMON_EXTERN void connect(const std::string& host, uint16_t port) const; - void close() const; + QPID_COMMON_EXTERN void close() const; /** Bind to a port and start listening. *@param port 0 means choose an available port. *@param backlog maximum number of pending connections. *@return The bound port. */ - int listen(uint16_t port = 0, int backlog = 10) const; + QPID_COMMON_EXTERN int listen(uint16_t port = 0, int backlog = 10) const; /** Returns the "socket name" ie the address bound to * the near end of the socket */ - std::string getSockname() const; + QPID_COMMON_EXTERN std::string getSockname() const; /** Returns the "peer name" ie the address bound to * the remote end of the socket @@ -74,14 +72,14 @@ public: * Returns an address (host and port) for the remote end of the * socket */ - std::string getPeerAddress() const; + QPID_COMMON_EXTERN std::string getPeerAddress() const; /** * Returns an address (host and port) for the local end of the * socket */ std::string getLocalAddress() const; - uint16_t getLocalPort() const; + QPID_COMMON_EXTERN uint16_t getLocalPort() const; uint16_t getRemotePort() const; /** @@ -93,13 +91,13 @@ public: /** Accept a connection from a socket that is already listening * and has an incoming connection */ - Socket* accept(struct sockaddr *addr, socklen_t *addrlen) const; + QPID_COMMON_EXTERN Socket* accept() const; // TODO The following are raw operations, maybe they need better wrapping? - int read(void *buf, size_t count) const; - int write(const void *buf, size_t count) const; + QPID_COMMON_EXTERN int read(void *buf, size_t count) const; + QPID_COMMON_EXTERN int write(const void *buf, size_t count) const; - void setTcpNoDelay(bool nodelay) const; + QPID_COMMON_EXTERN void setTcpNoDelay(bool nodelay) const; private: Socket(IOHandlePrivate*); diff --git a/qpid/cpp/src/qpid/sys/StrError.h b/qpid/cpp/src/qpid/sys/StrError.h index 3843f2abe1..69cc7e714c 100644 --- a/qpid/cpp/src/qpid/sys/StrError.h +++ b/qpid/cpp/src/qpid/sys/StrError.h @@ -23,12 +23,13 @@ */ #include <string> +#include "qpid/CommonImportExport.h" namespace qpid { namespace sys { /** Get the error message for a system number err, e.g. errno. */ -std::string strError(int err); +QPID_COMMON_EXTERN std::string strError(int err); }} // namespace qpid diff --git a/qpid/cpp/src/qpid/sys/SystemInfo.h b/qpid/cpp/src/qpid/sys/SystemInfo.h index d43fe34b04..6e97022b36 100644 --- a/qpid/cpp/src/qpid/sys/SystemInfo.h +++ b/qpid/cpp/src/qpid/sys/SystemInfo.h @@ -23,6 +23,7 @@ #include "qpid/sys/IntegerTypes.h" #include "qpid/Address.h" +#include "qpid/CommonImportExport.h" namespace qpid { namespace sys { @@ -36,15 +37,15 @@ namespace SystemInfo { * Estimate available concurrency, e.g. number of CPU cores. * -1 means estimate not available on this platform. */ - long concurrency(); + QPID_COMMON_EXTERN long concurrency(); /** * Get the local host name and set it in the specified TcpAddress. * Returns false if it can't be obtained and sets errno to any error value. */ - bool getLocalHostname (TcpAddress &address); + QPID_COMMON_EXTERN bool getLocalHostname (TcpAddress &address); - void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList); + QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList); /** * Retrieve system identifiers and versions. This is information that can @@ -57,7 +58,7 @@ namespace SystemInfo { * @param version Receives the OS release version (kernel, build, sp, etc.) * @param machine Receives the hardware type. */ - void getSystemId (std::string &osName, + QPID_COMMON_EXTERN void getSystemId (std::string &osName, std::string &nodeName, std::string &release, std::string &version, @@ -66,12 +67,17 @@ namespace SystemInfo { /** * Get the process ID of the current process. */ - uint32_t getProcessId(); + QPID_COMMON_EXTERN uint32_t getProcessId(); /** * Get the process ID of the parent of the current process. */ - uint32_t getParentProcessId(); + QPID_COMMON_EXTERN uint32_t getParentProcessId(); + + /** + * Get the name of the current process (i.e. the name of the executable) + */ + QPID_COMMON_EXTERN std::string getProcessName(); }}} // namespace qpid::sys::SystemInfo diff --git a/qpid/cpp/src/qpid/sys/Thread.h b/qpid/cpp/src/qpid/sys/Thread.h index e2b904aa1a..b532d4d80a 100644 --- a/qpid/cpp/src/qpid/sys/Thread.h +++ b/qpid/cpp/src/qpid/sys/Thread.h @@ -22,11 +22,14 @@ * */ #include <boost/shared_ptr.hpp> +#include "qpid/CommonImportExport.h" #ifdef _WIN32 # define QPID_TSS __declspec(thread) #elif defined (__GNUC__) # define QPID_TSS __thread +#elif defined (__SUNPRO_CC) +# define QPID_TSS __thread #else # error "Dont know how to define QPID_TSS for this platform" #endif @@ -42,15 +45,15 @@ class Thread boost::shared_ptr<ThreadPrivate> impl; public: - Thread(); - explicit Thread(qpid::sys::Runnable*); - explicit Thread(qpid::sys::Runnable&); + QPID_COMMON_EXTERN Thread(); + QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable*); + QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable&); - void join(); + QPID_COMMON_EXTERN void join(); - unsigned long id(); + QPID_COMMON_EXTERN unsigned long id(); - static Thread current(); + QPID_COMMON_EXTERN static Thread current(); /** ID of current thread for logging. * Workaround for broken Thread::current() in APR diff --git a/qpid/cpp/src/qpid/sys/Time.h b/qpid/cpp/src/qpid/sys/Time.h index d39be95434..b7173406ca 100644 --- a/qpid/cpp/src/qpid/sys/Time.h +++ b/qpid/cpp/src/qpid/sys/Time.h @@ -33,6 +33,8 @@ # include "posix/Time.h" #endif +#include "qpid/CommonImportExport.h" + #include <limits> #include <iosfwd> @@ -86,23 +88,23 @@ class AbsTime { TimePrivate timepoint; public: - inline AbsTime() {} - AbsTime(const AbsTime& time0, const Duration& duration); + QPID_COMMON_EXTERN inline AbsTime() {} + QPID_COMMON_EXTERN AbsTime(const AbsTime& time0, const Duration& duration); // Default assignment operation fine // Default copy constructor fine - static AbsTime now(); - static AbsTime FarFuture(); + QPID_COMMON_EXTERN static AbsTime now(); + QPID_COMMON_EXTERN static AbsTime FarFuture(); const TimePrivate& getPrivate(void) const { return timepoint; } bool operator==(const AbsTime& t) const { return t.timepoint == timepoint; } template <class S> void serialize(S& s) { s(timepoint); } friend bool operator<(const AbsTime& a, const AbsTime& b); friend bool operator>(const AbsTime& a, const AbsTime& b); - friend std::ostream& operator << (std::ostream&, const AbsTime&); + QPID_COMMON_EXTERN friend std::ostream& operator << (std::ostream&, const AbsTime&); }; -std::ostream& operator << (std::ostream&, const AbsTime&); +QPID_COMMON_EXTERN std::ostream& operator << (std::ostream&, const AbsTime&); /** * @class Duration @@ -120,9 +122,9 @@ class Duration { friend class AbsTime; public: - inline Duration(int64_t time0); - explicit Duration(const AbsTime& time0); - explicit Duration(const AbsTime& start, const AbsTime& finish); + QPID_COMMON_EXTERN inline Duration(int64_t time0); + QPID_COMMON_EXTERN explicit Duration(const AbsTime& time0); + QPID_COMMON_EXTERN explicit Duration(const AbsTime& start, const AbsTime& finish); inline operator int64_t() const; }; @@ -158,10 +160,10 @@ const Duration TIME_INFINITE = std::numeric_limits<int64_t>::max(); const AbsTime FAR_FUTURE = AbsTime::FarFuture(); /** Portable sleep for a number of seconds */ -void sleep(int secs); +QPID_COMMON_EXTERN void sleep(int secs); /** Portable sleep for a number of microseconds */ -void usleep(uint64_t usecs); +QPID_COMMON_EXTERN void usleep(uint64_t usecs); }} diff --git a/qpid/cpp/src/qpid/sys/Timer.h b/qpid/cpp/src/qpid/sys/Timer.h index 2561e41034..dab2f55edb 100644 --- a/qpid/cpp/src/qpid/sys/Timer.h +++ b/qpid/cpp/src/qpid/sys/Timer.h @@ -25,7 +25,7 @@ #include "qpid/sys/Thread.h" #include "qpid/sys/Runnable.h" #include "qpid/RefCounted.h" - +#include "qpid/CommonImportExport.h" #include <memory> #include <queue> @@ -49,15 +49,15 @@ class TimerTask : public RefCounted { void fireTask(); public: - TimerTask(Duration period); - TimerTask(AbsTime fireTime); - virtual ~TimerTask(); + QPID_COMMON_EXTERN TimerTask(Duration period); + QPID_COMMON_EXTERN TimerTask(AbsTime fireTime); + QPID_COMMON_EXTERN virtual ~TimerTask(); - void setupNextFire(); - void restart(); - void delayTill(AbsTime fireTime); - void cancel(); - bool isCancelled() const; + QPID_COMMON_EXTERN void setupNextFire(); + QPID_COMMON_EXTERN void restart(); + QPID_COMMON_EXTERN void delayTill(AbsTime fireTime); + QPID_COMMON_EXTERN void cancel(); + QPID_COMMON_EXTERN bool isCancelled() const; protected: // Must be overridden with callback @@ -78,12 +78,12 @@ class Timer : private Runnable { void run(); public: - Timer(); - ~Timer(); + QPID_COMMON_EXTERN Timer(); + QPID_COMMON_EXTERN ~Timer(); - void add(boost::intrusive_ptr<TimerTask> task); - void start(); - void stop(); + QPID_COMMON_EXTERN void add(boost::intrusive_ptr<TimerTask> task); + QPID_COMMON_EXTERN void start(); + QPID_COMMON_EXTERN void stop(); }; diff --git a/qpid/cpp/src/qpid/sys/alloca.h b/qpid/cpp/src/qpid/sys/alloca.h new file mode 100644 index 0000000000..e989670e4f --- /dev/null +++ b/qpid/cpp/src/qpid/sys/alloca.h @@ -0,0 +1,39 @@ +#ifndef QPID_SYS_ALLOCA_H +#define QPID_SYS_ALLOCA_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. + * + */ + +#if (defined(_WINDOWS) || defined (WIN32)) && defined(_MSC_VER) +#include <malloc.h> +#ifdef alloc +# undef alloc +#endif +#define alloc _alloc +#ifdef alloca +# undef alloca +#endif +#define alloca _alloca +#endif +#if !defined _WINDOWS && !defined WIN32 +#include <alloca.h> +#endif + +#endif /*!QPID_SYS_ALLOCA_H*/ diff --git a/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp b/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp index 10705e12da..42b5d8b1aa 100644 --- a/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp +++ b/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp @@ -54,17 +54,20 @@ class PollerHandlePrivate { INACTIVE, HUNGUP, MONITORED_HUNGUP, + INTERRUPTED, DELETED }; int fd; ::__uint32_t events; + PollerHandle* pollerHandle; FDStat stat; Mutex lock; - PollerHandlePrivate(int f) : + PollerHandlePrivate(int f, PollerHandle* p) : fd(f), events(0), + pollerHandle(p), stat(ABSENT) { } @@ -101,6 +104,14 @@ class PollerHandlePrivate { stat = HUNGUP; } + bool isInterrupted() const { + return stat == INTERRUPTED; + } + + void setInterrupted() { + stat = INTERRUPTED; + } + bool isDeleted() const { return stat == DELETED; } @@ -111,7 +122,7 @@ class PollerHandlePrivate { }; PollerHandle::PollerHandle(const IOHandle& h) : - impl(new PollerHandlePrivate(toFd(h.impl))) + impl(new PollerHandlePrivate(toFd(h.impl), this)) {} PollerHandle::~PollerHandle() { @@ -120,6 +131,10 @@ PollerHandle::~PollerHandle() { if (impl->isDeleted()) { return; } + if (impl->isInterrupted()) { + impl->setDeleted(); + return; + } if (impl->isActive()) { impl->setDeleted(); } @@ -243,23 +258,21 @@ class PollerPrivate { ::close(epollFd); } - void interrupt(bool all=false) { + void interrupt() { ::epoll_event epe; - if (all) { - // Not EPOLLONESHOT, so we eventually get all threads - epe.events = ::EPOLLIN; - epe.data.u64 = 0; // Keep valgrind happy - } else { - // Use EPOLLONESHOT so we only wake a single thread - epe.events = ::EPOLLIN | ::EPOLLONESHOT; - epe.data.u64 = 0; // Keep valgrind happy - epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle); - } + // Use EPOLLONESHOT so we only wake a single thread + epe.events = ::EPOLLIN | ::EPOLLONESHOT; + epe.data.u64 = 0; // Keep valgrind happy + epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle); QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe)); } void interruptAll() { - interrupt(true); + ::epoll_event epe; + // Not EPOLLONESHOT, so we eventually get all threads + epe.events = ::EPOLLIN; + epe.data.u64 = 0; // Keep valgrind happy + QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe)); } }; @@ -281,7 +294,7 @@ void Poller::addFd(PollerHandle& handle, Direction dir) { epe.events = eh.events | PollerPrivate::directionToEpollEvent(dir); } epe.data.u64 = 0; // Keep valgrind happy - epe.data.ptr = &handle; + epe.data.ptr = &eh; QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, op, eh.fd, &epe)); @@ -312,7 +325,7 @@ void Poller::modFd(PollerHandle& handle, Direction dir) { ::epoll_event epe; epe.events = PollerPrivate::directionToEpollEvent(dir) | ::EPOLLONESHOT; epe.data.u64 = 0; // Keep valgrind happy - epe.data.ptr = &handle; + epe.data.ptr = &eh; QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe)); @@ -329,7 +342,7 @@ void Poller::rearmFd(PollerHandle& handle) { ::epoll_event epe; epe.events = eh.events; epe.data.u64 = 0; // Keep valgrind happy - epe.data.ptr = &handle; + epe.data.ptr = &eh; QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe)); @@ -355,15 +368,14 @@ bool Poller::interrupt(PollerHandle& handle) { { PollerHandlePrivate& eh = *handle.impl; ScopedLock<Mutex> l(eh.lock); - if (eh.isInactive()) { + if (!eh.isActive()) { return false; } ::epoll_event epe; epe.events = 0; epe.data.u64 = 0; // Keep valgrind happy - epe.data.ptr = &eh; QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe)); - eh.setInactive(); + eh.setInterrupted(); } PollerPrivate::InterruptHandle& ih = impl->interruptHandle; @@ -422,37 +434,54 @@ Poller::Event Poller::wait(Duration timeout) { #else int rc = ::epoll_pwait(impl->epollFd, &epe, 1, timeoutMs, &impl->sigMask); #endif - // Check for shutdown - if (impl->isShutdown) { - PollerHandleDeletionManager.markAllUnusedInThisThread(); - return Event(0, SHUTDOWN); - } if (rc ==-1 && errno != EINTR) { QPID_POSIX_CHECK(rc); } else if (rc > 0) { assert(rc == 1); - PollerHandle* handle = static_cast<PollerHandle*>(epe.data.ptr); + void* dataPtr = epe.data.ptr; + + // Check if this is an interrupt + PollerPrivate::InterruptHandle& interruptHandle = impl->interruptHandle; + if (dataPtr == &interruptHandle) { + PollerHandle* wrappedHandle = 0; + { + ScopedLock<Mutex> l(interruptHandle.impl->lock); + if (interruptHandle.impl->isActive()) { + wrappedHandle = interruptHandle.getHandle(); + // If there is an interrupt queued behind this one we need to arm it + // We do it this way so that another thread can pick it up + if (interruptHandle.queuedHandles()) { + impl->interrupt(); + interruptHandle.impl->setActive(); + } else { + interruptHandle.impl->setInactive(); + } + } + } + if (wrappedHandle) { + ScopedLock<Mutex> l(wrappedHandle->impl->lock); + if (!wrappedHandle->impl->isDeleted()) { + wrappedHandle->impl->setInactive(); + return Event(wrappedHandle, INTERRUPTED); + } + PollerHandleDeletionManager.markForDeletion(wrappedHandle->impl); + } + continue; + } + + // Check for shutdown + if (impl->isShutdown) { + PollerHandleDeletionManager.markAllUnusedInThisThread(); + return Event(0, SHUTDOWN); + } - PollerHandlePrivate& eh = *handle->impl; + PollerHandlePrivate& eh = *static_cast<PollerHandlePrivate*>(dataPtr); ScopedLock<Mutex> l(eh.lock); // the handle could have gone inactive since we left the epoll_wait if (eh.isActive()) { - - // Check if this is an interrupt - if (handle == &impl->interruptHandle) { - PollerHandle* wrappedHandle = impl->interruptHandle.getHandle(); - // If there is an interrupt queued behind this one we need to arm it - // We do it this way so that another thread can pick it up - if (impl->interruptHandle.queuedHandles()) { - impl->interrupt(); - eh.setActive(); - } else { - eh.setInactive(); - } - return Event(wrappedHandle, INTERRUPTED); - } + PollerHandle* handle = eh.pollerHandle; // If the connection has been hungup we could still be readable // (just not writable), allow us to readable until we get here again diff --git a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp index a356a72650..a914dc817a 100644 --- a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp +++ b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp @@ -123,7 +123,7 @@ void AsynchAcceptorPrivate::readable(DispatchHandle& h) { // TODO: Currently we ignore the peers address, perhaps we should // log it or use it for connection acceptance. try { - s = socket.accept(0, 0); + s = socket.accept(); if (s) { acceptedCallback(*s); } else { @@ -474,7 +474,7 @@ void AsynchIO::readable(DispatchHandle& h) { break; } else { // Report error then just treat as a socket disconnect - QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(rc) << "(" << rc << ")" ); + QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(errno) << "(" << errno << ")" ); eofCallback(*this); h.unwatchRead(); break; diff --git a/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp b/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp index 0c55fd3c0d..0991e5fd76 100644 --- a/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp +++ b/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp @@ -22,17 +22,46 @@ * */ -#include "PollableCondition.h" +#include "qpid/sys/PollableCondition.h" +#include "qpid/sys/DispatchHandle.h" +#include "qpid/sys/IOHandle.h" #include "qpid/sys/posix/PrivatePosix.h" #include "qpid/Exception.h" +#include <boost/bind.hpp> + #include <unistd.h> #include <fcntl.h> namespace qpid { namespace sys { -PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) { +class PollableConditionPrivate : public sys::IOHandle { + friend class PollableCondition; + +private: + PollableConditionPrivate(const sys::PollableCondition::Callback& cb, + sys::PollableCondition& parent, + const boost::shared_ptr<sys::Poller>& poller); + ~PollableConditionPrivate(); + + void dispatch(sys::DispatchHandle& h); + void rewatch(); + void unwatch(); + +private: + PollableCondition::Callback cb; + PollableCondition& parent; + boost::shared_ptr<sys::Poller> poller; + int writeFd; + std::auto_ptr<DispatchHandleRef> handle; +}; + +PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb, + sys::PollableCondition& parent, + const boost::shared_ptr<sys::Poller>& poller) + : IOHandle(new sys::IOHandlePrivate), cb(cb), parent(parent) +{ int fds[2]; if (::pipe(fds) == -1) throw ErrnoException(QPID_MSG("Can't create PollableCondition")); @@ -42,22 +71,71 @@ PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) { throw ErrnoException(QPID_MSG("Can't create PollableCondition")); if (::fcntl(writeFd, F_SETFL, O_NONBLOCK) == -1) throw ErrnoException(QPID_MSG("Can't create PollableCondition")); + handle.reset (new DispatchHandleRef(*this, + boost::bind(&sys::PollableConditionPrivate::dispatch, this, _1), + 0, 0)); + handle->startWatch(poller); + handle->unwatch(); +} + +PollableConditionPrivate::~PollableConditionPrivate() +{ + handle->stopWatch(); + close(writeFd); +} + +void PollableConditionPrivate::dispatch(sys::DispatchHandle& /*h*/) +{ + cb(parent); +} + +void PollableConditionPrivate::rewatch() +{ + handle->rewatch(); +} + +void PollableConditionPrivate::unwatch() +{ + handle->unwatch(); +} + + /* PollableCondition */ + +PollableCondition::PollableCondition(const Callback& cb, + const boost::shared_ptr<sys::Poller>& poller) + : impl(new PollableConditionPrivate(cb, *this, poller)) +{ +} + +PollableCondition::~PollableCondition() +{ + delete impl; +} + +void PollableCondition::set() { + static const char dummy=0; + ssize_t n = ::write(impl->writeFd, &dummy, 1); + if (n == -1 && errno != EAGAIN) + throw ErrnoException("Error setting PollableCondition"); } bool PollableCondition::clear() { char buf[256]; ssize_t n; bool wasSet = false; - while ((n = ::read(impl->fd, buf, sizeof(buf))) > 0) + while ((n = ::read(impl->impl->fd, buf, sizeof(buf))) > 0) wasSet = true; - if (n == -1 && errno != EAGAIN) throw ErrnoException(QPID_MSG("Error clearing PollableCondition")); + if (n == -1 && errno != EAGAIN) + throw ErrnoException(QPID_MSG("Error clearing PollableCondition")); return wasSet; } -void PollableCondition::set() { - static const char dummy=0; - ssize_t n = ::write(writeFd, &dummy, 1); - if (n == -1 && errno != EAGAIN) throw ErrnoException("Error setting PollableCondition"); +void PollableCondition::disarm() { + impl->unwatch(); +} + +void PollableCondition::rearm() { + impl->rewatch(); } @@ -71,22 +149,35 @@ void PollableCondition::set() { namespace qpid { namespace sys { -PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) { +PollableConditionPrivate::PollableConditionPrivate(const PollableCondition::Callback& cb, + sys::PollableCondition& parent, + const boost::shared_ptr<sys::Poller>& poller) + : cb(cb), parent(parent), poller(poller), + IOHandle(new sys::IOHandlePrivate) { impl->fd = ::eventfd(0, 0); if (impl->fd < 0) throw ErrnoException("conditionfd() failed"); } +void PollableCondition::set() { + static const uint64_t value=1; + ssize_t n = ::write(impl->impl->fd, + reinterpret_cast<const void*>(&value), 8); + if (n != 8) throw ErrnoException("write failed on conditionfd"); +} + bool PollableCondition::clear() { char buf[8]; - ssize_t n = ::read(impl->fd, buf, 8); + ssize_t n = ::read(impl->impl->fd, buf, 8); if (n != 8) throw ErrnoException("read failed on conditionfd"); return *reinterpret_cast<uint64_t*>(buf); } -void PollableCondition::set() { - static const uint64_t value=1; - ssize_t n = ::write(impl->fd, reinterpret_cast<const void*>(&value), 8); - if (n != 8) throw ErrnoException("write failed on conditionfd"); +void PollableCondition::disarm() { + // ???? +} + +void PollableCondition::rearm() { + // ???? } #endif diff --git a/qpid/cpp/src/qpid/sys/posix/Socket.cpp b/qpid/cpp/src/qpid/sys/posix/Socket.cpp index 415d5293ef..ab0c28c48c 100644 --- a/qpid/cpp/src/qpid/sys/posix/Socket.cpp +++ b/qpid/cpp/src/qpid/sys/posix/Socket.cpp @@ -108,7 +108,7 @@ void Socket::createTcp() const { int& socket = impl->fd; if (socket != -1) Socket::close(); - int s = ::socket (PF_INET, SOCK_STREAM, 0); + int s = ::socket (AF_INET, SOCK_STREAM, 0); if (s < 0) throw QPID_POSIX_ERROR(errno); socket = s; } @@ -138,25 +138,30 @@ const char* h_errstr(int e) { } } -void Socket::connect(const std::string& host, uint16_t port) const +void Socket::connect(const std::string& host, uint16_t p) const { - std::stringstream namestream; - namestream << host << ":" << port; - connectname = namestream.str(); + std::stringstream portstream; + portstream << p; + std::string port = portstream.str(); + connectname = host + ":" + port; const int& socket = impl->fd; - struct sockaddr_in name; - name.sin_family = AF_INET; - name.sin_port = htons(port); - // TODO: Be good to make this work for IPv6 as well as IPv4 - // Use more modern lookup functions - struct hostent* hp = gethostbyname ( host.c_str() ); - if (hp == 0) - throw Exception(QPID_MSG("Cannot resolve " << host << ": " << h_errstr(h_errno))); - ::memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); - if ((::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) && - (errno != EINPROGRESS)) + + ::addrinfo *res; + ::addrinfo hints; + ::memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; // In order to allow AF_INET6 we'd have to change createTcp() as well + hints.ai_socktype = SOCK_STREAM; + int n = ::getaddrinfo(host.c_str(), port.c_str(), &hints, &res); + if (n != 0) + throw Exception(QPID_MSG("Cannot resolve " << host << ": " << ::gai_strerror(n))); + // TODO the correct thing to do here is loop on failure until you've used all the returned addresses + if ((::connect(socket, res->ai_addr, res->ai_addrlen) < 0) && + (errno != EINPROGRESS)) { + ::freeaddrinfo(res); throw qpid::Exception(QPID_MSG(strError(errno) << ": " << host << ":" << port)); + } + ::freeaddrinfo(res); } void @@ -189,9 +194,9 @@ int Socket::listen(uint16_t port, int backlog) const return ntohs(name.sin_port); } -Socket* Socket::accept(struct sockaddr *addr, socklen_t *addrlen) const +Socket* Socket::accept() const { - int afd = ::accept(impl->fd, addr, addrlen); + int afd = ::accept(impl->fd, 0, 0); if ( afd >= 0) return new Socket(new IOHandlePrivate(afd)); else if (errno == EAGAIN) @@ -238,7 +243,7 @@ uint16_t Socket::getLocalPort() const uint16_t Socket::getRemotePort() const { - return atoi(getService(impl->fd, true).c_str()); + return std::atoi(getService(impl->fd, true).c_str()); } int Socket::getError() const diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp index 938d4861c4..5d9eda605d 100755 --- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp +++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp @@ -27,6 +27,9 @@ #include <arpa/inet.h> #include <stdio.h> #include <unistd.h> +#include <iostream> +#include <fstream> +#include <sstream> #ifndef HOST_NAME_MAX # define HOST_NAME_MAX 256 @@ -104,6 +107,27 @@ uint32_t SystemInfo::getParentProcessId() return (uint32_t) ::getppid(); } +string SystemInfo::getProcessName() +{ + uint32_t pid = getProcessId(); + string value; + + stringstream pathStream; + pathStream << "/proc/" << pid << "/status"; + ifstream input(pathStream.str().c_str()); + if (input.good()) { + while (!input.eof()) { + string key; + input >> key; + if (key == "Name:") { + input >> value; + break; + } + } + input.close(); + } + return value; +} }} // namespace qpid::sys diff --git a/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp b/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp index 783f84576b..f12012cbb0 100644 --- a/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp +++ b/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp @@ -30,9 +30,11 @@ #include <port.h> #include <poll.h> #include <errno.h> +#include <pthread.h> +#include <signal.h> #include <assert.h> -#include <vector> +#include <queue> #include <exception> @@ -43,11 +45,11 @@ namespace qpid { namespace sys { // Deletion manager to handle deferring deletion of PollerHandles to when they definitely aren't being used -DeletionManager<PollerHandle> PollerHandleDeletionManager; +DeletionManager<PollerHandlePrivate> PollerHandleDeletionManager; // Instantiate (and define) class static for DeletionManager template <> -DeletionManager<PollerHandle>::AllThreadsStatuses DeletionManager<PollerHandle>::allThreadsStatuses(0); +DeletionManager<PollerHandlePrivate>::AllThreadsStatuses DeletionManager<PollerHandlePrivate>::allThreadsStatuses(0); class PollerHandlePrivate { friend class Poller; @@ -58,7 +60,8 @@ class PollerHandlePrivate { MONITORED, INACTIVE, HUNGUP, - MONITORED_HUNGUP + MONITORED_HUNGUP, + DELETED }; int fd; @@ -104,6 +107,14 @@ class PollerHandlePrivate { assert(stat == MONITORED); stat = HUNGUP; } + + bool isDeleted() const { + return stat == DELETED; + } + + void setDeleted() { + stat = DELETED; + } }; PollerHandle::PollerHandle(const IOHandle& h) : @@ -111,11 +122,16 @@ PollerHandle::PollerHandle(const IOHandle& h) : {} PollerHandle::~PollerHandle() { - delete impl; -} - -void PollerHandle::deferDelete() { - PollerHandleDeletionManager.markForDeletion(this); + { + ScopedLock<Mutex> l(impl->lock); + if (impl->isDeleted()) { + return; + } + if (impl->isActive()) { + impl->setDeleted(); + } + } + PollerHandleDeletionManager.markForDeletion(impl); } /** @@ -125,35 +141,82 @@ void PollerHandle::deferDelete() { class PollerPrivate { friend class Poller; - const int portId; + class InterruptHandle: public PollerHandle { + std::queue<PollerHandle*> handles; + + void processEvent(Poller::EventType) { + PollerHandle* handle = handles.front(); + handles.pop(); + assert(handle); + + //Synthesise event + Poller::Event event(handle, Poller::INTERRUPTED); + + //Process synthesised event + event.process(); + } + public: + InterruptHandle() : PollerHandle(DummyIOHandle) {} + + void addHandle(PollerHandle& h) { + handles.push(&h); + } + + PollerHandle *getHandle() { + PollerHandle* handle = handles.front(); + handles.pop(); + return handle; + } + + bool queuedHandles() { + return handles.size() > 0; + } + }; + + const int portId; + bool isShutdown; + InterruptHandle interruptHandle; + static uint32_t directionToPollEvent(Poller::Direction dir) { switch (dir) { - case Poller::INPUT: return POLLIN; - case Poller::OUTPUT: return POLLOUT; - case Poller::INOUT: return POLLIN | POLLOUT; - default: return 0; + case Poller::INPUT: return POLLIN; + case Poller::OUTPUT: return POLLOUT; + case Poller::INOUT: return POLLIN | POLLOUT; + default: return 0; } } static Poller::EventType pollToDirection(uint32_t events) { uint32_t e = events & (POLLIN | POLLOUT); switch (e) { - case POLLIN: return Poller::READABLE; - case POLLOUT: return Poller::WRITABLE; - case POLLIN | POLLOUT: return Poller::READ_WRITABLE; - default: - return (events & (POLLHUP | POLLERR)) ? - Poller::DISCONNECTED : Poller::INVALID; + case POLLIN: return Poller::READABLE; + case POLLOUT: return Poller::WRITABLE; + case POLLIN | POLLOUT: return Poller::READ_WRITABLE; + default: + return (events & (POLLHUP | POLLERR)) ? + Poller::DISCONNECTED : Poller::INVALID; } } - + PollerPrivate() : - portId(::port_create()) { + portId(::port_create()), + isShutdown(false) { + QPID_POSIX_CHECK(portId); + QPID_LOG(trace, "port_create returned port Id: " << portId); } ~PollerPrivate() { } + + void interrupt() { + //Send an Alarm to the port + //We need to send a nonzero event mask, using POLLHUP, + //nevertheless the wait method will only look for a PORT_ALERT_SET + QPID_LOG(trace, "Sending a port_alert to " << portId); + QPID_POSIX_CHECK(::port_alert(portId, PORT_ALERT_SET, POLLHUP, + &static_cast<PollerHandle&>(interruptHandle))); + } }; void Poller::addFd(PollerHandle& handle, Direction dir) { @@ -177,7 +240,6 @@ void Poller::addFd(PollerHandle& handle, Direction dir) { QPID_LOG(trace, "Poller::addFd(handle=" << &handle << "[" << typeid(&handle).name() << "], fd=" << eh.fd << ")"); - //assert(dynamic_cast<DispatchHandle*>(&handle)); } void Poller::delFd(PollerHandle& handle) { @@ -223,17 +285,56 @@ void Poller::rearmFd(PollerHandle& handle) { } void Poller::shutdown() { - //Send an Alarm to the port - //We need to send a nonzero event mask, using POLLHUP, but - //The wait method will only look for a PORT_ALERT_SET - QPID_POSIX_CHECK(::port_alert(impl->portId, PORT_ALERT_SET, POLLHUP, NULL)); - QPID_LOG(trace, "Poller::shutdown"); + //Allow sloppy code to shut us down more than once + if (impl->isShutdown) + return; + + impl->isShutdown = true; + impl->interrupt(); +} + +bool Poller::interrupt(PollerHandle& handle) { + PollerPrivate::InterruptHandle& ih = impl->interruptHandle; + PollerHandlePrivate& eh = *static_cast<PollerHandle&>(ih).impl; + ScopedLock<Mutex> l(eh.lock); + ih.addHandle(handle); + impl->interrupt(); + eh.setActive(); + return true; +} + +void Poller::run() { + // Make sure we can't be interrupted by signals at a bad time + ::sigset_t ss; + ::sigfillset(&ss); + ::pthread_sigmask(SIG_SETMASK, &ss, 0); + + do { + Event event = wait(); + + // If can read/write then dispatch appropriate callbacks + if (event.handle) { + event.process(); + } else { + // Handle shutdown + switch (event.type) { + case SHUTDOWN: + return; + default: + // This should be impossible + assert(false); + } + } + } while (true); } Poller::Event Poller::wait(Duration timeout) { timespec_t tout; timespec_t* ptout = NULL; port_event_t pe; + + AbsTime targetTimeout = (timeout == TIME_INFINITE) ? FAR_FUTURE : + AbsTime(now(), timeout); if (timeout != TIME_INFINITE) { tout.tv_sec = 0; @@ -243,12 +344,21 @@ Poller::Event Poller::wait(Duration timeout) { do { PollerHandleDeletionManager.markAllUnusedInThisThread(); - QPID_LOG(trace, "About to enter port_get. Thread " - << pthread_self() + QPID_LOG(trace, "About to enter port_get on " << impl->portId + << ". Thread " << pthread_self() << ", timeout=" << timeout); - + + int rc = ::port_get(impl->portId, &pe, ptout); + QPID_LOG(trace, "port_get on " << impl->portId + << " returned " << rc); + + if (impl->isShutdown) { + PollerHandleDeletionManager.markAllUnusedInThisThread(); + return Event(0, SHUTDOWN); + } + if (rc < 0) { switch (errno) { case EINTR: @@ -259,33 +369,61 @@ Poller::Event Poller::wait(Duration timeout) { QPID_POSIX_CHECK(rc); } } else { - //We use alert mode to notify the shutdown of the Poller - if (pe.portev_source == PORT_SOURCE_ALERT) { - return Event(0, SHUTDOWN); - } - if (pe.portev_source == PORT_SOURCE_FD) { - PollerHandle *handle = static_cast<PollerHandle*>(pe.portev_user); - PollerHandlePrivate& eh = *handle->impl; - ScopedLock<Mutex> l(eh.lock); - QPID_LOG(trace, "About to send handle: " << handle); + PollerHandle* handle = static_cast<PollerHandle*>(pe.portev_user); + PollerHandlePrivate& eh = *handle->impl; + ScopedLock<Mutex> l(eh.lock); + + if (eh.isActive()) { + QPID_LOG(trace, "Handle is active"); + //We use alert mode to notify interrupts + if (pe.portev_source == PORT_SOURCE_ALERT && + handle == &impl->interruptHandle) { + QPID_LOG(trace, "Interrupt notified"); + + PollerHandle* wrappedHandle = impl->interruptHandle.getHandle(); + + if (impl->interruptHandle.queuedHandles()) { + impl->interrupt(); + eh.setActive(); + } else { + eh.setInactive(); + } + return Event(wrappedHandle, INTERRUPTED); + } - if (eh.isActive()) { - if (pe.portev_events & POLLHUP) { - if (eh.isHungup()) { - return Event(handle, DISCONNECTED); + if (pe.portev_source == PORT_SOURCE_FD) { + QPID_LOG(trace, "About to send handle: " << handle); + if (pe.portev_events & POLLHUP) { + if (eh.isHungup()) { + return Event(handle, DISCONNECTED); + } + eh.setHungup(); + } else { + eh.setInactive(); } - eh.setHungup(); - } else { - eh.setInactive(); - } - QPID_LOG(trace, "Sending event (thread: " - << pthread_self() << ") for handle " << handle - << ", direction= " - << PollerPrivate::pollToDirection(pe.portev_events)); - return Event(handle, PollerPrivate::pollToDirection(pe.portev_events)); + QPID_LOG(trace, "Sending event (thread: " + << pthread_self() << ") for handle " << handle + << ", direction= " + << PollerPrivate::pollToDirection(pe.portev_events)); + return Event(handle, PollerPrivate::pollToDirection(pe.portev_events)); + } + } else if (eh.isDeleted()) { + //Remove the handle from the poller + int rc = ::port_dissociate(impl->portId, PORT_SOURCE_FD, + (uintptr_t) eh.fd); + if (rc == -1 && errno != EBADFD) { + QPID_POSIX_CHECK(rc); } } } + + if (timeout == TIME_INFINITE) { + continue; + } + if (rc == 0 && now() > targetTimeout) { + PollerHandleDeletionManager.markAllUnusedInThisThread(); + return Event(0, TIMEOUT); + } } while (true); } diff --git a/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp new file mode 100755 index 0000000000..0075a89021 --- /dev/null +++ b/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp @@ -0,0 +1,123 @@ +/* + * 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/SystemInfo.h" + +#define BSD_COMP +#include <sys/ioctl.h> +#include <netdb.h> +#undef BDS_COMP + + +#include <unistd.h> +#include <net/if.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <errno.h> +#include <limits.h> +#include <procfs.h> +#include <fcntl.h> +#include <sys/types.h> + +using namespace std; + +namespace qpid { +namespace sys { + +long SystemInfo::concurrency() { + return sysconf(_SC_NPROCESSORS_ONLN); +} + +bool SystemInfo::getLocalHostname(TcpAddress &address) { + char name[MAXHOSTNAMELEN]; + if (::gethostname(name, sizeof(name)) != 0) + return false; + address.host = name; + return true; +} + +static const string LOCALHOST("127.0.0.1"); + +void SystemInfo::getLocalIpAddresses(uint16_t port, + std::vector<Address> &addrList) { + int s = socket(PF_INET, SOCK_STREAM, 0); + for (int i=1;;i++) { + struct lifreq ifr; + ifr.lifr_index = i; + if (::ioctl(s, SIOCGIFADDR, &ifr) < 0) { + break; + } + struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.lifr_addr; + std::string addr(inet_ntoa(sin->sin_addr)); + if (addr != LOCALHOST) + addrList.push_back(TcpAddress(addr, port)); + } + if (addrList.empty()) { + addrList.push_back(TcpAddress(LOCALHOST, port)); + } + close (s); +} + +void SystemInfo::getSystemId(std::string &osName, + std::string &nodeName, + std::string &release, + std::string &version, + std::string &machine) { + struct utsname _uname; + if (uname (&_uname) == 0) { + osName = _uname.sysname; + nodeName = _uname.nodename; + release = _uname.release; + version = _uname.version; + machine = _uname.machine; + } +} + +uint32_t SystemInfo::getProcessId() +{ + return (uint32_t) ::getpid(); +} + +uint32_t SystemInfo::getParentProcessId() +{ + return (uint32_t) ::getppid(); +} + +string SystemInfo::getProcessName() +{ + psinfo processInfo; + char procfile[PATH_MAX]; + int fd; + string value; + + snprintf(procfile, PATH_MAX, "/proc/%d/psinfo", getProcessId()); + if ((fd = open(procfile, O_RDONLY)) >= 0) { + if (read(fd, (void *) &processInfo, sizeof(processInfo)) == sizeof(processInfo)) { + value = processInfo.pr_fname; + } + } + return value; +} + +}} // namespace qpid::sys diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp index 9be75af47d..624683ae7d 100644 --- a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp +++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp @@ -90,7 +90,7 @@ void SslAcceptor::readable(DispatchHandle& h) { // TODO: Currently we ignore the peers address, perhaps we should // log it or use it for connection acceptance. try { - s = socket.accept(0, 0); + s = socket.accept(); if (s) { acceptedCallback(*s); } else { diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp index 597fbe57db..dc816b403b 100644 --- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp +++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp @@ -201,9 +201,9 @@ int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, b return ntohs(name.sin_port); } -SslSocket* SslSocket::accept(struct sockaddr *addr, socklen_t *addrlen) const +SslSocket* SslSocket::accept() const { - int afd = ::accept(impl->fd, addr, addrlen); + int afd = ::accept(impl->fd, 0, 0); if ( afd >= 0) { return new SslSocket(new IOHandlePrivate(afd), prototype); } else if (errno == EAGAIN) { diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h index a82e9133e8..7434667b78 100644 --- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h +++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h @@ -64,7 +64,7 @@ public: * Accept a connection from a socket that is already listening * and has an incoming connection */ - SslSocket* accept(struct sockaddr *addr, socklen_t *addrlen) const; + SslSocket* accept() const; // TODO The following are raw operations, maybe they need better wrapping? int read(void *buf, size_t count) const; diff --git a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp index 37d87947a2..0a3c36452c 100644 --- a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp +++ b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp @@ -690,10 +690,9 @@ void AsynchIO::writeComplete(AsynchWriteResult *result) { } } - // If there are no writes outstanding, the priority is to write any - // remaining buffers first (either queued or via idle), then close the - // socket if that's queued. - // opsInProgress handled in completion() + // If there are no writes outstanding, check for more writes to initiate + // (either queued or via idle). The opsInProgress count is handled in + // completion() if (!writeInProgress) { bool writing = false; { @@ -706,11 +705,8 @@ void AsynchIO::writeComplete(AsynchWriteResult *result) { writing = true; } } - if (!writing) { - if (queuedClose) - close(); - else - notifyIdle(); + if (!writing && !queuedClose) { + notifyIdle(); } } return; @@ -757,9 +753,11 @@ void AsynchIO::completion(AsynchIoResult *result) { } working = false; } - // Lock released; ok to delete if all is done. - if (opsInProgress == 0 && queuedDelete) - delete this; + // Lock released; ok to close if ops are done and close requested. + // Layer above will call back to queueForDeletion() + if (opsInProgress == 0 && queuedClose) { + close(); + } } } // namespace windows diff --git a/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h b/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h index 80168fab88..47b1d16a76 100755 --- a/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h +++ b/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h @@ -32,8 +32,6 @@ typedef __int64 int64_t; // Visual Studio doesn't define other common types, so set them up here too. typedef int pid_t; -typedef int socklen_t; -typedef unsigned int size_t; typedef int ssize_t; typedef unsigned int uint; diff --git a/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp b/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp new file mode 100644 index 0000000000..ed0f7c3917 --- /dev/null +++ b/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp @@ -0,0 +1,125 @@ +#ifndef QPID_SYS_WINDOWS_POLLABLECONDITION_CPP +#define QPID_SYS_WINDOWS_POLLABLECONDITION_CPP + +/* + * + * 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/PollableCondition.h" +#include "qpid/sys/IOHandle.h" +#include "AsynchIoResult.h" +#include "IoHandlePrivate.h" + +#include <boost/bind.hpp> +#include <windows.h> + +namespace qpid { +namespace sys { + +// PollableConditionPrivate will reuse the IocpPoller's ability to queue +// a completion to the IOCP and have it dispatched to the completer callback +// noted in the IOHandlePrivate when the request is queued. The +// AsynchCallbackRequest object is not really used - we already have the +// desired callback for the user of PollableCondition. +class PollableConditionPrivate : private IOHandle { + friend class PollableCondition; + +private: + PollableConditionPrivate(const sys::PollableCondition::Callback& cb, + sys::PollableCondition& parent, + const boost::shared_ptr<sys::Poller>& poller); + ~PollableConditionPrivate(); + + void poke(); + void dispatch(AsynchIoResult *result); + +private: + PollableCondition::Callback cb; + PollableCondition& parent; + boost::shared_ptr<sys::Poller> poller; + LONG isSet; + LONG armed; +}; + +PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb, + sys::PollableCondition& parent, + const boost::shared_ptr<sys::Poller>& poller) + : IOHandle(new sys::IOHandlePrivate(INVALID_SOCKET, + boost::bind(&PollableConditionPrivate::dispatch, this, _1))), + cb(cb), parent(parent), poller(poller), isSet(0), armed(0) +{ +} + +PollableConditionPrivate::~PollableConditionPrivate() +{ +} + +void PollableConditionPrivate::poke() +{ + if (!armed) + return; + + // addFd will queue a completion for the IOCP; when it's handled, a + // poller thread will call back to dispatch() below. + PollerHandle ph(*this); + poller->addFd(ph, Poller::INPUT); +} + +void PollableConditionPrivate::dispatch(AsynchIoResult *result) +{ + delete result; // Poller::addFd() allocates this + cb(parent); +} + + /* PollableCondition */ + +PollableCondition::PollableCondition(const Callback& cb, + const boost::shared_ptr<sys::Poller>& poller) + : impl(new PollableConditionPrivate(cb, *this, poller)) +{ +} + +PollableCondition::~PollableCondition() +{ + delete impl; +} + +void PollableCondition::set() { + // Add one to the set count and poke it to provoke a callback + ::InterlockedIncrement(&impl->isSet); + impl->poke(); +} + +bool PollableCondition::clear() { + return (0 != ::InterlockedExchange(&impl->isSet, 0)); +} + +void PollableCondition::disarm() { + ::InterlockedExchange(&impl->armed, 0); +} + +void PollableCondition::rearm() { + if (0 == ::InterlockedExchange(&impl->armed, 1) && impl->isSet) + impl->poke(); +} + +}} // namespace qpid::sys + +#endif /*!QPID_SYS_WINDOWS_POLLABLECONDITION_CPP*/ diff --git a/qpid/cpp/src/qpid/sys/windows/Socket.cpp b/qpid/cpp/src/qpid/sys/windows/Socket.cpp index a9959bf43e..93059d03ef 100755 --- a/qpid/cpp/src/qpid/sys/windows/Socket.cpp +++ b/qpid/cpp/src/qpid/sys/windows/Socket.cpp @@ -262,9 +262,9 @@ int Socket::listen(uint16_t port, int backlog) const return ntohs(name.sin_port); } -Socket* Socket::accept(struct sockaddr *addr, socklen_t *addrlen) const +Socket* Socket::accept() const { - SOCKET afd = ::accept(impl->fd, addr, addrlen); + SOCKET afd = ::accept(impl->fd, 0, 0); if (afd != INVALID_SOCKET) return new Socket(new IOHandlePrivate(afd)); else if (WSAGetLastError() == EAGAIN) diff --git a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp index b887cac58b..3e2fcb1517 100755 --- a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp +++ b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp @@ -29,6 +29,7 @@ #include <winsock2.h> #include <ws2tcpip.h> #include <windows.h> +#include <tlhelp32.h> #ifndef HOST_NAME_MAX # define HOST_NAME_MAX 256 @@ -157,4 +158,41 @@ void SystemInfo::getSystemId (std::string &osName, } } +uint32_t SystemInfo::getProcessId() +{ + return static_cast<uint32_t>(::GetCurrentProcessId()); +} + +uint32_t SystemInfo::getParentProcessId() +{ + // Only want info for the current process, so ask for something specific. + // The module info won't be used here but it keeps the snapshot limited to + // the current process so a search through all processes is not needed. + HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); + if (snap == INVALID_HANDLE_VALUE) + return 0; + PROCESSENTRY32 entry; + entry.dwSize = sizeof(entry); + if (!Process32First(snap, &entry)) + entry.th32ParentProcessID = 0; + CloseHandle(snap); + return static_cast<uint32_t>(entry.th32ParentProcessID); +} + +std::string SystemInfo::getProcessName() +{ + // Only want info for the current process, so ask for something specific. + // The module info won't be used here but it keeps the snapshot limited to + // the current process so a search through all processes is not needed. + HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); + if (snap == INVALID_HANDLE_VALUE) + return 0; + PROCESSENTRY32 entry; + entry.dwSize = sizeof(entry); + if (!Process32First(snap, &entry)) + entry.szExeFile[0] = '\0'; + CloseHandle(snap); + return std::string(entry.szExeFile); +} + }} // namespace qpid::sys diff --git a/qpid/cpp/src/qpid/sys/windows/uuid.h b/qpid/cpp/src/qpid/sys/windows/uuid.h index a44ef2e9a3..7d003c3739 100644 --- a/qpid/cpp/src/qpid/sys/windows/uuid.h +++ b/qpid/cpp/src/qpid/sys/windows/uuid.h @@ -23,6 +23,7 @@ */ #include <Rpc.h> +#include "qpid/CommonImportExport.h" #ifdef uuid_t /* Done in rpcdce.h */ # undef uuid_t @@ -31,11 +32,11 @@ namespace qpid { namespace sys { const size_t UuidSize = 16; }} typedef uint8_t uuid_t[qpid::sys::UuidSize]; -void uuid_clear (uuid_t uu); -void uuid_copy (uuid_t dst, const uuid_t src); -void uuid_generate (uuid_t out); -int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0 -int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1 -void uuid_unparse (const uuid_t uu, char *out); +QPID_COMMON_EXTERN void uuid_clear (uuid_t uu); +QPID_COMMON_EXTERN void uuid_copy (uuid_t dst, const uuid_t src); +QPID_COMMON_EXTERN void uuid_generate (uuid_t out); +QPID_COMMON_EXTERN int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0 +QPID_COMMON_EXTERN int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1 +QPID_COMMON_EXTERN void uuid_unparse (const uuid_t uu, char *out); #endif /*!_sys_windows_uuid_h*/ diff --git a/qpid/cpp/src/qpid/xml/XmlExchange.cpp b/qpid/cpp/src/qpid/xml/XmlExchange.cpp index 5197b239d0..4e9de49ad5 100644 --- a/qpid/cpp/src/qpid/xml/XmlExchange.cpp +++ b/qpid/cpp/src/qpid/xml/XmlExchange.cpp @@ -33,6 +33,9 @@ #include "qpid/Plugin.h" #include <xercesc/framework/MemBufInputSource.hpp> + +#include <xqilla/ast/XQGlobalVariable.hpp> + #include <xqilla/context/ItemFactory.hpp> #include <xqilla/xqilla-simple.hpp> @@ -62,17 +65,6 @@ XmlExchange::XmlExchange(const std::string& _name, bool _durable, mgmtExchange->set_type (typeName); } -/* - * Use the name of the query as the binding key. - * - * The first time a given name is used in a binding, the query body - * must be provided.After that, no query body should be present. - * - * To modify an installed query, the user must first unbind the - * existing query, then replace it by binding again with the same - * name. - * - */ // #### TODO: The Binding should take the query text // #### only. Consider encapsulating the entire block, including @@ -94,6 +86,21 @@ bool XmlExchange::bind(Queue::shared_ptr queue, const string& routingKey, const bindings.add(binding); QPID_LOG(trace, "Bound successfully with query: " << queryText ); + binding->parse_message_content = false; + + if (query->getQueryBody()->getStaticAnalysis().areContextFlagsUsed()) { + binding->parse_message_content = true; + } + else { + GlobalVariables &vars = const_cast<GlobalVariables&>(query->getVariables()); + for(GlobalVariables::iterator it = vars.begin(); it != vars.end(); ++it) { + if ((*it)->getStaticAnalysis().areContextFlagsUsed()) { + binding->parse_message_content = true; + break; + } + } + } + if (mgmtExchange != 0) { mgmtExchange->inc_bindingCount(); ((_qmf::Queue*) queue->GetManagementObject())->inc_bindingCount(); @@ -126,59 +133,74 @@ bool XmlExchange::unbind(Queue::shared_ptr queue, const string& routingKey, cons } } -bool XmlExchange::matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args) +bool XmlExchange::matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args, bool parse_message_content) { - // ### TODO: Need istream for frameset - // Hack alert - the following code does not work for really large messages - string msgContent; try { - msg.getMessage().getFrames().getContent(msgContent); - - QPID_LOG(trace, "matches: query is [" << UTF8(query->getQueryText()) << "]"); - QPID_LOG(trace, "matches: message content is [" << msgContent << "]"); - - boost::scoped_ptr<DynamicContext> context(query->createDynamicContext()); - if (!context.get()) { - throw InternalErrorException(QPID_MSG("Query context looks munged ...")); - } - - XERCES_CPP_NAMESPACE::MemBufInputSource xml((const XMLByte*) msgContent.c_str(), - msgContent.length(), "input" ); - Sequence seq(context->parseDocument(xml)); - - if (args) { - FieldTable::ValueMap::const_iterator v = args->begin(); - for(; v != args->end(); ++v) { - // ### TODO: Do types properly - if (v->second->convertsTo<std::string>()) { - QPID_LOG(trace, "XmlExchange, external variable: " << v->first << " = " << v->second->getData().getString().c_str()); - Item::Ptr value = context->getItemFactory()->createString(X(v->second->getData().getString().c_str()), context.get()); - context->setExternalVariable(X(v->first.c_str()), value); - } - } - } - - if(!seq.isEmpty() && seq.first()->isNode()) { - context->setContextItem(seq.first()); - context->setContextPosition(1); - context->setContextSize(1); - } - Result result = query->execute(context.get()); - return result->getEffectiveBooleanValue(context.get(), 0); + QPID_LOG(trace, "matches: query is [" << UTF8(query->getQueryText()) << "]"); + + boost::scoped_ptr<DynamicContext> context(query->createDynamicContext()); + if (!context.get()) { + throw InternalErrorException(QPID_MSG("Query context looks munged ...")); + } + + if (parse_message_content) { + + msg.getMessage().getFrames().getContent(msgContent); + + QPID_LOG(trace, "matches: message content is [" << msgContent << "]"); + + XERCES_CPP_NAMESPACE::MemBufInputSource xml((const XMLByte*) msgContent.c_str(), + msgContent.length(), "input" ); + + // This will parse the document using either Xerces or FastXDM, depending + // on your XQilla configuration. FastXDM can be as much as 10x faster. + + Sequence seq(context->parseDocument(xml)); + + if(!seq.isEmpty() && seq.first()->isNode()) { + context->setContextItem(seq.first()); + context->setContextPosition(1); + context->setContextSize(1); + } + } + + if (args) { + FieldTable::ValueMap::const_iterator v = args->begin(); + for(; v != args->end(); ++v) { + // ### TODO: Do types properly + if (v->second->convertsTo<std::string>()) { + QPID_LOG(trace, "XmlExchange, external variable: " << v->first << " = " << v->second->getData().getString().c_str()); + Item::Ptr value = context->getItemFactory()->createString(X(v->second->getData().getString().c_str()), context.get()); + context->setExternalVariable(X(v->first.c_str()), value); + } + } + } + + Result result = query->execute(context.get()); + return result->getEffectiveBooleanValue(context.get(), 0); } catch (XQException& e) { - QPID_LOG(warning, "Could not parse XML content (or message headers):" << msgContent); - return 0; + QPID_LOG(warning, "Could not parse XML content (or message headers):" << msgContent); } catch (...) { - QPID_LOG(warning, "Unexpected error routing message: " << msgContent); - return 0; + QPID_LOG(warning, "Unexpected error routing message: " << msgContent); } return 0; } +// Future optimization: If any query in a binding for a given routing key requires +// message content, parse the message once, and use that parsed form for all bindings. +// +// Future optimization: XQilla does not currently do document projection for data +// accessed via the context item. If there is a single query for a given routing key, +// and it accesses document data, this could be a big win. +// +// Document projection often is not a win if you have multiple queries on the same data. +// But for very large messages, if all these queries are on the first part of the data, +// it could still be a big win. + void XmlExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* args) { PreRoute pr(msg, this); @@ -192,7 +214,7 @@ void XmlExchange::route(Deliverable& msg, const string& routingKey, const FieldT int count(0); for (std::vector<XmlBinding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); i++) { - if ((*i)->xquery && matches((*i)->xquery, msg, args)) { // Overly defensive? There should always be a query ... + if (matches((*i)->xquery, msg, args, (*i)->parse_message_content)) { msg.deliverTo((*i)->queue); count++; QPID_LOG(trace, "Delivered to queue" ); diff --git a/qpid/cpp/src/qpid/xml/XmlExchange.h b/qpid/cpp/src/qpid/xml/XmlExchange.h index 066a26489d..7bec480bde 100644 --- a/qpid/cpp/src/qpid/xml/XmlExchange.h +++ b/qpid/cpp/src/qpid/xml/XmlExchange.h @@ -46,9 +46,10 @@ class XmlExchange : public virtual Exchange { typedef qpid::sys::CopyOnWriteArray<XmlBinding::shared_ptr> vector; boost::shared_ptr<XQQuery> xquery; + bool parse_message_content; XmlBinding(const std::string& key, const Queue::shared_ptr queue, Exchange* parent, Query query): - Binding(key, queue, parent), xquery(query) {} + Binding(key, queue, parent), xquery(query), parse_message_content(true) {} }; @@ -58,7 +59,7 @@ class XmlExchange : public virtual Exchange { XQilla xqilla; qpid::sys::RWlock lock; - bool matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args); + bool matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args, bool parse_message_content); public: static const std::string typeName; diff --git a/qpid/cpp/src/replication.mk b/qpid/cpp/src/replication.mk index 6830f99d36..c65a7ae3b9 100644 --- a/qpid/cpp/src/replication.mk +++ b/qpid/cpp/src/replication.mk @@ -29,6 +29,9 @@ replicating_listener_la_SOURCES = \ qpid/replication/ReplicatingEventListener.h replicating_listener_la_LIBADD = libqpidbroker.la +if SUNOS + replicating_listener_la_LIBADD += libqpidcommon.la -lboost_program_options -luuid $(SUNCC_RUNTIME_LIBS) +endif replicating_listener_la_LDFLAGS = $(PLUGINLDFLAGS) @@ -43,4 +46,7 @@ replication_exchange_la_SOURCES = \ replication_exchange_la_LIBADD = libqpidbroker.la +if SUNOS + replication_exchange_la_LIBADD += libqpidcommon.la -lboost_program_options -lCrun -luuid +endif replication_exchange_la_LDFLAGS = $(PLUGINLDFLAGS) diff --git a/qpid/cpp/src/tests/ClientSessionTest.cpp b/qpid/cpp/src/tests/ClientSessionTest.cpp index 1658f3d4ec..589e1154e1 100644 --- a/qpid/cpp/src/tests/ClientSessionTest.cpp +++ b/qpid/cpp/src/tests/ClientSessionTest.cpp @@ -428,8 +428,8 @@ QPID_AUTO_TEST_CASE(testConcurrentSenders) for (size_t i = 0; i < 5; i++) { publishers.push_back(new Publisher(connection, message, 100)); } - for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::start, _1)); - for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::join, _1)); + std::for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::start, _1)); + std::for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::join, _1)); connection.close(); } @@ -564,6 +564,24 @@ QPID_AUTO_TEST_CASE(testSessionManagerSetFlowControl) { BOOST_CHECK_EQUAL("my-message", got.getData()); } +QPID_AUTO_TEST_CASE(testGetThenSubscribe) { + ClientSessionFixture fix; + std::string name("myqueue"); + fix.session.queueDeclare(arg::queue=name, arg::exclusive=true, arg::autoDelete=true); + fix.session.messageTransfer(arg::content=Message("one", name)); + fix.session.messageTransfer(arg::content=Message("two", name)); + Message got; + BOOST_CHECK(fix.subs.get(got, name)); + BOOST_CHECK_EQUAL("one", got.getData()); + + DummyListener listener(fix.session, name, 1); + listener.run(); + BOOST_CHECK_EQUAL(1u, listener.messages.size()); + if (!listener.messages.empty()) { + BOOST_CHECK_EQUAL("two", listener.messages[0].getData()); + } +} + QPID_AUTO_TEST_SUITE_END() diff --git a/qpid/cpp/src/tests/ClusterFixture.cpp b/qpid/cpp/src/tests/ClusterFixture.cpp index 3a0ea74098..5658957b48 100644 --- a/qpid/cpp/src/tests/ClusterFixture.cpp +++ b/qpid/cpp/src/tests/ClusterFixture.cpp @@ -109,7 +109,7 @@ void ClusterFixture::addLocal() { Args args(makeArgs(prefix)); vector<const char*> argv(args.size()); transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1)); - qpid::log::Logger::instance().setPrefix(os.str()); + qpid::log::Logger::instance().setPrefix(prefix); localBroker.reset(new BrokerFixture(parseOpts(argv.size(), &argv[0]))); push_back(localBroker->getPort()); forkedBrokers.push_back(shared_ptr<ForkedBroker>()); diff --git a/qpid/cpp/src/tests/DispatcherTest.cpp b/qpid/cpp/src/tests/DispatcherTest.cpp index c2f6bca12a..c619a36438 100644 --- a/qpid/cpp/src/tests/DispatcherTest.cpp +++ b/qpid/cpp/src/tests/DispatcherTest.cpp @@ -78,9 +78,6 @@ void reader(DispatchHandle& h, int fd) { h.rewatch(); } -DispatchHandle* rh = 0; -DispatchHandle* wh = 0; - void rInterrupt(DispatchHandle&) { cerr << "R"; } @@ -92,9 +89,27 @@ void wInterrupt(DispatchHandle&) { DispatchHandle::Callback rcb = rInterrupt; DispatchHandle::Callback wcb = wInterrupt; +DispatchHandleRef *volatile rh = 0; +DispatchHandleRef *volatile wh = 0; + +volatile bool stopWait = false; +volatile bool phase1finished = false; + +timer_t timer; + +void stop_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) { + stopWait = true; +} + void timer_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) { - rh->call(rcb); - wh->call(wcb); + static int count = 0; + if (count++ < 10) { + rh->call(rcb); + wh->call(wcb); + } else { + phase1finished = true; + assert(::timer_delete(timer) == 0); + } } int main(int /*argc*/, char** /*argv*/) @@ -114,7 +129,7 @@ int main(int /*argc*/, char** /*argv*/) // Setup sender and receiver int sv[2]; - int rc = ::socketpair(AF_LOCAL, SOCK_STREAM, 0, sv); + int rc = ::socketpair(AF_UNIX, SOCK_STREAM, 0, sv); assert(rc >= 0); // Set non-blocking @@ -132,8 +147,8 @@ int main(int /*argc*/, char** /*argv*/) PosixIOHandle f0(sv[0]); PosixIOHandle f1(sv[1]); - rh = new DispatchHandle(f0, boost::bind(reader, _1, sv[0]), 0, 0); - wh = new DispatchHandle(f1, 0, boost::bind(writer, _1, sv[1], testString), 0); + rh = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0); + wh = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0); rh->startWatch(poller); wh->startWatch(poller); @@ -155,10 +170,9 @@ int main(int /*argc*/, char** /*argv*/) assert(rc == 0); ::sigevent se; + ::memset(&se, 0, sizeof(se)); // Clear to make valgrind happy (this *is* the neatest way to do this portably - sigh) se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIGRTMIN; - se.sigev_value.sival_ptr = 0; - timer_t timer; rc = ::timer_create(CLOCK_REALTIME, &se, &timer); assert(rc == 0); @@ -169,11 +183,52 @@ int main(int /*argc*/, char** /*argv*/) rc = ::timer_settime(timer, 0, &ts, 0); assert(rc == 0); - // wait 2 minutes then shutdown - ::sleep(60); + // wait + while (!phase1finished) { + ::sleep(1); + } + + // Now test deleting/creating DispatchHandles in tight loop, so that we are likely to still be using the + // attached PollerHandles after deleting the DispatchHandle + DispatchHandleRef* t = wh; + wh = 0; + delete t; + t = rh; + rh = 0; + delete t; + + sa.sa_sigaction = stop_handler; + rc = ::sigaction(SIGRTMIN, &sa,0); + assert(rc == 0); + + itimerspec nts = { + /*.it_value = */ {30, 0}, // s, ns + /*.it_interval = */ {30, 0}}; // s, ns + + rc = ::timer_create(CLOCK_REALTIME, &se, &timer); + assert(rc == 0); + rc = ::timer_settime(timer, 0, &nts, 0); + assert(rc == 0); + + DispatchHandleRef* rh1; + DispatchHandleRef* wh1; + + struct timespec w = {0, 1000000}; + while (!stopWait) { + rh1 = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0); + wh1 = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0); + rh1->startWatch(poller); + wh1->startWatch(poller); + + ::nanosleep(&w, 0); + + delete wh1; + delete rh1; + } rc = ::timer_delete(timer); assert(rc == 0); + poller->shutdown(); dt.join(); dt1.join(); diff --git a/qpid/cpp/src/tests/FieldTable.cpp b/qpid/cpp/src/tests/FieldTable.cpp index 6b364723cf..9f2fd45b73 100644 --- a/qpid/cpp/src/tests/FieldTable.cpp +++ b/qpid/cpp/src/tests/FieldTable.cpp @@ -22,7 +22,7 @@ #include "qpid/framing/Array.h" #include "qpid/framing/FieldTable.h" #include "qpid/framing/FieldValue.h" -#include <alloca.h> +#include "qpid/sys/alloca.h" #include "unit_test.h" diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp index 2b90068549..f90f76aeb2 100644 --- a/qpid/cpp/src/tests/ForkedBroker.cpp +++ b/qpid/cpp/src/tests/ForkedBroker.cpp @@ -22,6 +22,9 @@ #include "ForkedBroker.h" #include <boost/bind.hpp> #include <algorithm> +#include <stdlib.h> +#include <sys/types.h> +#include <signal.h> ForkedBroker::ForkedBroker(const Args& args) { init(args); } @@ -41,9 +44,9 @@ void ForkedBroker::kill(int sig) { if (::kill(savePid, sig) < 0) throw ErrnoException("kill failed"); int status; - if (::waitpid(savePid, &status, 0) < 0) + if (::waitpid(savePid, &status, 0) < 0 && sig != 9) throw ErrnoException("wait for forked process failed"); - if (WEXITSTATUS(status) != 0) + if (WEXITSTATUS(status) != 0 && sig != 9) throw qpid::Exception(QPID_MSG("Forked broker exited with: " << WEXITSTATUS(status))); } diff --git a/qpid/cpp/src/tests/FrameDecoder.cpp b/qpid/cpp/src/tests/FrameDecoder.cpp new file mode 100644 index 0000000000..f5db66d5fe --- /dev/null +++ b/qpid/cpp/src/tests/FrameDecoder.cpp @@ -0,0 +1,73 @@ +/* + * + * 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 "unit_test.h" +#include "qpid/framing/AMQFrame.h" +#include "qpid/framing/FrameDecoder.h" +#include "qpid/framing/AMQContentBody.h" +#include "qpid/framing/Buffer.h" +#include <string> + + +QPID_AUTO_TEST_SUITE(FrameDecoderTest) + +using namespace std; +using namespace qpid::framing; + + +string makeData(int size) { + string data; + data.resize(size); + for (int i =0; i < size; ++i) + data[i] = 'a' + (i%26); + return data; +} +string encodeFrame(string data) { + AMQFrame f((AMQContentBody(data))); + string encoded; + encoded.resize(f.encodedSize()); + Buffer b(&encoded[0], encoded.size()); + f.encode(b); + return encoded; +} + +string getData(const AMQFrame& frame) { + const AMQContentBody* content = dynamic_cast<const AMQContentBody*>(frame.getBody()); + BOOST_CHECK(content); + return content->getData(); +} + +QPID_AUTO_TEST_CASE(testByteFragments) { + string data = makeData(42); + string encoded = encodeFrame(data); + FrameDecoder decoder; + for (size_t i = 0; i < encoded.size()-1; ++i) { + Buffer buf(&encoded[i], 1); + BOOST_CHECK(!decoder.decode(buf)); + } + Buffer buf(&encoded[encoded.size()-1], 1); + BOOST_CHECK(decoder.decode(buf)); + BOOST_CHECK_EQUAL(data, getData(decoder.getFrame())); +} + + + +QPID_AUTO_TEST_SUITE_END() diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am index 9da85eaad4..9a81ef18b3 100644 --- a/qpid/cpp/src/tests/Makefile.am +++ b/qpid/cpp/src/tests/Makefile.am @@ -94,7 +94,9 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \ QueueEvents.cpp \ ProxyTest.cpp \ RetryList.cpp \ - RateFlowcontrolTest.cpp + RateFlowcontrolTest.cpp \ + FrameDecoder.cpp \ + ReplicationTest.cpp if HAVE_XML unit_test_SOURCES+= XmlClientSessionTest.cpp @@ -163,7 +165,7 @@ header_test_LDADD=$(lib_client) check_PROGRAMS+=failover_soak failover_soak_SOURCES=failover_soak.cpp ForkedBroker.h ForkedBroker.cpp -failover_soak_LDADD=$(lib_client) +failover_soak_LDADD=$(lib_client) $(lib_broker) check_PROGRAMS+=declare_queues declare_queues_SOURCES=declare_queues.cpp @@ -195,11 +197,11 @@ sender_LDADD=$(lib_client) check_PROGRAMS+=PollerTest PollerTest_SOURCES=PollerTest.cpp -PollerTest_LDADD=$(lib_common) +PollerTest_LDADD=$(lib_common) $(SOCKLIBS) check_PROGRAMS+=DispatcherTest DispatcherTest_SOURCES=DispatcherTest.cpp -DispatcherTest_LDADD=$(lib_common) +DispatcherTest_LDADD=$(lib_common) $(SOCKLIBS) TESTS_ENVIRONMENT = VALGRIND=$(VALGRIND) srcdir=$(srcdir) QPID_DATA_DIR= BOOST_TEST_SHOW_PROGRESS=yes $(srcdir)/run_test @@ -255,9 +257,11 @@ CLEANFILES+=valgrind.out *.log *.vglog* dummy_test $(unit_wrappers) # Longer running stability tests, not run by default check: target. # Not run under valgrind, too slow -LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak stop_broker reliable_replication_test +LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak stop_broker \ + reliable_replication_test federated_cluster_test_with_node_failure -EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test +EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test \ + federated_cluster_test_with_node_failure check-long: $(MAKE) check TESTS="$(LONG_TESTS)" VALGRIND= diff --git a/qpid/cpp/src/tests/MessageTest.cpp b/qpid/cpp/src/tests/MessageTest.cpp index 8fd9a53c7c..cd63f64a37 100644 --- a/qpid/cpp/src/tests/MessageTest.cpp +++ b/qpid/cpp/src/tests/MessageTest.cpp @@ -24,13 +24,12 @@ #include "qpid/framing/MessageTransferBody.h" #include "qpid/framing/FieldValue.h" #include "qpid/framing/Uuid.h" +#include "qpid/sys/alloca.h" #include "unit_test.h" #include <iostream> -#include <alloca.h> -using namespace boost; using namespace qpid::broker; using namespace qpid::framing; @@ -44,7 +43,7 @@ QPID_AUTO_TEST_CASE(testEncodeDecode) string data1("abcdefg"); string data2("hijklmn"); - intrusive_ptr<Message> msg(new Message()); + boost::intrusive_ptr<Message> msg(new Message()); AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0))); AMQFrame header((AMQHeaderBody())); diff --git a/qpid/cpp/src/tests/MessageUtils.h b/qpid/cpp/src/tests/MessageUtils.h index 67a852aa10..6a12c72007 100644 --- a/qpid/cpp/src/tests/MessageUtils.h +++ b/qpid/cpp/src/tests/MessageUtils.h @@ -33,7 +33,7 @@ struct MessageUtils static boost::intrusive_ptr<Message> createMessage(const string& exchange="", const string& routingKey="", const Uuid& messageId=Uuid(true), uint64_t contentSize = 0) { - boost::intrusive_ptr<Message> msg(new Message()); + boost::intrusive_ptr<broker::Message> msg(new broker::Message()); AMQFrame method(( MessageTransferBody(ProtocolVersion(), exchange, 0, 0))); AMQFrame header((AMQHeaderBody())); diff --git a/qpid/cpp/src/tests/PollerTest.cpp b/qpid/cpp/src/tests/PollerTest.cpp index 4f11dc5901..5b6b09ef65 100644 --- a/qpid/cpp/src/tests/PollerTest.cpp +++ b/qpid/cpp/src/tests/PollerTest.cpp @@ -74,7 +74,7 @@ int main(int /*argc*/, char** /*argv*/) try { int sv[2]; - int rc = ::socketpair(AF_LOCAL, SOCK_STREAM, 0, sv); + int rc = ::socketpair(AF_UNIX, SOCK_STREAM, 0, sv); assert(rc >= 0); // Set non-blocking diff --git a/qpid/cpp/src/tests/ProxyTest.cpp b/qpid/cpp/src/tests/ProxyTest.cpp index 9007f3dc97..4ea10f7be9 100644 --- a/qpid/cpp/src/tests/ProxyTest.cpp +++ b/qpid/cpp/src/tests/ProxyTest.cpp @@ -23,7 +23,6 @@ #include "qpid/framing/AMQMethodBody.h" #include "qpid/framing/ExecutionSyncBody.h" #include "qpid/framing/Proxy.h" -#include <alloca.h> #include "unit_test.h" diff --git a/qpid/cpp/src/tests/QueueEvents.cpp b/qpid/cpp/src/tests/QueueEvents.cpp index 3e377d04b3..cd9439355e 100644 --- a/qpid/cpp/src/tests/QueueEvents.cpp +++ b/qpid/cpp/src/tests/QueueEvents.cpp @@ -27,6 +27,7 @@ #include "qpid/broker/QueueEvents.h" #include "qpid/client/QueueOptions.h" #include "qpid/framing/SequenceNumber.h" +#include "qpid/sys/Dispatcher.h" #include <boost/bind.hpp> #include <boost/format.hpp> @@ -37,7 +38,7 @@ using namespace qpid::broker; using namespace qpid::sys; using qpid::framing::SequenceNumber; -struct DummyListener +struct EventChecker { typedef std::deque<QueueEvents::Event> Events; @@ -70,9 +71,9 @@ QPID_AUTO_TEST_CASE(testBasicEventProcessing) sys::Dispatcher dispatcher(poller); Thread dispatchThread(dispatcher); QueueEvents events(poller); - DummyListener listener; + EventChecker listener; listener.poller = poller; - events.registerListener("dummy", boost::bind(&DummyListener::handle, &listener, _1)); + events.registerListener("dummy", boost::bind(&EventChecker::handle, &listener, _1)); //signal occurence of some events: Queue queue("queue1"); SequenceNumber id; diff --git a/qpid/cpp/src/tests/QueuePolicyTest.cpp b/qpid/cpp/src/tests/QueuePolicyTest.cpp index 6c650169c7..7c7f8b7a10 100644 --- a/qpid/cpp/src/tests/QueuePolicyTest.cpp +++ b/qpid/cpp/src/tests/QueuePolicyTest.cpp @@ -158,6 +158,15 @@ QPID_AUTO_TEST_CASE(testRingPolicy) BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData()); } BOOST_CHECK(!f.subs.get(msg, q)); + + for (int i = 10; i < 20; i++) { + f.session.messageTransfer(arg::content=client::Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), q)); + } + for (int i = 15; i < 20; i++) { + BOOST_CHECK(f.subs.get(msg, q, qpid::sys::TIME_SEC)); + BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData()); + } + BOOST_CHECK(!f.subs.get(msg, q)); } QPID_AUTO_TEST_CASE(testStrictRingPolicy) diff --git a/qpid/cpp/src/tests/ReplicationTest.cpp b/qpid/cpp/src/tests/ReplicationTest.cpp new file mode 100644 index 0000000000..7bd585639d --- /dev/null +++ b/qpid/cpp/src/tests/ReplicationTest.cpp @@ -0,0 +1,129 @@ + /* + * + * 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 "unit_test.h" +#include "test_tools.h" +#include "BrokerFixture.h" + +#include "qpid/Plugin.h" +#include "qpid/broker/Broker.h" +#include "qpid/client/QueueOptions.h" +#include "qpid/framing/reply_exceptions.h" +#include "qpid/framing/SequenceNumber.h" +#include "qpid/replication/constants.h" +#include "qpid/sys/Shlib.h" + +#include <string> +#include <sstream> +#include <vector> + +#include <boost/assign.hpp> +#include <boost/bind.hpp> + +using namespace qpid::client; +using namespace qpid::framing; +using namespace qpid::replication::constants; +using boost::assign::list_of; + +QPID_AUTO_TEST_SUITE(ReplicationTestSuite) + +qpid::sys::Shlib plugin("../.libs/replicating_listener.so"); + +qpid::broker::Broker::Options getBrokerOpts(const std::vector<std::string>& args) +{ + std::vector<const char*> argv(args.size()); + transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1)); + + qpid::broker::Broker::Options opts; + qpid::Plugin::addOptions(opts); + opts.parse(argv.size(), &argv[0], "", true); + return opts; +} + +QPID_AUTO_TEST_CASE(testReplicationExchange) +{ + qpid::broker::Broker::Options brokerOpts(getBrokerOpts(list_of<string>("qpidd") + ("--replication-exchange-name=qpid.replication"))); + ProxySessionFixture f(brokerOpts); + + + std::string dataQ("queue-1"); + std::string eventQ("event-queue-1"); + std::string dataQ2("queue-2"); + std::string eventQ2("event-queue-2"); + FieldTable eventQopts; + eventQopts.setString("qpid.insert_sequence_numbers", REPLICATION_EVENT_SEQNO); + + f.session.queueDeclare(arg::queue=eventQ, arg::exclusive=true, arg::autoDelete=true, arg::arguments=eventQopts); + f.session.exchangeBind(arg::exchange="qpid.replication", arg::queue=eventQ, arg::bindingKey=dataQ); + + f.session.queueDeclare(arg::queue=eventQ2, arg::exclusive=true, arg::autoDelete=true, arg::arguments=eventQopts); + f.session.exchangeBind(arg::exchange="qpid.replication", arg::queue=eventQ2, arg::bindingKey=dataQ2); + + QueueOptions args; + args.enableQueueEvents(false); + f.session.queueDeclare(arg::queue=dataQ, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args); + f.session.queueDeclare(arg::queue=dataQ2, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args); + for (int i = 0; i < 10; i++) { + f.session.messageTransfer(arg::content=Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), dataQ)); + f.session.messageTransfer(arg::content=Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), dataQ2)); + } + Message msg; + LocalQueue incoming; + Subscription sub = f.subs.subscribe(incoming, dataQ); + for (int i = 0; i < 10; i++) { + BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC)); + BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData()); + } + BOOST_CHECK(!f.subs.get(msg, dataQ)); + + sub.cancel(); + sub = f.subs.subscribe(incoming, eventQ); + //check that we received enqueue events for first queue: + for (int i = 0; i < 10; i++) { + BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC)); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), ENQUEUE); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+1)); + BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData()); + } + //check that we received dequeue events for first queue: + for (int i = 0; i < 10; i++) { + BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC)); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), DEQUEUE); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(DEQUEUED_MESSAGE_POSITION), (i+1)); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+11)); + } + + sub.cancel(); + sub = f.subs.subscribe(incoming, eventQ2); + //check that we received enqueue events for second queue: + for (int i = 0; i < 10; i++) { + BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC)); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ2); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), ENQUEUE); + BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+1)); + BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData()); + } +} + + +QPID_AUTO_TEST_SUITE_END() diff --git a/qpid/cpp/src/tests/SocketProxy.h b/qpid/cpp/src/tests/SocketProxy.h index 9722359d82..d2a93c902b 100644 --- a/qpid/cpp/src/tests/SocketProxy.h +++ b/qpid/cpp/src/tests/SocketProxy.h @@ -94,7 +94,7 @@ class SocketProxy : private qpid::sys::Runnable throwIf(!(event.type == qpid::sys::Poller::READABLE && event.handle == &listenerHandle), "SocketProxy: Accept failed"); poller.delFd(listenerHandle); - server.reset(listener.accept(0, 0)); + server.reset(listener.accept()); // Pump data between client & server sockets qpid::sys::PollerHandle clientHandle(client); diff --git a/qpid/cpp/src/tests/TimerTest.cpp b/qpid/cpp/src/tests/TimerTest.cpp index 50712ff79c..f8ab9fb2f3 100644 --- a/qpid/cpp/src/tests/TimerTest.cpp +++ b/qpid/cpp/src/tests/TimerTest.cpp @@ -75,7 +75,11 @@ class TestTask : public TimerTask BOOST_CHECK(fired); BOOST_CHECK_EQUAL(expected_position, position); Duration actual(start, end); +#ifdef _WIN32 + uint64_t difference = _abs64(expected - actual); +#else uint64_t difference = abs(expected - actual); +#endif std::string msg(boost::lexical_cast<std::string>(boost::format("tolerance = %1%, difference = %2%") % tolerance % difference)); BOOST_CHECK_MESSAGE(difference < tolerance, msg); } diff --git a/qpid/cpp/src/tests/Uuid.cpp b/qpid/cpp/src/tests/Uuid.cpp index ee86d75a26..ea2e80b63b 100644 --- a/qpid/cpp/src/tests/Uuid.cpp +++ b/qpid/cpp/src/tests/Uuid.cpp @@ -18,11 +18,11 @@ #include "qpid/framing/Uuid.h" #include "qpid/framing/Buffer.h" +#include "qpid/sys/alloca.h" #include "unit_test.h" #include <set> -#include <alloca.h> QPID_AUTO_TEST_SUITE(UuidTestSuite) diff --git a/qpid/cpp/src/tests/client_test.vcproj b/qpid/cpp/src/tests/client_test.vcproj index 0f9a50cdf0..1623c2961e 100644 --- a/qpid/cpp/src/tests/client_test.vcproj +++ b/qpid/cpp/src/tests/client_test.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="client_test"
- ProjectGUID="{9A95F0E4-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="client_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\client_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\client_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\client_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\client_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\client_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\client_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\client_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\client_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/cluster.mk b/qpid/cpp/src/tests/cluster.mk index c3100ac968..5d115de5a5 100644 --- a/qpid/cpp/src/tests/cluster.mk +++ b/qpid/cpp/src/tests/cluster.mk @@ -29,8 +29,9 @@ if HAVE_LIBCPG # ais_check checks pre-requisites for cluster tests and runs them if ok. -TESTS+=ais_check federated_cluster_test -EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt federated_cluster_test +TESTS+=ais_check federated_cluster_test clustered_replication_test +EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt \ + federated_cluster_test clustered_replication_test check_PROGRAMS+=cluster_test cluster_test_SOURCES=unit_test.cpp cluster_test.cpp ClusterFixture.cpp ClusterFixture.h ForkedBroker.h ForkedBroker.cpp diff --git a/qpid/cpp/src/tests/cluster_test.cpp b/qpid/cpp/src/tests/cluster_test.cpp index c880f30e6b..eee2df58cc 100644 --- a/qpid/cpp/src/tests/cluster_test.cpp +++ b/qpid/cpp/src/tests/cluster_test.cpp @@ -27,6 +27,7 @@ #include "qpid/client/ConnectionAccess.h" #include "qpid/client/Session.h" #include "qpid/client/FailoverListener.h" +#include "qpid/client/FailoverManager.h" #include "qpid/cluster/Cluster.h" #include "qpid/cluster/Cpg.h" #include "qpid/cluster/UpdateClient.h" @@ -35,6 +36,8 @@ #include "qpid/framing/reply_exceptions.h" #include "qpid/framing/enum.h" #include "qpid/log/Logger.h" +#include "qpid/sys/Monitor.h" +#include "qpid/sys/Thread.h" #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> @@ -148,49 +151,65 @@ vector<string> browse(Client& c, const string& q, int n) { c.subs.subscribe(lq, q, browseSettings); vector<string> result; for (int i = 0; i < n; ++i) { - result.push_back(lq.get(TIMEOUT).getData()); + Message m; + if (!lq.get(m, TIMEOUT)) + break; + result.push_back(m.getData()); } c.subs.getSubscription(q).cancel(); return result; } +ConnectionSettings aclSettings(int port, const std::string& id) { + ConnectionSettings settings; + settings.port = port; + settings.mechanism = "PLAIN"; + settings.username = id; + settings.password = id; + return settings; +} + +#if 0 +// FIXME aconway 2009-03-10: This test passes but exposes a memory leak in the SASL client code. +// Enable it when the leak is fixed. + +QPID_AUTO_TEST_CASE(testAcl) { + ofstream policyFile("cluster_test.acl"); + // FIXME aconway 2009-02-12: guest -> qpidd? + policyFile << "acl allow foo@QPID create queue name=foo" << endl + << "acl allow foo@QPID create queue name=foo2" << endl + << "acl deny foo@QPID create queue name=bar" << endl + << "acl allow all all" << endl; + policyFile.close(); + char cwd[1024]; + BOOST_CHECK(::getcwd(cwd, sizeof(cwd))); + ClusterFixture cluster(2,-1, list_of<string> + ("--no-data-dir") + ("--auth=no") + ("--acl-file="+string(cwd)+"/cluster_test.acl") + ("--cluster-mechanism=PLAIN") + ("--cluster-username=cluster") + ("--cluster-password=cluster") + ("--load-module=../.libs/acl.so")); + + Client c0(aclSettings(cluster[0], "c0"), "c0"); + Client c1(aclSettings(cluster[1], "c1"), "c1"); + Client foo(aclSettings(cluster[1], "foo"), "foo"); + + foo.session.queueDeclare("foo"); + BOOST_CHECK_EQUAL(c0.session.queueQuery("foo").getQueue(), "foo"); + + BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), framing::NotAllowedException); + BOOST_CHECK(c0.session.queueQuery("bar").getQueue().empty()); + BOOST_CHECK(c1.session.queueQuery("bar").getQueue().empty()); -// FIXME aconway 2009-02-12: need to figure out how to test this properly. -// Current problems: -// - all brokers share the same data-dir (set ACL without data dir?) -// - updater's user name not making it through to updatee for ACL checks. -// -// QPID_AUTO_TEST_CASE(testAcl) { -// ofstream policyFile("cluster_test.acl"); -// // FIXME aconway 2009-02-12: guest -> qpidd? -// policyFile << "acl allow guest@QPID all all" << endl -// << "acl allow foo@QPID create queue name=foo" << endl -// << "acl allow bar@QPID create queue name=bar" << endl -// << "acl deny all create queue" << endl -// << "acl allow all all" << endl; -// policyFile.close(); -// ClusterFixture cluster(2,-1, list_of<string> -// ("--data-dir=.") ("--auth=no") -// ("--acl-file=cluster_test.acl") -// ("--cluster-mechanism=PLAIN") -// ("--load-module=../.libs/acl.so")); -// Client c0(cluster[0], "c0"); -// Client c1(cluster[1], "c1"); - -// ConnectionSettings settings; -// settings.port = cluster[0]; -// settings.username = "foo"; -// Client foo(settings, "foo"); - -// foo.session.queueDeclare("foo"); -// BOOST_CHECK_EQUAL(c0.session.queueQuery("foo").getQueue(), "foo"); -// BOOST_CHECK_EQUAL(c1.session.queueQuery("foo").getQueue(), "foo"); - -// BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), int); -// BOOST_CHECK_EQUAL(c0.session.queueQuery("bar").getQueue(), ""); -// BOOST_CHECK_EQUAL(c1.session.queueQuery("bar").getQueue(), ""); -// } + cluster.add(); + Client c2(aclSettings(cluster[2], "c2"), "c2"); + BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), framing::NotAllowedException); + BOOST_CHECK(c2.session.queueQuery("bar").getQueue().empty()); +} +#endif QPID_AUTO_TEST_CASE(testMessageTimeToLive) { // Note: this doesn't actually test for cluster race conditions around TTL, @@ -199,13 +218,23 @@ QPID_AUTO_TEST_CASE(testMessageTimeToLive) { ClusterFixture cluster(2); Client c0(cluster[0], "c0"); Client c1(cluster[1], "c1"); + c0.session.queueDeclare("p"); c0.session.queueDeclare("q"); c0.session.messageTransfer(arg::content=ttlMessage("a", "q", 200)); c0.session.messageTransfer(arg::content=Message("b", "q")); - BOOST_CHECK_EQUAL(browse(c1, "q", 2), list_of<string>("a")("b")); - sys::usleep(300*1000); + c0.session.messageTransfer(arg::content=ttlMessage("x", "p", 10000)); + c0.session.messageTransfer(arg::content=Message("y", "p")); + cluster.add(); + Client c2(cluster[1], "c2"); + + BOOST_CHECK_EQUAL(browse(c0, "p", 2), list_of<string>("x")("y")); + BOOST_CHECK_EQUAL(browse(c1, "p", 2), list_of<string>("x")("y")); + BOOST_CHECK_EQUAL(browse(c2, "p", 2), list_of<string>("x")("y")); + + sys::usleep(200*1000); BOOST_CHECK_EQUAL(browse(c0, "q", 1), list_of<string>("b")); BOOST_CHECK_EQUAL(browse(c1, "q", 1), list_of<string>("b")); + BOOST_CHECK_EQUAL(browse(c2, "q", 1), list_of<string>("b")); } QPID_AUTO_TEST_CASE(testSequenceOptions) { @@ -506,10 +535,11 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) { c0.session.queueDeclare("q"); c0.session.messageTransfer(arg::content=Message("foo","q")); c0.session.messageTransfer(arg::content=Message("bar","q")); + while (c0.session.queueQuery("q").getMessageCount() != 2) sys::usleep(1000); // Wait for message to show up on broker 0. - // Add a new broker, it should catch up. + // Add a new broker, it will catch up. cluster.add(); // Do some work post-add @@ -527,6 +557,7 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) { BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT)); BOOST_CHECK_EQUAL(m.getData(), "foo"); + BOOST_CHECK_EQUAL(m.getDeliveryProperties().getExchange(), ""); BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT)); BOOST_CHECK_EQUAL(m.getData(), "bar"); BOOST_CHECK_EQUAL(c1.session.queueQuery("q").getMessageCount(), 0u); @@ -628,4 +659,86 @@ QPID_AUTO_TEST_CASE(testDequeueWaitingSubscription) { BOOST_CHECK_EQUAL(0u, c2.session.queueQuery("q").getMessageCount()); } +QPID_AUTO_TEST_CASE(testHeartbeatCancelledOnFailover) +{ + struct Sender : FailoverManager::Command + { + std::string queue; + std::string content; + + Sender(const std::string& q, const std::string& c) : queue(q), content(c) {} + + void execute(AsyncSession& session, bool) + { + session.messageTransfer(arg::content=Message(content, queue)); + } + }; + + struct Receiver : FailoverManager::Command, MessageListener, qpid::sys::Runnable + { + FailoverManager& mgr; + std::string queue; + std::string expectedContent; + qpid::client::Subscription subscription; + qpid::sys::Monitor lock; + bool ready; + + Receiver(FailoverManager& m, const std::string& q, const std::string& c) : mgr(m), queue(q), expectedContent(c), ready(false) {} + + void received(Message& message) + { + BOOST_CHECK_EQUAL(expectedContent, message.getData()); + subscription.cancel(); + } + + void execute(AsyncSession& session, bool) + { + session.queueDeclare(arg::queue=queue); + SubscriptionManager subs(session); + subscription = subs.subscribe(*this, queue); + session.sync(); + setReady(); + subs.run(); + //cleanup: + session.queueDelete(arg::queue=queue); + } + + void run() + { + mgr.execute(*this); + } + + void waitForReady() + { + qpid::sys::Monitor::ScopedLock l(lock); + while (!ready) { + lock.wait(); + } + } + + void setReady() + { + qpid::sys::Monitor::ScopedLock l(lock); + ready = true; + lock.notify(); + } + }; + + ClusterFixture cluster(2); + ConnectionSettings settings; + settings.port = cluster[1]; + settings.heartbeat = 1; + FailoverManager fmgr(settings); + Sender sender("my-queue", "my-data"); + Receiver receiver(fmgr, "my-queue", "my-data"); + qpid::sys::Thread runner(receiver); + receiver.waitForReady(); + cluster.kill(1); + //sleep for 2 secs to allow the heartbeat task to fire on the now dead connection: + ::usleep(2*1000*1000); + fmgr.execute(sender); + runner.join(); + fmgr.close(); +} + QPID_AUTO_TEST_SUITE_END() diff --git a/qpid/cpp/src/tests/clustered_replication_test b/qpid/cpp/src/tests/clustered_replication_test new file mode 100755 index 0000000000..2a3e742632 --- /dev/null +++ b/qpid/cpp/src/tests/clustered_replication_test @@ -0,0 +1,127 @@ +#!/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. +# + +# Test reliability of the replication feature in the face of link +# failures: +srcdir=`dirname $0` +PYTHON_DIR=$srcdir/../../../python + +trap stop_brokers INT EXIT + +fail() { + echo $1 + exit 1 +} +with_ais_group() { + id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group." 1>&2; exit 1; } + echo $* | newgrp ais +} + +stop_brokers() { + if [[ $PRIMARY1 ]] ; then + ../qpidd -q --port $PRIMARY1 + unset PRIMARY1 + fi + if [[ $PRIMARY2 ]] ; then + ../qpidd -q --port $PRIMARY2 + unset PRIMARY2 + fi + if [[ $DR1 ]] ; then + ../qpidd -q --port $DR1 + unset DR1 + fi + if [[ $DR2 ]] ; then + ../qpidd -q --port $DR2 + unset DR2 + fi +} + +if test -d ${PYTHON_DIR}; then + id -nG | grep '\<ais\>' >/dev/null || \ + NOGROUP="You are not a member of the ais group." + ps -u root | grep 'aisexec\|corosync' >/dev/null || \ + NOAISEXEC="The aisexec or corosync daemon is not running as root" + + if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then + cat <<EOF +Not running federation to cluster test because: + $NOGROUP + $NOAISEXEC +EOF + exit 0; + fi + + #todo: these cluster names need to be unique to prevent clashes + PRIMARY_CLUSTER=PRIMARY_$(hostname)_$(pwd) + DR_CLUSTER=DR_$(hostname)_$(pwd) + + GENERAL_OPTS="--auth no --no-module-dir --no-data-dir --daemon --port 0 --log-enable notice+ --log-to-stderr false" + PRIMARY_OPTS="--load-module ../.libs/replicating_listener.so --create-replication-queue true --replication-queue REPLICATION_QUEUE --load-module ../.libs/cluster.so --cluster-name $PRIMARY_CLUSTER" + DR_OPTS="--load-module ../.libs/replication_exchange.so --load-module ../.libs/cluster.so --cluster-name $DR_CLUSTER" + + rm -f repl*.tmp #cleanup any files left from previous run + + #start first node of primary cluster and set up test queue + echo Starting primary cluster + PRIMARY1=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.1.tmp) || fail "Could not start node" + $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue test-queue --generate-queue-events 2 + $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue control-queue --generate-queue-events 1 + + #send 10 messages, consume 5 of them + for i in `seq 1 10`; do echo Message$i; done | ./sender --port $PRIMARY1 + ./receiver --port $PRIMARY1 --messages 5 > /dev/null + + #add new node to primary cluster, testing correct transfer of state: + echo Adding node to primary cluster + PRIMARY2=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.2.tmp) + + #start DR cluster, set up test queue there and establish replication bridge + echo Starting DR cluster + DR1=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.1.tmp) + DR2=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.2.tmp) + + $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue test-queue + $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue control-queue + $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add exchange replication REPLICATION_EXCHANGE + $PYTHON_DIR/commands/qpid-route queue add localhost:$DR2 localhost:$PRIMARY2 REPLICATION_EXCHANGE REPLICATION_QUEUE + + #send more messages to primary + for i in `seq 11 20`; do echo Message$i; done | ./sender --port $PRIMARY1 --send-eos 1 + + #wait for replication events to all be processed: + echo Waiting for replication to complete + echo Done | ./sender --port $PRIMARY1 --routing-key control-queue --send-eos 1 + ./receiver --queue control-queue --port $DR1 > /dev/null + + #verify contents of test queue on dr cluster: + echo Verifying... + ./receiver --port $DR2 > repl.out.tmp + for i in `seq 6 20`; do echo Message$i; done | diff repl.out.tmp - || FAIL=1 + + if [[ $FAIL ]]; then + echo Clustered replication test failed: expectations not met! + exit 1 + else + echo Clustered replication test passed + rm -f repl*.tmp + fi + +fi diff --git a/qpid/cpp/src/tests/consume.vcproj b/qpid/cpp/src/tests/consume.vcproj index ecf7b2df08..2e1f8e3e56 100644 --- a/qpid/cpp/src/tests/consume.vcproj +++ b/qpid/cpp/src/tests/consume.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="consume"
- ProjectGUID="{7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="consume"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\consume\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\consume\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\consume\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\consume\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\consume\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\consume\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\consume\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\consume\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/echotest.vcproj b/qpid/cpp/src/tests/echotest.vcproj index 0048dde85f..2848894228 100644 --- a/qpid/cpp/src/tests/echotest.vcproj +++ b/qpid/cpp/src/tests/echotest.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="echotest"
- ProjectGUID="{0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="echotest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\echotest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\echotest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\echotest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\echotest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\echotest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\echotest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\echotest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\echotest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/failover_soak.cpp b/qpid/cpp/src/tests/failover_soak.cpp index 6149e845e4..4f16e469b8 100644 --- a/qpid/cpp/src/tests/failover_soak.cpp +++ b/qpid/cpp/src/tests/failover_soak.cpp @@ -26,18 +26,32 @@ #include <sys/wait.h> #include <sys/time.h> #include <string.h> +#include <sys/types.h> +#include <signal.h> #include <string> #include <iostream> #include <sstream> #include <vector> +#include <boost/assign.hpp> + +#include "qpid/framing/Uuid.h" + #include <ForkedBroker.h> +#include <qpid/client/Connection.h> + + using namespace std; +using boost::assign::list_of; +using namespace qpid::framing; +using namespace qpid::client; + + typedef vector<ForkedBroker *> brokerVector; @@ -51,11 +65,34 @@ typedef enum childStatus; +typedef enum +{ + NO_TYPE, + DECLARING_CLIENT, + SENDING_CLIENT, + RECEIVING_CLIENT +} +childType; + + +ostream& operator<< ( ostream& os, const childType& ct ) { + switch ( ct ) { + case DECLARING_CLIENT: os << "Declaring Client"; break; + case SENDING_CLIENT: os << "Sending Client"; break; + case RECEIVING_CLIENT: os << "Receiving Client"; break; + default: os << "No Client"; break; + } + + return os; +} + + + struct child { - child ( string & name, pid_t pid ) - : name(name), pid(pid), retval(-999), status(RUNNING) + child ( string & name, pid_t pid, childType type ) + : name(name), pid(pid), retval(-999), status(RUNNING), type(type) { gettimeofday ( & startTime, 0 ); } @@ -70,10 +107,18 @@ struct child } + void + setType ( childType t ) + { + type = t; + } + + string name; pid_t pid; int retval; childStatus status; + childType type; struct timeval startTime, stopTime; }; @@ -83,10 +128,11 @@ struct child struct children : public vector<child *> { + void - add ( string & name, pid_t pid ) + add ( string & name, pid_t pid, childType type ) { - push_back(new child ( name, pid )); + push_back ( new child ( name, pid, type ) ); } @@ -108,7 +154,7 @@ struct children : public vector<child *> child * kid = get ( pid ); if(! kid) { - if ( verbosity > 0 ) + if ( verbosity > 1 ) { cerr << "children::exited warning: Can't find child with pid " << pid @@ -138,10 +184,15 @@ struct children : public vector<child *> int checkChildren ( ) { - vector<child *>::iterator i; + vector<child *>::iterator i; for ( i = begin(); i != end(); ++ i ) if ( (COMPLETED == (*i)->status) && (0 != (*i)->retval) ) - return (*i)->retval; + { + cerr << "checkChildren: error on child of type " + << (*i)->type + << endl; + return (*i)->retval; + } return 0; } @@ -176,22 +227,43 @@ struct children : public vector<child *> If it has been at least that long since a shild stopped running, we judge the system to have hung. */ - bool + int hanging ( int hangTime ) { struct timeval now, duration; gettimeofday ( &now, 0 ); + int how_many_hanging = 0; + vector<child *>::iterator i; for ( i = begin(); i != end(); ++ i ) { - timersub ( & now, &((*i)->startTime), & duration ); - if ( duration.tv_sec >= hangTime ) - return true; + //Not in POSIX + //timersub ( & now, &((*i)->startTime), & duration ); + duration.tv_sec = now.tv_sec - (*i)->startTime.tv_sec; + duration.tv_usec = now.tv_usec - (*i)->startTime.tv_usec; + if (duration.tv_usec < 0) { + --duration.tv_sec; + duration.tv_usec += 1000000; + } + + if ( (COMPLETED != (*i)->status) // child isn't done running + && + ( duration.tv_sec >= hangTime ) // it's been too long + ) + { + std::cerr << "Child of type " + << (*i)->type + << " hanging. " + << "PID is " + << (*i)->pid + << endl; + ++ how_many_hanging; + } } - return false; + return how_many_hanging; } @@ -206,9 +278,8 @@ children allMyChildren; void -childExit ( int signalNumber ) +childExit ( int ) { - signalNumber ++; // Now maybe the compiler willleave me alone? int childReturnCode; pid_t pid = waitpid ( 0, & childReturnCode, WNOHANG); @@ -235,10 +306,9 @@ mrand ( int minDesiredVal, int maxDesiredVal ) { void -makeClusterName ( string & s, int & num ) { - num = mrand(1000); +makeClusterName ( string & s ) { stringstream ss; - ss << "soakTestCluster_" << num; + ss << "soakTestCluster_" << Uuid(true).str(); s = ss.str(); } @@ -263,66 +333,136 @@ printBrokers ( brokerVector & brokers ) +ForkedBroker * newbie = 0; +int newbie_port = 0; + + + +bool +wait_for_newbie ( ) +{ + if ( ! newbie ) + return true; + + try + { + Connection connection; + connection.open ( "127.0.0.1", newbie_port ); + connection.close(); + newbie = 0; // He's no newbie anymore! + return true; + } + catch ( const std::exception& error ) + { + std::cerr << "wait_for_newbie error: " + << error.what() + << endl; + return false; + } +} + + + void startNewBroker ( brokerVector & brokers, char const * srcRoot, char const * moduleDir, - string const clusterName ) + string const clusterName, + int verbosity ) { static int brokerId = 0; stringstream path, prefix, module; module << moduleDir << "/cluster.so"; path << srcRoot << "/qpidd"; - prefix << "soak-" << brokerId++; - - const char * const argv[] = - { - "qpidd", - "-p0", - "--load-module=cluster.so", - "--cluster-name", - clusterName.c_str(), - "--auth=no", - "--no-data-dir", - "--no-module-dir", - "--mgmt-enable=no", - "--log-prefix", prefix.str().c_str(), - 0 - }; - - size_t argc = sizeof(argv)/sizeof(argv[0]); - brokers.push_back ( new ForkedBroker ( argc, argv ) ); + prefix << "soak-" << brokerId; + std::vector<std::string> argv = list_of<string> + ("qpidd") + ("--no-module-dir") + ("--load-module=cluster.so") + ("--cluster-name") + (clusterName) + ("--auth=no") + ("--no-data-dir") + ("--mgmt-enable=no") + ("--log-prefix") + (prefix.str()) + ("--log-to-file") + (prefix.str()+".log"); + + newbie = new ForkedBroker ( argv ); + newbie_port = newbie->getPort(); + ForkedBroker * broker = newbie; + + if ( verbosity > 0 ) + std::cerr << "new broker created: pid == " + << broker->getPID() + << " log-prefix == " + << "soak-" << brokerId + << endl; + brokers.push_back ( broker ); + + ++ brokerId; } -void +bool killFrontBroker ( brokerVector & brokers, int verbosity ) { + cerr << "killFrontBroker: waiting for newbie sync...\n"; + if ( ! wait_for_newbie() ) + return false; + cerr << "killFrontBroker: newbie synced.\n"; + if ( verbosity > 0 ) cout << "killFrontBroker pid: " << brokers[0]->getPID() << " on port " << brokers[0]->getPort() << endl; try { brokers[0]->kill(9); } catch ( const exception& error ) { if ( verbosity > 0 ) - cout << "error killing broker: " << error.what() << endl; + { + cout << "error killing broker: " + << error.what() + << endl; + } + + return false; } delete brokers[0]; brokers.erase ( brokers.begin() ); + return true; } +/* + * The optional delay is to avoid killing newbie brokers that have just + * been added and are still in the process of updating. This causes + * spurious, test-generated errors that scare everybody. + */ void -killAllBrokers ( brokerVector & brokers ) +killAllBrokers ( brokerVector & brokers, int delay ) { + if ( delay > 0 ) + { + std::cerr << "Killing all brokers after delay of " << delay << endl; + sleep ( delay ); + } + for ( uint i = 0; i < brokers.size(); ++ i ) try { brokers[i]->kill(9); } - catch ( ... ) { } + catch ( const exception& error ) + { + std::cerr << "killAllBrokers Warning: exception during kill on broker " + << i + << " " + << error.what() + << endl; + } } @@ -339,7 +479,7 @@ runDeclareQueuesClient ( brokerVector brokers, string name("declareQueues"); int port = brokers[0]->getPort ( ); - if ( verbosity > 0 ) + if ( verbosity > 1 ) cout << "startDeclareQueuesClient: host: " << host << " port: " @@ -357,11 +497,11 @@ runDeclareQueuesClient ( brokerVector brokers, if ( ! pid ) { execv ( path, const_cast<char * const *>(&argv[0]) ); - perror ( "error executing dq: " ); + perror ( "error executing declareQueues: " ); return 0; } - allMyChildren.add ( name, pid ); + allMyChildren.add ( name, pid, DECLARING_CLIENT ); return pid; } @@ -380,12 +520,16 @@ startReceivingClient ( brokerVector brokers, string name("receiver"); int port = brokers[0]->getPort ( ); - if ( verbosity > 0 ) + if ( verbosity > 1 ) cout << "startReceivingClient: port " << port << endl; + + // verbosity has to be > 1 to let clients talk. + int client_verbosity = (verbosity > 1 ) ? 1 : 0; + char portStr[100]; char verbosityStr[100]; sprintf(portStr, "%d", port); - sprintf(verbosityStr, "%d", verbosity); + sprintf(verbosityStr, "%d", client_verbosity); vector<const char*> argv; @@ -404,7 +548,7 @@ startReceivingClient ( brokerVector brokers, return 0; } - allMyChildren.add ( name, pid ); + allMyChildren.add ( name, pid, RECEIVING_CLIENT ); return pid; } @@ -424,13 +568,16 @@ startSendingClient ( brokerVector brokers, string name("sender"); int port = brokers[0]->getPort ( ); - if ( verbosity ) + if ( verbosity > 1) cout << "startSenderClient: port " << port << endl; char portStr[100]; char verbosityStr[100]; + // + // verbosity has to be > 1 to let clients talk. + int client_verbosity = (verbosity > 1 ) ? 1 : 0; sprintf ( portStr, "%d", port); - sprintf ( verbosityStr, "%d", verbosity); + sprintf ( verbosityStr, "%d", client_verbosity); vector<const char*> argv; argv.push_back ( "replayingSender" ); @@ -449,19 +596,21 @@ startSendingClient ( brokerVector brokers, return 0; } - allMyChildren.add ( name, pid ); + allMyChildren.add ( name, pid, SENDING_CLIENT ); return pid; } -#define HUNKY_DORY 0 -#define BAD_ARGS 1 -#define CANT_FORK_DQ 2 -#define CANT_FORK_RECEIVER 3 -#define DQ_FAILED 4 -#define ERROR_ON_CHILD 5 -#define HANGING 6 +#define HUNKY_DORY 0 +#define BAD_ARGS 1 +#define CANT_FORK_DQ 2 +#define CANT_FORK_RECEIVER 3 +#define CANT_FORK_SENDER 4 +#define DQ_FAILED 5 +#define ERROR_ON_CHILD 6 +#define HANGING 7 +#define ERROR_KILLING_BROKER 8 int @@ -489,16 +638,15 @@ main ( int argc, char const ** argv ) allMyChildren.verbosity = verbosity; - int clusterNum; string clusterName; srand ( getpid() ); - makeClusterName ( clusterName, clusterNum ); + makeClusterName ( clusterName ); brokerVector brokers; - if ( verbosity > 0 ) + if ( verbosity > 1 ) cout << "Starting initial cluster...\n"; int nBrokers = 3; @@ -506,7 +654,8 @@ main ( int argc, char const ** argv ) startNewBroker ( brokers, srcRoot, moduleDir, - clusterName ); + clusterName, + verbosity ); } @@ -518,14 +667,14 @@ main ( int argc, char const ** argv ) pid_t dqClientPid = runDeclareQueuesClient ( brokers, host, declareQueuesPath, verbosity ); if ( -1 == dqClientPid ) { - cerr << "failoverSoak error: Couldn't fork declareQueues.\n"; + cerr << "END_OF_TEST ERROR_START_DECLARE_1\n"; return CANT_FORK_DQ; } // Don't continue until declareQueues is finished. pid_t retval = waitpid ( dqClientPid, & childStatus, 0); if ( retval != dqClientPid) { - cerr << "failoverSoak error: waitpid on declareQueues returned value " << retval << endl; + cerr << "END_OF_TEST ERROR_START_DECLARE_2\n"; return DQ_FAILED; } allMyChildren.exited ( dqClientPid, childStatus ); @@ -540,7 +689,7 @@ main ( int argc, char const ** argv ) reportFrequency, verbosity ); if ( -1 == receivingClientPid ) { - cerr << "failoverSoak error: Couldn't fork receiver.\n"; + cerr << "END_OF_TEST ERROR_START_RECEIVER\n"; return CANT_FORK_RECEIVER; } @@ -554,13 +703,13 @@ main ( int argc, char const ** argv ) reportFrequency, verbosity ); if ( -1 == sendingClientPid ) { - cerr << "failoverSoak error: Couldn't fork sender.\n"; - return CANT_FORK_RECEIVER; + cerr << "END_OF_TEST ERROR_START_SENDER\n"; + return CANT_FORK_SENDER; } - int minSleep = 3, - maxSleep = 6; + int minSleep = 2, + maxSleep = 4; for ( int totalBrokers = 3; @@ -578,11 +727,16 @@ main ( int argc, char const ** argv ) sleep ( sleepyTime ); // Kill the oldest broker. -------------------------- - killFrontBroker ( brokers, verbosity ); + if ( ! killFrontBroker ( brokers, verbosity ) ) + { + allMyChildren.killEverybody(); + std::cerr << "END_OF_TEST ERROR_BROKER\n"; + return ERROR_KILLING_BROKER; + } // Sleep for a while. ------------------------- sleepyTime = mrand ( minSleep, maxSleep ); - if ( verbosity > 0 ) + if ( verbosity > 1 ) cerr << "Sleeping for " << sleepyTime << " seconds.\n"; sleep ( sleepyTime ); @@ -593,22 +747,33 @@ main ( int argc, char const ** argv ) startNewBroker ( brokers, srcRoot, moduleDir, - clusterName ); + clusterName, + verbosity ); - if ( verbosity > 0 ) + if ( verbosity > 1 ) printBrokers ( brokers ); // If all children have exited, quit. int unfinished = allMyChildren.unfinished(); if ( ! unfinished ) { - killAllBrokers ( brokers ); + killAllBrokers ( brokers, 5 ); - if ( verbosity > 0 ) + if ( verbosity > 1 ) cout << "failoverSoak: all children have exited.\n"; int retval = allMyChildren.checkChildren(); - if ( verbosity > 0 ) + if ( verbosity > 1 ) std::cerr << "failoverSoak: checkChildren: " << retval << endl; - return retval ? ERROR_ON_CHILD : HUNKY_DORY; + + if ( retval ) + { + std::cerr << "END_OF_TEST ERROR_CLIENT\n"; + return ERROR_ON_CHILD; + } + else + { + std::cerr << "END_OF_TEST SUCCESSFUL\n"; + return HUNKY_DORY; + } } // Even if some are still running, if there's an error, quit. @@ -617,35 +782,38 @@ main ( int argc, char const ** argv ) if ( verbosity > 0 ) cout << "failoverSoak: error on child.\n"; allMyChildren.killEverybody(); - killAllBrokers ( brokers ); + killAllBrokers ( brokers, 5 ); + std::cerr << "END_OF_TEST ERROR_CLIENT\n"; return ERROR_ON_CHILD; } // If one is hanging, quit. if ( allMyChildren.hanging ( 120 ) ) { - if ( verbosity > 0 ) - cout << "failoverSoak: child hanging.\n"; - allMyChildren.killEverybody(); - killAllBrokers ( brokers ); + /* + * Don't kill any processes. Leave alive for questioning. + * */ + std::cerr << "END_OF_TEST ERROR_HANGING\n"; return HANGING; } - if ( verbosity > 0 ) { + if ( verbosity > 1 ) { std::cerr << "------- next kill-broker loop --------\n"; allMyChildren.print(); } } retval = allMyChildren.checkChildren(); - if ( verbosity > 0 ) + if ( verbosity > 1 ) std::cerr << "failoverSoak: checkChildren: " << retval << endl; - if ( verbosity > 0 ) + if ( verbosity > 1 ) cout << "failoverSoak: maxBrokers reached.\n"; allMyChildren.killEverybody(); - killAllBrokers ( brokers ); + killAllBrokers ( brokers, 5 ); + + std::cerr << "END_OF_TEST SUCCESSFUL\n"; return retval ? ERROR_ON_CHILD : HUNKY_DORY; } diff --git a/qpid/cpp/src/tests/federated_cluster_test b/qpid/cpp/src/tests/federated_cluster_test index d4549738b2..575a5d9c9b 100755 --- a/qpid/cpp/src/tests/federated_cluster_test +++ b/qpid/cpp/src/tests/federated_cluster_test @@ -21,8 +21,8 @@ # Test reliability of the replication feature in the face of link # failures: -MY_DIR=`dirname \`which $0\`` -PYTHON_DIR=${MY_DIR}/../../../python +srcdir=`dirname $0` +PYTHON_DIR=$srcdir/../../../python trap stop_brokers EXIT @@ -37,9 +37,14 @@ stop_brokers() { unset BROKER_A fi if [[ $NODE_1 ]] ; then - ./stop_cluster + ../qpidd -q --port $NODE_1 unset NODE_1 fi + if [[ $NODE_2 ]] ; then + ../qpidd -q --port $NODE_2 + unset NODE_2 + fi + rm cluster.ports } start_brokers() { @@ -48,19 +53,20 @@ start_brokers() { BROKER_A=`cat fed.port.tmp` #...and start cluster - ./start_cluster 2 || fail "Could not start cluster" + $srcdir/start_cluster 2 || fail "Could not start cluster" NODE_1=$(head -1 cluster.ports) NODE_2=$(tail -1 cluster.ports) } setup() { + export PYTHONPATH=$PYTHON_DIR #create exchange on both cluster and single broker $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add exchange direct test-exchange $PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add exchange direct test-exchange #create dynamic routes for test exchange - $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_1" "localhost:$BROKER_A" test-exchange - $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_1" test-exchange + $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_2" "localhost:$BROKER_A" test-exchange + $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_2" test-exchange #create test queue on cluster and bind it to the test exchange $PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add queue test-queue @@ -71,7 +77,7 @@ setup() { $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" bind test-exchange test-queue from-cluster } -run_test_pull_to_cluster() { +run_test_pull_to_cluster_two_consumers() { #start consumers on each of the two nodes of the cluster ./receiver --port $NODE_1 --queue test-queue --credit-window 1 > fed1.out.tmp & ./receiver --port $NODE_2 --queue test-queue --credit-window 1 > fed2.out.tmp & @@ -88,6 +94,20 @@ run_test_pull_to_cluster() { rm -f fed*.tmp #cleanup } +run_test_pull_to_cluster() { + #send stream of messages to test exchange on single broker + for i in `seq 1 1000`; do echo Message $i >> fed.in.tmp; done + ./sender --port $BROKER_A --exchange test-exchange --routing-key to-cluster --send-eos 1 < fed.in.tmp + + #consume from remaining node of the cluster + ./receiver --port $NODE_2 --queue test-queue > fed.out.tmp + + #verify all messages are received + diff fed.in.tmp fed.out.tmp || fail "federated link to cluster failed: expectations not met!" + + rm -f fed*.tmp #cleanup +} + run_test_pull_from_cluster() { #start consumer on single broker ./receiver --port $BROKER_A --queue test-queue --credit-window 1 > fed.out.tmp & @@ -124,8 +144,19 @@ EOF echo "brokers started" setup echo "setup completed" - run_test_pull_to_cluster + run_test_pull_to_cluster_two_consumers echo "federated link to cluster verified" run_test_pull_from_cluster echo "federated link from cluster verified" + if [[ $TEST_NODE_FAILURE ]] ; then + #kill first cluster node and retest + kill -9 $(../qpidd --check --port $NODE_1) && unset NODE_1 + echo "killed first cluster node; waiting for links to re-establish themselves..." + sleep 5 + echo "retesting..." + run_test_pull_to_cluster + echo "federated link to cluster verified" + run_test_pull_from_cluster + echo "federated link from cluster verified" + fi fi diff --git a/qpid/cpp/src/tests/federated_cluster_test_with_node_failure b/qpid/cpp/src/tests/federated_cluster_test_with_node_failure new file mode 100755 index 0000000000..f144a676de --- /dev/null +++ b/qpid/cpp/src/tests/federated_cluster_test_with_node_failure @@ -0,0 +1,23 @@ +#!/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. +# + +srcdir=`dirname $0` +TEST_NODE_FAILURE=1 $srcdir/federated_cluster_test diff --git a/qpid/cpp/src/tests/header_test.vcproj b/qpid/cpp/src/tests/header_test.vcproj index 9a1da958cc..da761a6edb 100644 --- a/qpid/cpp/src/tests/header_test.vcproj +++ b/qpid/cpp/src/tests/header_test.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="header_test"
- ProjectGUID="{1B23F05D-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="header_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\header_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\header_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\header_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\header_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\header_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\header_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\header_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\header_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/latencytest.vcproj b/qpid/cpp/src/tests/latencytest.vcproj index eb9741a1e1..758302029a 100644 --- a/qpid/cpp/src/tests/latencytest.vcproj +++ b/qpid/cpp/src/tests/latencytest.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="latencytest"
- ProjectGUID="{4A809018-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{4A809018-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="latencytest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\latencytest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\latencytest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\latencytest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\latencytest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\latencytest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\latencytest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\latencytest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\latencytest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/logging.cpp b/qpid/cpp/src/tests/logging.cpp index 051722e7c8..00e1d7de85 100644 --- a/qpid/cpp/src/tests/logging.cpp +++ b/qpid/cpp/src/tests/logging.cpp @@ -23,6 +23,7 @@ #include "qpid/memory.h" #include "qpid/Options.h" #if defined (_WIN32) +# include "qpid/log/windows/SinkOptions.h" #else # include "qpid/log/posix/SinkOptions.h" #endif @@ -172,7 +173,7 @@ QPID_AUTO_TEST_CASE(testLoggerFormat) { l.format(Logger::FUNCTION); QPID_LOG(critical, "foo"); - BOOST_CHECK_REGEX("void .*testLoggerFormat.*\\(\\): foo\n", out->last()); + BOOST_CHECK_EQUAL(string(BOOST_CURRENT_FUNCTION) + ": foo\n", out->last()); l.format(Logger::LEVEL); QPID_LOG(critical, "foo"); @@ -270,7 +271,11 @@ QPID_AUTO_TEST_CASE(testOptionsParse) { "--log-function", "YES" }; qpid::log::Options opts(""); +#ifdef _WIN32 + qpid::log::windows::SinkOptions sinks("test"); +#else qpid::log::posix::SinkOptions sinks("test"); +#endif opts.parse(ARGC(argv), const_cast<char**>(argv)); sinks = *opts.sinkOptions; vector<string> expect=list_of("error+:foo")("debug:bar")("info"); @@ -286,7 +291,11 @@ QPID_AUTO_TEST_CASE(testOptionsParse) { QPID_AUTO_TEST_CASE(testOptionsDefault) { Options opts(""); +#ifdef _WIN32 + qpid::log::windows::SinkOptions sinks("test"); +#else qpid::log::posix::SinkOptions sinks("test"); +#endif sinks = *opts.sinkOptions; BOOST_CHECK(sinks.logToStderr); BOOST_CHECK(!sinks.logToStdout); @@ -345,8 +354,13 @@ QPID_AUTO_TEST_CASE(testQuoteNonPrintable) { ScopedSuppressLogging ls(l); Options opts("test"); opts.time=false; +#ifdef _WIN32 + qpid::log::windows::SinkOptions *sinks = + dynamic_cast<qpid::log::windows::SinkOptions *>(opts.sinkOptions.get()); +#else qpid::log::posix::SinkOptions *sinks = dynamic_cast<qpid::log::posix::SinkOptions *>(opts.sinkOptions.get()); +#endif sinks->logToStderr = false; sinks->logFile = "logging.tmp"; l.configure(opts); diff --git a/qpid/cpp/src/tests/perftest.cpp b/qpid/cpp/src/tests/perftest.cpp index 6456bc8304..18491d72a0 100644 --- a/qpid/cpp/src/tests/perftest.cpp +++ b/qpid/cpp/src/tests/perftest.cpp @@ -38,7 +38,6 @@ #include <sstream> #include <numeric> #include <algorithm> -#include <unistd.h> #include <math.h> @@ -238,8 +237,10 @@ struct Client : public Runnable { ~Client() { try { - session.close(); - connection->close(); + if (connection->isOpen()) { + session.close(); + connection->close(); + } } catch (const std::exception& e) { std::cerr << "Error in shutdown: " << e.what() << std::endl; } @@ -523,7 +524,8 @@ struct PublishThread : public Client { sync(session).txCommit(); } } - if (opts.intervalPub) ::usleep(opts.intervalPub*1000); + if (opts.intervalPub) + qpid::sys::usleep(opts.intervalPub*1000); } if (opts.confirm) session.sync(); AbsTime end=now(); @@ -613,7 +615,8 @@ struct SubscribeThread : public Client { if (opts.commitAsync) session.txCommit(); else sync(session).txCommit(); } - if (opts.intervalSub) ::usleep(opts.intervalSub*1000); + if (opts.intervalSub) + qpid::sys::usleep(opts.intervalSub*1000); // TODO aconway 2007-11-23: check message order for. // multiple publishers. Need an array of counters, // one per publisher and a publisher ID in the diff --git a/qpid/cpp/src/tests/perftest.vcproj b/qpid/cpp/src/tests/perftest.vcproj index c9132bac03..3a2397ac9b 100644 --- a/qpid/cpp/src/tests/perftest.vcproj +++ b/qpid/cpp/src/tests/perftest.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="perftest"
- ProjectGUID="{1F2066BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="perftest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\perftest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\perftest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\perftest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\perftest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\perftest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\perftest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\perftest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\perftest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/publish.vcproj b/qpid/cpp/src/tests/publish.vcproj index a205337ecd..7422606a32 100644 --- a/qpid/cpp/src/tests/publish.vcproj +++ b/qpid/cpp/src/tests/publish.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="publish"
- ProjectGUID="{AE773E7F-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="publish"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\publish\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\publish\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\publish\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\publish\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\publish\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\publish\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\publish\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\publish\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/receiver.cpp b/qpid/cpp/src/tests/receiver.cpp index 1ecaece51e..49f7ff0338 100644 --- a/qpid/cpp/src/tests/receiver.cpp +++ b/qpid/cpp/src/tests/receiver.cpp @@ -23,7 +23,7 @@ #include <qpid/client/Session.h> #include <qpid/client/Message.h> #include <qpid/client/SubscriptionManager.h> -#include <qpid/client/SubscriptionManager.h> +#include <qpid/client/SubscriptionSettings.h> #include "TestOptions.h" #include <iostream> @@ -43,15 +43,17 @@ struct Args : public qpid::TestOptions bool ignoreDuplicates; uint creditWindow; uint ackFrequency; + bool browse; - Args() : queue("test-queue"), messages(0), ignoreDuplicates(false), creditWindow(0), ackFrequency(1) + Args() : queue("test-queue"), messages(0), ignoreDuplicates(false), creditWindow(0), ackFrequency(1), browse(false) { addOptions() ("queue", qpid::optValue(queue, "QUEUE NAME"), "Queue from which to request messages") ("messages", qpid::optValue(messages, "N"), "Number of messages to receive; 0 means receive indefinitely") ("ignore-duplicates", qpid::optValue(ignoreDuplicates), "Detect and ignore duplicates (by checking 'sn' header)") ("credit-window", qpid::optValue(creditWindow, "N"), "Credit window (0 implies infinite window)") - ("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)"); + ("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)") + ("browse", qpid::optValue(browse), "Browse rather than consuming"); } }; @@ -60,7 +62,7 @@ const string EOS("eos"); class Receiver : public MessageListener, public FailoverManager::Command { public: - Receiver(const string& queue, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency); + Receiver(const string& queue, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency, bool browse); void received(Message& message); void execute(AsyncSession& session, bool isRetry); private: @@ -75,9 +77,10 @@ class Receiver : public MessageListener, public FailoverManager::Command bool isDuplicate(Message& message); }; -Receiver::Receiver(const string& q, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency) : +Receiver::Receiver(const string& q, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency, bool browse) : queue(q), count(messages), skipDups(ignoreDuplicates), processed(0), lastSn(0) { + if (browse) settings.acquireMode = ACQUIRE_MODE_NOT_ACQUIRED; if (creditWindow) settings.flowControl = FlowControl::messageWindow(creditWindow); settings.autoAck = ackFrequency; } @@ -107,6 +110,9 @@ void Receiver::execute(AsyncSession& session, bool /*isRetry*/) SubscriptionManager subs(session); subscription = subs.subscribe(*this, queue, settings); subs.run(); + if (settings.autoAck) { + subscription.accept(subscription.getUnaccepted()); + } } int main(int argc, char ** argv) @@ -115,7 +121,7 @@ int main(int argc, char ** argv) try { opts.parse(argc, argv); FailoverManager connection(opts.con); - Receiver receiver(opts.queue, opts.messages, opts.ignoreDuplicates, opts.creditWindow, opts.ackFrequency); + Receiver receiver(opts.queue, opts.messages, opts.ignoreDuplicates, opts.creditWindow, opts.ackFrequency, opts.browse); connection.execute(receiver); connection.close(); return 0; diff --git a/qpid/cpp/src/tests/receiver.vcproj b/qpid/cpp/src/tests/receiver.vcproj index 824b75d7d9..ce6fad366e 100644 --- a/qpid/cpp/src/tests/receiver.vcproj +++ b/qpid/cpp/src/tests/receiver.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="receiver"
- ProjectGUID="{7D314A98-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7D314A98-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="receiver"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\receiver\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\receiver\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\receiver\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\receiver\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\receiver\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\receiver\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\receiver\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\receiver\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/replaying_sender.cpp b/qpid/cpp/src/tests/replaying_sender.cpp index 7e148e277f..ea2a13bd54 100644 --- a/qpid/cpp/src/tests/replaying_sender.cpp +++ b/qpid/cpp/src/tests/replaying_sender.cpp @@ -60,6 +60,8 @@ Sender::Sender(const std::string& queue, uint count_, uint reportFreq ) : sender void Sender::execute(AsyncSession& session, bool isRetry) { + if (verbosity > 0) + std::cout << "replaying_sender " << (isRetry ? "first " : "re-") << "connect." << endl; if (isRetry) sender.replay(session); else sender.init(session); while (sent < count) { @@ -70,7 +72,7 @@ void Sender::execute(AsyncSession& session, bool isRetry) sender.send(message); if (count > reportFrequency && !(sent % reportFrequency)) { if ( verbosity > 0 ) - std::cout << "sent " << sent << " of " << count << std::endl; + std::cout << "Sender sent " << sent << " of " << count << std::endl; } } message.setData("That's all, folks!"); diff --git a/qpid/cpp/src/tests/replication_test b/qpid/cpp/src/tests/replication_test index 9b6e5cfb29..6e0c1c8d3b 100755 --- a/qpid/cpp/src/tests/replication_test +++ b/qpid/cpp/src/tests/replication_test @@ -22,21 +22,20 @@ # Run a test of the replication feature MY_DIR=`dirname \`which $0\`` PYTHON_DIR=${MY_DIR}/../../../python - trap stop_brokers INT TERM QUIT stop_brokers() { - if [[ $BROKER_A ]] ; then + if [ x$BROKER_A != x ]; then ../qpidd -q --port $BROKER_A unset BROKER_A fi - if [[ $BROKER_B ]] ; then + if [ x$BROKER_B != x ]; then ../qpidd -q --port $BROKER_B unset BROKER_B fi } -if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e ../.libs/replication_exchange.so ; then +if test -d ${PYTHON_DIR} && test -f ../.libs/replicating_listener.so && test -f ../.libs/replication_exchange.so; then rm -f queue-*.repl replication-*.log #cleanup from any earlier runs ../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replicating_listener.so --replication-queue replication --create-replication-queue true --log-enable info+ --log-to-file replication-source.log --log-to-stderr 0 > qpidd.port @@ -44,7 +43,8 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e ../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replication_exchange.so --log-enable info+ --log-to-file replication-dest.log --log-to-stderr 0 > qpidd.port BROKER_B=`cat qpidd.port` - export PYTHONPATH=$PYTHON_DIR + PYTHONPATH=$PYTHON_DIR + export PYTHONPATH echo "Running replication test between localhost:$BROKER_A and localhost:$BROKER_B" $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication @@ -55,23 +55,39 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 2 $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-b --generate-queue-events 2 $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-c --generate-queue-events 1 + $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 2 $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-a $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-b $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-c - - #publish and consume from test queus on broker A: - for i in `seq 1 10`; do echo Message $i for A >> queue-a-input.repl; done - for i in `seq 1 20`; do echo Message $i for B >> queue-b-input.repl; done - for i in `seq 1 15`; do echo Message $i for C >> queue-c-input.repl; done + #queue-d deliberately not declared on DR; this error case should be handled + + #publish and consume from test queues on broker A: + i=1 + while [ $i -le 10 ]; do + echo Message $i for A >> queue-a-input.repl + i=`expr $i + 1` + done + i=1 + while [ $i -le 20 ]; do + echo Message $i for B >> queue-b-input.repl + i=`expr $i + 1` + done + i=1 + while [ $i -le 15 ]; do + echo Message $i for C >> queue-c-input.repl + i=`expr $i + 1` + done ./sender --port $BROKER_A --routing-key queue-a --send-eos 1 < queue-a-input.repl ./sender --port $BROKER_A --routing-key queue-b --send-eos 1 < queue-b-input.repl ./sender --port $BROKER_A --routing-key queue-c --send-eos 1 < queue-c-input.repl + echo dummy | ./sender --port $BROKER_A --routing-key queue-d --send-eos 1 ./receiver --port $BROKER_A --queue queue-a --messages 5 > /dev/null ./receiver --port $BROKER_A --queue queue-b --messages 10 > /dev/null ./receiver --port $BROKER_A --queue queue-c --messages 10 > /dev/null + ./receiver --port $BROKER_A --queue queue-d > /dev/null #shutdown broker A then check that broker Bs versions of the queues are as expected ../qpidd -q --port $BROKER_A @@ -90,7 +106,9 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e diff queue-b-backup.repl queue-b-expected.repl || FAIL=1 diff queue-c-backup.repl queue-c-input.repl || FAIL=1 - if [[ $FAIL ]]; then + grep 'queue-d does not exist' replication-dest.log > /dev/null || echo "WARNING: Expected error to be logged!" + + if [ x$FAIL != x ]; then echo replication test failed: expectations not met! exit 1 else diff --git a/qpid/cpp/src/tests/resuming_receiver.cpp b/qpid/cpp/src/tests/resuming_receiver.cpp index f49a115e1e..ef559a009d 100644 --- a/qpid/cpp/src/tests/resuming_receiver.cpp +++ b/qpid/cpp/src/tests/resuming_receiver.cpp @@ -53,6 +53,7 @@ class Listener : public MessageListener, bool gaps; uint reportFrequency; int verbosity; + bool done; }; @@ -62,7 +63,8 @@ Listener::Listener(int freq, int verbosity) lastSn(0), gaps(false), reportFrequency(freq), - verbosity(verbosity) + verbosity(verbosity), + done(false) {} @@ -70,6 +72,7 @@ void Listener::received(Message & message) { if (message.getData() == "That's all, folks!") { + done = true; if(verbosity > 0 ) { std::cout << "Shutting down listener for " @@ -111,14 +114,14 @@ void Listener::check() if (gaps) throw Exception("Detected gaps in sequence; messages appear to have been lost."); } -void Listener::execute(AsyncSession& session, bool isRetry) -{ - if (isRetry) { - // std::cout << "Resuming from " << count << std::endl; +void Listener::execute(AsyncSession& session, bool isRetry) { + if (verbosity > 0) + std::cout << "resuming_receiver " << (isRetry ? "first " : "re-") << "connect." << endl; + if (!done) { + SubscriptionManager subs(session); + subscription = subs.subscribe(*this, "message_queue"); + subs.run(); } - SubscriptionManager subs(session); - subscription = subs.subscribe(*this, "message_queue"); - subs.run(); } void Listener::editUrlList(std::vector<Url>& urls) diff --git a/qpid/cpp/src/tests/run_failover_soak b/qpid/cpp/src/tests/run_failover_soak index 9dddf59cf1..36dfed79a6 100755 --- a/qpid/cpp/src/tests/run_failover_soak +++ b/qpid/cpp/src/tests/run_failover_soak @@ -22,8 +22,8 @@ # Check AIS requirements and run tests if found. id -ng | grep '\<ais\>' >/dev/null || \ NOGROUP="The ais group is not your primary group." -ps -u root | grep aisexec >/dev/null || \ - NOAISEXEC="The aisexec daemon is not running as root" +ps -u root | grep 'aisexec\|corosync' >/dev/null || \ + NOAISEXEC="The aisexec/corosync daemon is not running as root" if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then cat <<EOF @@ -47,10 +47,10 @@ host=127.0.0.1 src_root=.. module_dir=$src_root/.libs -n_messages=300000 -report_frequency=10000 -verbosity=1 +MESSAGES=${MESSAGES:-300000} +REPORT_FREQUENCY=${REPORT_FREQUENCY:-`expr $MESSAGES / 20`} +VERBOSITY=${VERBOSITY:-1} -exec `dirname $0`/failover_soak $src_root $module_dir $host ./declare_queues ./replaying_sender ./resuming_receiver $n_messages $report_frequency $verbosity +exec ./failover_soak $src_root $module_dir $host ./declare_queues ./replaying_sender ./resuming_receiver $MESSAGES $REPORT_FREQUENCY $VERBOSITY diff --git a/qpid/cpp/src/tests/run_header_test b/qpid/cpp/src/tests/run_header_test index 39d4a24f84..414fecd28f 100755 --- a/qpid/cpp/src/tests/run_header_test +++ b/qpid/cpp/src/tests/run_header_test @@ -29,7 +29,8 @@ test -f qpidd.port && QPID_PORT=`cat qpidd.port` if test -d ${PYTHON_DIR} ; then ./header_test -p $QPID_PORT - export PYTHONPATH=$PYTHON_DIR:$PYTHONPATH + PYTHONPATH=$PYTHON_DIR:$PYTHONPATH + export PYTHONPATH $srcdir/header_test.py "localhost" $QPID_PORT else echo "Skipping header test as python libs not found" diff --git a/qpid/cpp/src/tests/sender.cpp b/qpid/cpp/src/tests/sender.cpp index 48062315fe..9d9e5be99d 100644 --- a/qpid/cpp/src/tests/sender.cpp +++ b/qpid/cpp/src/tests/sender.cpp @@ -24,6 +24,7 @@ #include <qpid/client/AsyncSession.h> #include <qpid/client/Message.h> #include <qpid/client/MessageReplayTracker.h> +#include <qpid/client/QueueOptions.h> #include <qpid/Exception.h> #include "TestOptions.h" @@ -40,13 +41,17 @@ struct Args : public qpid::TestOptions string destination; string key; uint sendEos; + bool durable; + string lvqMatchValue; - Args() : key("test-queue"), sendEos(0) + Args() : key("test-queue"), sendEos(0), durable(false) { - addOptions() + addOptions() ("exchange", qpid::optValue(destination, "EXCHANGE"), "Exchange to send messages to") ("routing-key", qpid::optValue(key, "KEY"), "Routing key to add to messages") - ("send-eos", qpid::optValue(sendEos, "N"), "Send N EOS messages to mark end of input"); + ("send-eos", qpid::optValue(sendEos, "N"), "Send N EOS messages to mark end of input") + ("durable", qpid::optValue(durable, "true|false"), "Mark messages as durable.") + ("lvq-match-value", qpid::optValue(lvqMatchValue, "KEY"), "The value to set for the LVQ match key property"); } }; @@ -55,7 +60,7 @@ const string EOS("eos"); class Sender : public FailoverManager::Command { public: - Sender(const std::string& destination, const std::string& key, uint sendEos); + Sender(const std::string& destination, const std::string& key, uint sendEos, bool durable, const std::string& lvqMatchValue); void execute(AsyncSession& session, bool isRetry); private: const std::string destination; @@ -65,8 +70,17 @@ class Sender : public FailoverManager::Command uint sent; }; -Sender::Sender(const std::string& dest, const std::string& key, uint eos) : - destination(dest), sender(10), message("", key), sendEos(eos), sent(0) {} +Sender::Sender(const std::string& dest, const std::string& key, uint eos, bool durable, const std::string& lvqMatchValue) : + destination(dest), sender(10), message("", key), sendEos(eos), sent(0) +{ + if (durable){ + message.getDeliveryProperties().setDeliveryMode(framing::PERSISTENT); + } + + if (!lvqMatchValue.empty()) { + message.getHeaders().setString(QueueOptions::strLVQMatchProperty, lvqMatchValue); + } +} void Sender::execute(AsyncSession& session, bool isRetry) { @@ -90,7 +104,7 @@ int main(int argc, char ** argv) try { opts.parse(argc, argv); FailoverManager connection(opts.con); - Sender sender(opts.destination, opts.key, opts.sendEos); + Sender sender(opts.destination, opts.key, opts.sendEos, opts.durable, opts.lvqMatchValue); connection.execute(sender); connection.close(); return 0; diff --git a/qpid/cpp/src/tests/sender.vcproj b/qpid/cpp/src/tests/sender.vcproj index 7ae9081332..616b665406 100644 --- a/qpid/cpp/src/tests/sender.vcproj +++ b/qpid/cpp/src/tests/sender.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="sender"
- ProjectGUID="{09714CB8-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{09714CB8-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="sender"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\sender\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\sender\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\sender\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\sender\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\sender\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\sender\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\sender\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\sender\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/shlibtest.vcproj b/qpid/cpp/src/tests/shlibtest.vcproj index b30ce30b3a..4a139a2cb5 100644 --- a/qpid/cpp/src/tests/shlibtest.vcproj +++ b/qpid/cpp/src/tests/shlibtest.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="shlibtest"
- ProjectGUID="{37AB26B9-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="shlibtest"
Keyword="Win32Proj"
SignManifests="true"
@@ -22,8 +22,8 @@ <Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\shlibtest\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\shlibtest\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -52,10 +52,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -74,8 +74,16 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtestsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\shlibtestd.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -96,8 +104,8 @@ <Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\shlibtest\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\shlibtest\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -126,8 +134,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -145,8 +153,18 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtests.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\shlibtest.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -167,8 +185,8 @@ <Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\shlibtest\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\shlibtest\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -197,10 +215,10 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -219,8 +237,17 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtestsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\shlibtestd.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -241,8 +268,8 @@ <Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\shlibtest\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\shlibtest\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -271,8 +298,8 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -290,8 +317,19 @@ Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtests.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\shlibtest.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -336,6 +374,9 @@ RelativePath="BrokerFixture.h">
</File>
<File
+ RelativePath="ClusterFixture.h">
+ </File>
+ <File
RelativePath="ConnectionOptions.h">
</File>
<File
diff --git a/qpid/cpp/src/tests/ssl_test b/qpid/cpp/src/tests/ssl_test index c7b59b62ef..13965f3a03 100755 --- a/qpid/cpp/src/tests/ssl_test +++ b/qpid/cpp/src/tests/ssl_test @@ -39,8 +39,7 @@ create_certs() { } start_broker() { - ../qpidd --daemon --transport ssl --port 0 --ssl-port 0 --no-data-dir --no-module-dir --auth no --config $CONFIG --load-module ../.libs/ssl.so --ssl-cert-db $CERT_DIR --ssl-cert-password-file $CERT_PW_FILE > qpidd.port - PORT=`cat qpidd.port` + PORT=`../qpidd --daemon --transport ssl --port 0 --ssl-port 0 --no-data-dir --no-module-dir --auth no --config $CONFIG --load-module ../.libs/ssl.so --ssl-cert-db $CERT_DIR --ssl-cert-password-file $CERT_PW_FILE` } stop_broker() { diff --git a/qpid/cpp/src/tests/start_cluster b/qpid/cpp/src/tests/start_cluster index 4f0516500c..053b23da33 100755 --- a/qpid/cpp/src/tests/start_cluster +++ b/qpid/cpp/src/tests/start_cluster @@ -28,11 +28,10 @@ with_ais_group() { echo $* | newgrp ais } -test -f cluster.ports && { echo "cluster.ports file already exists" ; exit 1; } rm -f cluster*.log SIZE=${1:-1}; shift CLUSTER=`pwd` # Cluster name=pwd, avoid clashes. -OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --no-data-dir --auth=no $*" +OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --no-data-dir --auth=no $@" for (( i=0; i<SIZE; ++i )); do PORT=`with_ais_group ../qpidd -p0 --log-to-file=cluster$i.log $OPTS` || exit 1 diff --git a/qpid/cpp/src/tests/tests.sln b/qpid/cpp/src/tests/tests.sln index cee1a45292..273e90d1c8 100644 --- a/qpid/cpp/src/tests/tests.sln +++ b/qpid/cpp/src/tests/tests.sln @@ -7,38 +7,38 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # this file will be lost the next time it is generated.
#
# MPC Command:
-# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 -static tests.mwc
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_test", "client_test.vcproj", "{9A95F0E4-FECA-1BAD-2235-047BCDC7409E}"
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 tests.mwc
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_test", "client_test.vcproj", "{9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "consume", "consume.vcproj", "{7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "consume", "consume.vcproj", "{7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echotest", "echotest.vcproj", "{0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echotest", "echotest.vcproj", "{0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "header_test", "header_test.vcproj", "{1B23F05D-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "header_test", "header_test.vcproj", "{1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "latencytest", "latencytest.vcproj", "{4A809018-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "latencytest", "latencytest.vcproj", "{4A809018-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perftest", "perftest.vcproj", "{1F2066BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perftest", "perftest.vcproj", "{1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "publish", "publish.vcproj", "{AE773E7F-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "publish", "publish.vcproj", "{AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "receiver", "receiver.vcproj", "{7D314A98-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "receiver", "receiver.vcproj", "{7D314A98-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sender", "sender.vcproj", "{09714CB8-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sender", "sender.vcproj", "{09714CB8-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shlibtest", "shlibtest.vcproj", "{37AB26B9-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shlibtest", "shlibtest.vcproj", "{37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_listener", "topic_listener.vcproj", "{9392D1EE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_listener", "topic_listener.vcproj", "{9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_publisher", "topic_publisher.vcproj", "{7D66FE10-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_publisher", "topic_publisher.vcproj", "{7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txjob", "txjob.vcproj", "{09034A53-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txjob", "txjob.vcproj", "{09034A53-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txshift", "txshift.vcproj", "{6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txshift", "txshift.vcproj", "{6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txtest", "txtest.vcproj", "{697786BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txtest", "txtest.vcproj", "{697786BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_test", "unit_test.vcproj", "{51E5F6B9-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_test", "unit_test.vcproj", "{51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -48,134 +48,134 @@ Global Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/src/tests/topic_listener.cpp b/qpid/cpp/src/tests/topic_listener.cpp index 7bdc2c32de..1f0b3f5377 100644 --- a/qpid/cpp/src/tests/topic_listener.cpp +++ b/qpid/cpp/src/tests/topic_listener.cpp @@ -37,6 +37,7 @@ #include "qpid/client/MessageListener.h" #include "qpid/client/Session.h" #include "qpid/client/SubscriptionManager.h" +#include "qpid/sys/SystemInfo.h" #include "qpid/sys/Time.h" #include "qpid/framing/FieldValue.h" #include <iostream> @@ -132,7 +133,7 @@ int main(int argc, char** argv){ if( args.statusqueue.length() > 0 ) { stringstream msg_str; - msg_str << "topic_listener: " << (int)getpid(); + msg_str << "topic_listener: " << qpid::sys::SystemInfo::getProcessId(); session.messageTransfer(arg::content=Message(msg_str.str(), args.statusqueue)); cout << "Ready status put on queue '" << args.statusqueue << "'" << endl; } diff --git a/qpid/cpp/src/tests/topic_listener.vcproj b/qpid/cpp/src/tests/topic_listener.vcproj index eedfe14687..0be31b8348 100644 --- a/qpid/cpp/src/tests/topic_listener.vcproj +++ b/qpid/cpp/src/tests/topic_listener.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="topic_listener"
- ProjectGUID="{9392D1EE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="topic_listener"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_listener\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_listener\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_listener\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_listener\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_listener\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_listener\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_listener\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_listener\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/topic_publisher.vcproj b/qpid/cpp/src/tests/topic_publisher.vcproj index a059adb398..016c6d4a38 100644 --- a/qpid/cpp/src/tests/topic_publisher.vcproj +++ b/qpid/cpp/src/tests/topic_publisher.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="topic_publisher"
- ProjectGUID="{7D66FE10-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="topic_publisher"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_publisher\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_publisher\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_publisher\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_publisher\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_publisher\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_publisher\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_publisher\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_publisher\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txjob.vcproj b/qpid/cpp/src/tests/txjob.vcproj index 69bdff2e8d..19fe3fba12 100644 --- a/qpid/cpp/src/tests/txjob.vcproj +++ b/qpid/cpp/src/tests/txjob.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="txjob"
- ProjectGUID="{09034A53-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{09034A53-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txjob"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txjob\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txjob\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txjob\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txjob\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txjob\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txjob\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txjob\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txjob\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txshift.cpp b/qpid/cpp/src/tests/txshift.cpp index 5db08d7a53..dd67710526 100644 --- a/qpid/cpp/src/tests/txshift.cpp +++ b/qpid/cpp/src/tests/txshift.cpp @@ -155,6 +155,7 @@ struct Worker : FailoverManager::Command, Runnable SubscriptionManager subs(session); transfer.subscribeToControl(subs); subs.run(); + session.txCommit();//commit accept of control messages } }; @@ -173,8 +174,8 @@ int main(int argc, char** argv) for (size_t i = 0; i < opts.workers; i++) { workers.push_back(new Worker(connection, opts.workQueue)); } - for_each(workers.begin(), workers.end(), boost::bind(&Worker::start, _1)); - for_each(workers.begin(), workers.end(), boost::bind(&Worker::join, _1)); + std::for_each(workers.begin(), workers.end(), boost::bind(&Worker::start, _1)); + std::for_each(workers.begin(), workers.end(), boost::bind(&Worker::join, _1)); } return 0; diff --git a/qpid/cpp/src/tests/txshift.vcproj b/qpid/cpp/src/tests/txshift.vcproj index aa7d6ca303..3212881351 100644 --- a/qpid/cpp/src/tests/txshift.vcproj +++ b/qpid/cpp/src/tests/txshift.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="txshift"
- ProjectGUID="{6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txshift"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txshift\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txshift\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txshift\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txshift\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txshift\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txshift\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txshift\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txshift\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txtest.vcproj b/qpid/cpp/src/tests/txtest.vcproj index a56e820dc0..663291a9d5 100644 --- a/qpid/cpp/src/tests/txtest.vcproj +++ b/qpid/cpp/src/tests/txtest.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="txtest"
- ProjectGUID="{697786BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{697786BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txtest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txtest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txtest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txtest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txtest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txtest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txtest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txtest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txtest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@ Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/unit_test.h b/qpid/cpp/src/tests/unit_test.h index df3ebfb1fe..fc542e62ad 100644 --- a/qpid/cpp/src/tests/unit_test.h +++ b/qpid/cpp/src/tests/unit_test.h @@ -61,7 +61,14 @@ namespace { struct test_name { void test_method(); }; } \ void test_name::test_method() -#endif // Workaround for BOOST_AUTO_TEST_SUITE_EXPECTED_FAILURES +#endif // Workaround for BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES + +// Correct syntax for boost > 1.36 +#if (BOOST_VERSION > 103500) +# define QPID_AUTO_TEST_CASE_EXPECTED_FAILURES(name,n) \ + BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(name,n) \ + BOOST_AUTO_TEST_CASE(name) +#endif // Correct syntax for boost > 1.36 // // Default definitions for latest version of boost. diff --git a/qpid/cpp/src/tests/unit_test.vcproj b/qpid/cpp/src/tests/unit_test.vcproj index ab6d13cd62..8710b617f8 100644 --- a/qpid/cpp/src/tests/unit_test.vcproj +++ b/qpid/cpp/src/tests/unit_test.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++"
Version="9.00"
Name="unit_test"
- ProjectGUID="{51E5F6B9-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="unit_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@ <Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\unit_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\unit_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -52,22 +52,22 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -76,7 +76,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qpidbrokerd.lib qmfconsoled.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@ </Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\unit_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\unit_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -134,19 +134,19 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -155,7 +155,7 @@ />
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qpidbroker.lib qmfconsole.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@ </Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\unit_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\unit_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -215,22 +215,22 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -240,7 +240,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qpidbrokerd.lib qmfconsoled.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@ </Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\unit_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\unit_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -298,19 +298,19 @@ Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -320,7 +320,7 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qpidbroker.lib qmfconsole.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -361,15 +361,33 @@ RelativePath="Array.cpp">
</File>
<File
+ RelativePath="AsyncCompletion.cpp">
+ </File>
+ <File
RelativePath="AtomicValue.cpp">
</File>
<File
RelativePath="Blob.cpp">
</File>
<File
+ RelativePath="ClientSessionTest.cpp">
+ </File>
+ <File
RelativePath="ConsoleTest.cpp">
</File>
<File
+ RelativePath="DeliveryRecordTest.cpp">
+ </File>
+ <File
+ RelativePath="DtxWorkRecordTest.cpp">
+ </File>
+ <File
+ RelativePath="exception_test.cpp">
+ </File>
+ <File
+ RelativePath="ExchangeTest.cpp">
+ </File>
+ <File
RelativePath="FieldTable.cpp">
</File>
<File
@@ -379,9 +397,15 @@ RelativePath="FramingTest.cpp">
</File>
<File
+ RelativePath="HeadersExchangeTest.cpp">
+ </File>
+ <File
RelativePath="HeaderTest.cpp">
</File>
<File
+ RelativePath="IncompleteMessageList.cpp">
+ </File>
+ <File
RelativePath="InlineAllocator.cpp">
</File>
<File
@@ -394,6 +418,15 @@ RelativePath="ManagementTest.cpp">
</File>
<File
+ RelativePath="MessageBuilderTest.cpp">
+ </File>
+ <File
+ RelativePath="MessageReplayTracker.cpp">
+ </File>
+ <File
+ RelativePath="MessageTest.cpp">
+ </File>
+ <File
RelativePath="ProxyTest.cpp">
</File>
<File
@@ -403,6 +436,15 @@ RelativePath="QueueOptionsTest.cpp">
</File>
<File
+ RelativePath="QueuePolicyTest.cpp">
+ </File>
+ <File
+ RelativePath="QueueRegistryTest.cpp">
+ </File>
+ <File
+ RelativePath="QueueTest.cpp">
+ </File>
+ <File
RelativePath="RangeSet.cpp">
</File>
<File
@@ -430,6 +472,18 @@ RelativePath="StringUtils.cpp">
</File>
<File
+ RelativePath="TimerTest.cpp">
+ </File>
+ <File
+ RelativePath="TopicExchangeTest.cpp">
+ </File>
+ <File
+ RelativePath="TxBufferTest.cpp">
+ </File>
+ <File
+ RelativePath="TxPublishTest.cpp">
+ </File>
+ <File
RelativePath="unit_test.cpp">
</File>
<File
diff --git a/qpid/cpp/xml/cluster.xml b/qpid/cpp/xml/cluster.xml index 2cf4e915b6..8fdde0ada6 100644 --- a/qpid/cpp/xml/cluster.xml +++ b/qpid/cpp/xml/cluster.xml @@ -125,13 +125,13 @@ <field name="member-id" type="uint64"/> <field name="connection-id" type="uint64"/> <field name="user-name" type="str8"/> + <field name="fragment" type="str32"/> </control> <!-- Complete a cluster state update. --> <control name="membership" code="0x21" label="Cluster membership details."> <field name="joiners" type="map"/> <!-- member-id -> URL --> <field name="members" type="map"/> <!-- member-id -> state --> - <field name="frame-id" type="uint64"/>> <!-- Frame id counter value --> </control> <!-- Set the position of a replicated queue. --> @@ -139,11 +139,12 @@ <field name="queue" type="str8"/> <field name="position" type="sequence-no"/> </control> - + <!-- Replicate encoded exchanges/queues. --> <control name="exchange" code="0x31"><field name="encoded" type="str32"/></control> <control name="queue" code="0x32"><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> </class> </amqp> diff --git a/qpid/dotnet/client-010/default.build b/qpid/dotnet/client-010/default.build index 75eadf0a0c..3a99354e56 100644 --- a/qpid/dotnet/client-010/default.build +++ b/qpid/dotnet/client-010/default.build @@ -30,7 +30,7 @@ <!-- Sets build properties consistently accross all assemblies in the project. --> <property name="build.version.major" value="0"/> - <property name="build.version.minor" value="10"/> + <property name="build.version.minor" value="5"/> <property name="build.version.build" value="0"/> <property name="build.version.revision" value="0"/> <property name="build.company" value="Apache Software Foundation"/> diff --git a/qpid/dotnet/default.build b/qpid/dotnet/default.build index b450c2481b..bfd6ada094 100644 --- a/qpid/dotnet/default.build +++ b/qpid/dotnet/default.build @@ -30,7 +30,7 @@ <!-- Sets build properties consistently accross all assemblies in the project. --> <property name="build.version.major" value="0"/> - <property name="build.version.minor" value="3"/> + <property name="build.version.minor" value="5"/> <property name="build.version.build" value="0"/> <property name="build.version.revision" value="0"/> <property name="build.company" value="Apache Software Foundation"/> diff --git a/qpid/java/010ExcludeList b/qpid/java/010ExcludeList index c2d254f3ce..3eab025053 100644 --- a/qpid/java/010ExcludeList +++ b/qpid/java/010ExcludeList @@ -58,3 +58,5 @@ org.apache.qpid.test.client.timeouts.SyncWaitTimeoutDelayTest#* org.apache.qpid.server.exchange.ReturnUnroutableMandatoryMessageTest#* org.apache.qpid.server.queue.PriorityTest#* org.apache.qpid.server.queue.TimeToLiveTest#* +// QPID-1727 , QPID-1726 :c++ broker does not support flow to disk on transient queues. Also it requries a persistent store impl. for Apache +org.apache.qpid.test.client.QueueBrowsingFlowToDiskTest#* diff --git a/qpid/java/08ExcludeList b/qpid/java/08ExcludeList index 88eb754950..1d8950dddf 100644 --- a/qpid/java/08ExcludeList +++ b/qpid/java/08ExcludeList @@ -6,3 +6,4 @@ org.apache.qpid.test.testcases.FailoverTest#* org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover // Those tests are written against the 0.10 path org.apache.qpid.test.unit.message.UTF8Test#* +org.apache.qpid.client.MessageListenerTest#testSynchronousRecieveNoWait diff --git a/qpid/java/08ExcludeList-nonvm b/qpid/java/08ExcludeList-nonvm index eb6c60b225..546dc01f5b 100644 --- a/qpid/java/08ExcludeList-nonvm +++ b/qpid/java/08ExcludeList-nonvm @@ -27,3 +27,4 @@ org.apache.qpid.server.security.acl.SimpleACLTest#* // Those tests are written against the 0.10 path org.apache.qpid.test.unit.message.UTF8Test#* +org.apache.qpid.client.MessageListenerTest#testSynchronousRecieveNoWait diff --git a/qpid/java/ExcludeList b/qpid/java/ExcludeList index 509f74bbbd..5566c0eb9f 100644 --- a/qpid/java/ExcludeList +++ b/qpid/java/ExcludeList @@ -1,8 +1,6 @@ org.apache.qpid.client.MultipleJCAProviderRegistrationTest#test -// QPID-1451 : testBrowsingWithSelector test is not correct. -org.apache.qpid.test.client.QueueBrowserAutoAckTest#testBrowsingWithSelector -org.apache.qpid.test.client.QueueBrowserClientAckTest#testBrowsingWithSelector -org.apache.qpid.test.client.QueueBrowserDupsOkTest#testBrowsingWithSelector -org.apache.qpid.test.client.QueueBrowserNoAckTest#testBrowsingWithSelector -org.apache.qpid.test.client.QueueBrowserPreAckTest#testBrowsingWithSelector -org.apache.qpid.test.client.QueueBrowserTransactedTest#testBrowsingWithSelector +// QPID-1715, QPID-1715 : Client Error Handling on close is still broken +org.apache.qpid.server.queue.QueueCreateTest#testCreatePriorityString +org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskValidNoSize +org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskInvalid +org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskInvalidSize diff --git a/qpid/java/broker/bin/create-example-ssl-stores.bat b/qpid/java/broker/bin/create-example-ssl-stores.bat new file mode 100644 index 0000000000..5419c098d5 --- /dev/null +++ b/qpid/java/broker/bin/create-example-ssl-stores.bat @@ -0,0 +1,36 @@ +@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM
+
+@REM Create example keystore for broker and trust store for client/management console.
+@REM
+@REM Use generated qpid.keystore as the brokers keystore
+@REM Use generated qpid.truststore as client/consoles truststore
+@REM All passwords have value: password
+
+@REM Create Broker Keystore:
+keytool -genkey -alias qpidBroker -keyalg RSA -validity 365 -keystore qpid.keystore -storepass password -keypass password -dname "CN=hostname, OU=OrgUnit, O=Org, L=City, C=US"
+
+@REM Export Self Signed Cert:
+keytool -export -alias qpidBroker -keystore qpid.keystore -file qpidBroker.cer -storepass password
+
+@REM Import Broker Cert Into MC TrustStore:
+keytool -import -alias qpidBrokerCert -file qpidBroker.cer -keystore qpid.truststore -storepass password -noprompt
+
+@REM Delete the cert
+del qpidBroker.cer
\ No newline at end of file diff --git a/qpid/java/broker/bin/create-example-ssl-stores.sh b/qpid/java/broker/bin/create-example-ssl-stores.sh new file mode 100644 index 0000000000..bfcb3dfecf --- /dev/null +++ b/qpid/java/broker/bin/create-example-ssl-stores.sh @@ -0,0 +1,38 @@ +#!/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. +# + +# Create example keystore for broker and trust store for client/management console. +# +# Use generated qpid.keystore as the brokers keystore +# Use generated qpid.truststore as client/consoles truststore +# All passwords have value: password + +#Create Broker Keystore: +keytool -genkey -alias qpidBroker -keyalg RSA -validity 365 -keystore qpid.keystore \ +-storepass password -keypass password -dname "CN=hostname, OU=OrgUnit, O=Org, L=City, C=US" + +#Export Self Signed Cert: +keytool -export -alias qpidBroker -keystore qpid.keystore -file qpidBroker.cer -storepass password + +#Import Broker Cert Into MC TrustStore: +keytool -import -alias qpidBrokerCert -file qpidBroker.cer -keystore qpid.truststore -storepass password -noprompt + +#Delete the cert +rm qpidBroker.cer diff --git a/qpid/java/broker/etc/config.xml b/qpid/java/broker/etc/config.xml index b2b3625cca..e0045c1e74 100644 --- a/qpid/java/broker/etc/config.xml +++ b/qpid/java/broker/etc/config.xml @@ -45,7 +45,6 @@ <management> <enabled>true</enabled> <jmxport>8999</jmxport> - <security-enabled>false</security-enabled> <ssl> <enabled>true</enabled> <!-- Update below path to your keystore location, eg ${conf}/qpid.keystore --> diff --git a/qpid/java/broker/etc/debug.log4j.xml b/qpid/java/broker/etc/debug.log4j.xml index 71f9502b75..fc0bd9f34f 100644 --- a/qpid/java/broker/etc/debug.log4j.xml +++ b/qpid/java/broker/etc/debug.log4j.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8"?> <!-- - - Licensed to the Apache Software Foundation (ASF) under one @@ -18,10 +18,10 @@ - specific language governing permissions and limitations - under the License. - - --> -<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> -<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> - <appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender"> + --><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null"> + <appender class="org.apache.log4j.QpidCompositeRollingAppender" name="ArchivingFileAppender"> <!-- Ensure that logs allways have the dateFormat set--> <param name="StaticLogFileName" value="false"/> <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> @@ -48,7 +48,7 @@ </layout> </appender> - <appender name="FileAppender" class="org.apache.log4j.FileAppender"> + <appender class="org.apache.log4j.FileAppender" name="FileAppender"> <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> <param name="Append" value="false"/> @@ -57,7 +57,7 @@ </layout> </appender> - <appender name="AlertFile" class="org.apache.log4j.FileAppender"> + <appender class="org.apache.log4j.FileAppender" name="AlertFile"> <param name="File" value="${QPID_WORK}/log/alert.log"/> <param name="Append" value="false"/> @@ -66,28 +66,28 @@ </layout> </appender> - <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> + <appender class="org.apache.log4j.ConsoleAppender" name="STDOUT"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> </layout> </appender> - <category name="Qpid.Broker"> + <category additivity="true" name="Qpid.Broker"> <priority value="debug"/> <appender-ref ref="AlertFile"/> <!--appender-ref ref="STDOUT"/--> </category> - <category name="org.apache.qpid.server.queue.AMQQueueMBean"> + <category additivity="true" name="org.apache.qpid.server.queue.AMQQueueMBean"> <priority value="info"/> <appender-ref ref="AlertFile"/> </category> <!-- Provide warnings to standard output --> - <!--category name="org.apache.qpid"> + <!--category additivity="true" name="org.apache.qpid"> <priority value="warn"/> <appender-ref ref="STDOUT"/> </category--> @@ -96,11 +96,11 @@ <!-- Additional level settings for debugging --> <!-- Each class in the Broker is a category that can have its logging level adjusted. --> <!-- This will provide more details if available about that classes processing. --> - <!--category name="org.apache.qpid.server.txn"> + <!--category additivity="true" name="org.apache.qpid.server.txn"> <priority value="debug"/> </category>--> - <!--<category name="org.apache.qpid.server.store"> + <!--<category additivity="true" name="org.apache.qpid.server.store"> <priority value="debug"/> </category--> diff --git a/qpid/java/broker/etc/log4j.xml b/qpid/java/broker/etc/log4j.xml index eff5d17588..a395d0fd56 100644 --- a/qpid/java/broker/etc/log4j.xml +++ b/qpid/java/broker/etc/log4j.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8"?> <!-- - - Licensed to the Apache Software Foundation (ASF) under one @@ -18,10 +18,10 @@ - specific language governing permissions and limitations - under the License. - - --> -<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> -<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> - <appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender"> + --><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null"> + <appender class="org.apache.log4j.QpidCompositeRollingAppender" name="ArchivingFileAppender"> <!-- Ensure that logs allways have the dateFormat set--> <param name="StaticLogFileName" value="false"/> <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> @@ -48,7 +48,7 @@ </layout> </appender> - <appender name="FileAppender" class="org.apache.log4j.FileAppender"> + <appender class="org.apache.log4j.FileAppender" name="FileAppender"> <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/> <param name="Append" value="false"/> @@ -57,25 +57,25 @@ </layout> </appender> - <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> + <appender class="org.apache.log4j.ConsoleAppender" name="STDOUT"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/> </layout> </appender> - <!-- Qpid.Broker log is a special log category used to only useful broker startup details --> - <category name="Qpid.Broker"> + <!-- Qpid.Broker log is a special log category used to log only useful broker startup details --> + <category additivity="true" name="Qpid.Broker"> <priority value="debug"/> <appender-ref ref="STDOUT"/> </category> - <category name="org.apache.qpid.server.queue.AMQQueueMBean"> + <category additivity="true" name="org.apache.qpid.server.queue.AMQQueueMBean"> <priority value="info"/> </category> <!-- Provide warnings to standard output --> - <category name="org.apache.qpid"> + <category additivity="true" name="org.apache.qpid"> <priority value="warn"/> </category> @@ -83,7 +83,7 @@ <!-- Examples of additional logging settings --> <!-- Used to generate extra debug. See debug.log4j.xml --> - <!--<category name="org.apache.qpid.server.store"> + <!--<category additivity="true" name="org.apache.qpid.server.store"> <priority value="debug"/> </category--> diff --git a/qpid/java/broker/etc/persistent_config.xml b/qpid/java/broker/etc/persistent_config.xml index ed2c2cab1f..67ef28117d 100644 --- a/qpid/java/broker/etc/persistent_config.xml +++ b/qpid/java/broker/etc/persistent_config.xml @@ -37,7 +37,6 @@ <management> <enabled>true</enabled> <jmxport>8999</jmxport> - <security-enabled>false</security-enabled> <ssl> <enabled>true</enabled> <!-- Update below path to your keystore location, eg ${conf}/qpid.keystore --> diff --git a/qpid/java/broker/etc/transient_config.xml b/qpid/java/broker/etc/transient_config.xml index 19ffeb9720..a21afe7d21 100644 --- a/qpid/java/broker/etc/transient_config.xml +++ b/qpid/java/broker/etc/transient_config.xml @@ -37,7 +37,6 @@ <management> <enabled>true</enabled> <jmxport>8999</jmxport> - <security-enabled>false</security-enabled> <ssl> <enabled>true</enabled> <!-- Update below path to your keystore location, eg ${conf}/qpid.keystore --> diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java index b3c843ebaa..22bdae8267 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java @@ -52,9 +52,9 @@ import org.apache.qpid.server.management.MBeanConstructor; import org.apache.qpid.server.management.MBeanDescription; import org.apache.qpid.server.management.ManagedBroker; import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.transactionlog.TransactionLog; import org.apache.qpid.server.routing.RoutingTable; @@ -77,7 +77,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr @MBeanConstructor("Creates the Broker Manager MBean") public AMQBrokerManagerMBean(VirtualHost.VirtualHostMBean virtualHostMBean) throws JMException { - super(ManagedBroker.class, ManagedBroker.TYPE); + super(ManagedBroker.class, ManagedBroker.TYPE, ManagedBroker.VERSION); _virtualHostMBean = virtualHostMBean; VirtualHost virtualHost = virtualHostMBean.getVirtualHost(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index 2d0589c223..72a2780c32 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -20,6 +20,14 @@ */ package org.apache.qpid.server; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; @@ -29,12 +37,12 @@ import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.ack.UnacknowledgedMessageMap; import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl; -import org.apache.qpid.server.configuration.Configurator; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.NoRouteException; import org.apache.qpid.server.flow.FlowCreditManager; import org.apache.qpid.server.flow.Pre0_10CreditManager; import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.IncomingMessage; import org.apache.qpid.server.queue.QueueEntry; @@ -45,19 +53,15 @@ import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.RecordDeliveryMethod; import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.subscription.ClientDeliveryMethod; +import org.apache.qpid.server.subscription.RecordDeliveryMethod; +import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.txn.LocalTransactionalContext; import org.apache.qpid.server.txn.NonTransactionalContext; import org.apache.qpid.server.txn.TransactionalContext; import org.apache.qpid.server.transactionlog.TransactionLog; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.concurrent.atomic.AtomicBoolean; - public class AMQChannel { public static final int DEFAULT_PREFETCH = 5000; @@ -114,9 +118,6 @@ public class AMQChannel public AMQChannel(AMQProtocolSession session, int channelId, TransactionLog transactionLog) throws AMQException { - //Set values from configuration - Configurator.configure(this); - _session = session; _channelId = channelId; _storeContext = new StoreContext("Session: " + session.getClientIdentifier() + "; channel: " + channelId); @@ -250,7 +251,6 @@ public class AMQChannel } catch (NoRouteException e) { - //_currentMessage.incrementReference(); _returnMessages.add(e); } } @@ -431,7 +431,7 @@ public class AMQChannel { if (_log.isDebugEnabled()) { - _log.debug(debugIdentity() + " Adding unacked message(" + entry.getMessage().toString() + " DT:" + deliveryTag + _log.debug(debugIdentity() + " Adding unacked message(" + entry.toString() + " DT:" + deliveryTag + ") with a queue(" + entry.getQueue() + ") for " + subscription); } } @@ -498,7 +498,7 @@ public class AMQChannel } else { - unacked.discard(_storeContext); + unacked.dequeueAndDelete(_storeContext); } } @@ -551,10 +551,10 @@ public class AMQChannel } else { - _log.warn(System.identityHashCode(this) + " Requested requeue of message(" + unacked.getMessage().debugIdentity() + _log.warn(System.identityHashCode(this) + " Requested requeue of message(" + unacked.debugIdentity() + "):" + deliveryTag + " but no queue defined and no DeadLetter queue so DROPPING message."); - unacked.discard(_storeContext); + unacked.dequeueAndDelete(_storeContext); } } else @@ -711,7 +711,7 @@ public class AMQChannel { try { - message.discard(_storeContext); + message.dequeueAndDelete(_storeContext); message.setQueueDeleted(true); } @@ -830,9 +830,7 @@ public class AMQChannel { AMQMessage message = bouncedMessage.getAMQMessage(); _session.getProtocolOutputConverter().writeReturn(message, _channelId, bouncedMessage.getReplyCode().getCode(), - new AMQShortString(bouncedMessage.getMessage())); - - message.decrementReference(_storeContext); + new AMQShortString(bouncedMessage.getMessage())); } _returnMessages.clear(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java index 1723d46ef0..8d41cc58d2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java @@ -82,13 +82,13 @@ public class ExtractResendAndRequeue implements UnacknowledgedMessageMap.Visitor } else { - queueEntry.discard(_storeContext); + queueEntry.dequeueAndDelete(_storeContext); _log.info("No DeadLetter Queue and requeue not requested so dropping message:" + queueEntry); } } else { - queueEntry.discard(_storeContext); + queueEntry.dequeueAndDelete(_storeContext); _log.warn("Message.queue is null and no DeadLetter Queue so dropping message:" + queueEntry); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java index f3b54034e7..49619ac5b0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -20,6 +20,14 @@ */ package org.apache.qpid.server; +import java.io.File; +import java.io.IOException; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import javax.management.NotCompliantMBeanException; + import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; @@ -27,36 +35,26 @@ import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; import org.apache.mina.common.ByteBuffer; -import org.apache.mina.common.IoAcceptor; import org.apache.mina.common.FixedSizeByteBufferAllocator; +import org.apache.mina.common.IoAcceptor; import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; import org.apache.mina.transport.socket.nio.SocketSessionConfig; +import org.apache.mina.util.NewThreadExecutor; import org.apache.qpid.AMQException; import org.apache.qpid.common.QpidProperties; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.pool.ReadWriteThreadModel; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; -import org.apache.qpid.server.management.JMXManagedObjectRegistry; +import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean; +import org.apache.qpid.server.logging.management.LoggingManagementMBean; import org.apache.qpid.server.protocol.AMQPFastProtocolHandler; import org.apache.qpid.server.protocol.AMQPProtocolProvider; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; -import org.apache.qpid.server.transport.ConnectorConfiguration; -import org.apache.qpid.url.URLSyntaxException; - -import java.io.File; -import java.io.IOException; -import java.net.BindException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.List; /** * Main entry point for AMQPD. @@ -200,13 +198,6 @@ public class Main _brokerLogger.error("Initialisation Error : " + e.getMessage()); shutdown(1); } - catch (ConfigurationException e) - { - System.out.println("Error configuring message broker: " + e); - _brokerLogger.error("Error configuring message broker: " + e); - e.printStackTrace(); - shutdown(1); - } catch (Throwable e) { System.out.println("Error initialising message broker: " + e); @@ -223,7 +214,7 @@ public class Main System.exit(status); } - protected void startup() throws InitException, ConfigurationException, Exception + protected void startup() throws Exception { final String QpidHome = System.getProperty(QPID_HOME); final File defaultConfigFile = new File(QpidHome, DEFAULT_CONFIG_FILE); @@ -246,53 +237,63 @@ public class Main String logConfig = commandLine.getOptionValue("l"); String logWatchConfig = commandLine.getOptionValue("w", "0"); + + int logWatchTime = 0; + try + { + logWatchTime = Integer.parseInt(logWatchConfig); + } + catch (NumberFormatException e) + { + System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " + + "a non-negative integer. Using default of zero (no watching configured"); + } + + File logConfigFile; if (logConfig != null) { - File logConfigFile = new File(logConfig); - configureLogging(logConfigFile, logWatchConfig); + logConfigFile = new File(logConfig); + configureLogging(logConfigFile, logWatchTime); } else { File configFileDirectory = configFile.getParentFile(); - File logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME); - configureLogging(logConfigFile, logWatchConfig); + logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME); + configureLogging(logConfigFile, logWatchTime); } ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile); - - - updateManagementPort(config.getConfiguration(), commandLine.getOptionValue("m")); - - + ServerConfiguration serverConfig = config.getConfiguration(); + updateManagementPort(serverConfig, commandLine.getOptionValue("m")); ApplicationRegistry.initialise(config); + + configureLoggingManagementMBean(logConfigFile, logWatchTime); - + ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean(); + configMBean.register(); + //fixme .. use QpidProperties.getVersionString when we have fixed the classpath issues // that are causing the broker build to pick up the wrong properties file and hence say // Starting Qpid Client _brokerLogger.info("Starting Qpid Broker " + QpidProperties.getReleaseVersion() + " build: " + QpidProperties.getBuildVersion()); - ConnectorConfiguration connectorConfig = - ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class); - - ByteBuffer.setUseDirectBuffers(connectorConfig.enableDirectBuffers); + ByteBuffer.setUseDirectBuffers(serverConfig.getEnableDirectBuffers()); // the MINA default is currently to use the pooled allocator although this may change in future // once more testing of the performance of the simple allocator has been done - if (!connectorConfig.enablePooledAllocator) + if (!serverConfig.getEnablePooledAllocator()) { ByteBuffer.setAllocator(new FixedSizeByteBufferAllocator()); } - - if(connectorConfig.useBiasedWrites) + if(serverConfig.getUseBiasedWrites()) { System.setProperty("org.apache.qpid.use_write_biased_pool","true"); } - int port = connectorConfig.port; + int port = serverConfig.getPort(); String portStr = commandLine.getOptionValue("p"); if (portStr != null) @@ -306,29 +307,8 @@ public class Main throw new InitException("Invalid port: " + portStr, e); } } - - String VIRTUAL_HOSTS = "virtualhosts"; - - Object virtualHosts = ApplicationRegistry.getInstance().getConfiguration().getProperty(VIRTUAL_HOSTS); - - if (virtualHosts != null) - { - if (virtualHosts instanceof Collection) - { - int totalVHosts = ((Collection) virtualHosts).size(); - for (int vhost = 0; vhost < totalVHosts; vhost++) - { - setupVirtualHosts(configFile.getParent(), (String) ((List) virtualHosts).get(vhost)); - } - } - else - { - setupVirtualHosts(configFile.getParent(), (String) virtualHosts); - } - } - - bind(port, connectorConfig); - + + bind(port, serverConfig); } /** @@ -336,86 +316,59 @@ public class Main * @param configuration * @param managementPort The string from the command line */ - private void updateManagementPort(Configuration configuration, String managementPort) + private void updateManagementPort(ServerConfiguration configuration, String managementPort) { if (managementPort != null) { - int mport; - int defaultMPort = configuration.getInt(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH); try { - mport = Integer.parseInt(managementPort); - configuration.setProperty(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH, mport); + configuration.setJMXManagementPort(Integer.parseInt(managementPort)); } catch (NumberFormatException e) { - _logger.warn("Invalid management port: " + managementPort + " will use default:" + defaultMPort, e); - } - } - } - - protected void setupVirtualHosts(String configFileParent, String configFilePath) - throws ConfigurationException, AMQException, URLSyntaxException - { - String configVar = "${conf}"; - - if (configFilePath.startsWith(configVar)) - { - configFilePath = configFileParent + configFilePath.substring(configVar.length()); - } - - if (configFilePath.indexOf(".xml") != -1) - { - VirtualHostConfiguration vHostConfig = new VirtualHostConfiguration(configFilePath); - vHostConfig.performBindings(); - } - else - { - // the virtualhosts value is a path. Search it for XML files. - - File virtualHostDir = new File(configFilePath); - - String[] fileNames = virtualHostDir.list(); - - for (int each = 0; each < fileNames.length; each++) - { - if (fileNames[each].endsWith(".xml")) - { - VirtualHostConfiguration vHostConfig = - new VirtualHostConfiguration(configFilePath + "/" + fileNames[each]); - vHostConfig.performBindings(); - } + _logger.warn("Invalid management port: " + managementPort + " will use:" + configuration.getJMXManagementPort(), e); } } } - protected void bind(int port, ConnectorConfiguration connectorConfig) throws BindException + protected void bind(int port, ServerConfiguration config) throws BindException { String bindAddr = commandLine.getOptionValue("b"); if (bindAddr == null) { - bindAddr = connectorConfig.bindAddress; + bindAddr = config.getBind(); } try { - // IoAcceptor acceptor = new SocketAcceptor(connectorConfig.processors); - IoAcceptor acceptor = connectorConfig.createAcceptor(); + IoAcceptor acceptor; + + if (ApplicationRegistry.getInstance().getConfiguration().getQpidNIO()) + { + _logger.warn("Using Qpid Multithreaded IO Processing"); + acceptor = new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor(config.getProcessors(), new NewThreadExecutor()); + } + else + { + _logger.warn("Using Mina IO Processing"); + acceptor = new org.apache.mina.transport.socket.nio.SocketAcceptor(config.getProcessors(), new NewThreadExecutor()); + } + SocketAcceptorConfig sconfig = (SocketAcceptorConfig) acceptor.getDefaultConfig(); SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig(); - sc.setReceiveBufferSize(connectorConfig.socketReceiveBufferSize); - sc.setSendBufferSize(connectorConfig.socketWriteBuferSize); - sc.setTcpNoDelay(connectorConfig.tcpNoDelay); + sc.setReceiveBufferSize(config.getReceiveBufferSize()); + sc.setSendBufferSize(config.getWriteBufferSize()); + sc.setTcpNoDelay(config.getTcpNoDelay()); // if we do not use the executor pool threading model we get the default leader follower // implementation provided by MINA - if (connectorConfig.enableExecutorPool) + if (config.getEnableExecutorPool()) { sconfig.setThreadModel(ReadWriteThreadModel.getInstance()); } - if (!connectorConfig.enableSSL || !connectorConfig.sslOnly) + if (!config.getEnableSSL() || !config.getSSLOnly()) { AMQPFastProtocolHandler handler = new AMQPProtocolProvider().getHandler(); InetSocketAddress bindAddress; @@ -434,16 +387,16 @@ public class Main _brokerLogger.info("Qpid.AMQP listening on non-SSL address " + bindAddress); } - if (connectorConfig.enableSSL) + if (config.getEnableSSL()) { AMQPFastProtocolHandler handler = new AMQPProtocolProvider().getHandler(); try { - bind(acceptor, new InetSocketAddress(connectorConfig.sslPort), handler, sconfig); + bind(acceptor, new InetSocketAddress(config.getSSLPort()), handler, sconfig); //fixme qpid.AMQP should be using qpidproperties to get value - _brokerLogger.info("Qpid.AMQP listening on SSL port " + connectorConfig.sslPort); + _brokerLogger.info("Qpid.AMQP listening on SSL port " + config.getSSLPort()); } catch (IOException e) @@ -515,19 +468,8 @@ public class Main return ip; } - private void configureLogging(File logConfigFile, String logWatchConfig) + private void configureLogging(File logConfigFile, int logWatchTime) { - int logWatchTime = 0; - try - { - logWatchTime = Integer.parseInt(logWatchConfig); - } - catch (NumberFormatException e) - { - System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " - + "a non-negative integer. Using default of zero (no watching configured"); - } - if (logConfigFile.exists() && logConfigFile.canRead()) { System.out.println("Configuring logger using configuration file " + logConfigFile.getAbsolutePath()); @@ -551,4 +493,17 @@ public class Main } } + private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception + { + LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime); + + try + { + blm.register(); + } + catch (AMQException e) + { + throw new InitException("Unable to initialise the Logging Management MBean: ", e); + } + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java index 3f1947d65a..a81b2cc2db 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java @@ -56,13 +56,10 @@ public abstract class RequiredDeliveryException extends AMQException public void setMessage(final AMQMessage payload) { - - // Increment the reference as this message is in the routing phase - // and so will have the ref decremented as routing fails. // we need to keep this message around so we can return it in the - // handler. So increment here. - _amqMessage = payload.takeReference(); - + // handler. + // Messages are all kept in memory now. Only queues can push messages out of memory. + _amqMessage = payload; } public AMQMessage getAMQMessage() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java index db3a05eb52..95de0dc8c3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.ack; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.HashMap; @@ -103,7 +102,7 @@ public class TxAck implements TxnOp //buffer must be marked as persistent: for (QueueEntry msg : _unacked.values()) { - if (msg.getMessage().isPersistent()) + if (msg.isPersistent()) { return true; } @@ -116,22 +115,20 @@ public class TxAck implements TxnOp //make persistent changes, i.e. dequeue and decrementReference for (QueueEntry msg : _unacked.values()) { - //Message has been ack so discard it. This will dequeue and decrement the reference. - msg.discard(storeContext); - + //Message has been ack so dequeueAndDelete it. + // If the message is persistent and this is the last QueueEntry that uses it then the data will be removed + // from the transaciton log + msg.dequeueAndDelete(storeContext); } } public void undoPrepare() { - //decrementReference is annoyingly untransactional (due to - //in memory counter) so if we failed in prepare for full - //txn, this op will have to compensate by fixing the count - //in memory (persistent changes will be rolled back by store) - for (QueueEntry msg : _unacked.values()) - { - msg.getMessage().takeReference(); - } + //As this is transaction the above dequeueAndDelete will only request the message be dequeue from the + // transactionLog. Only when the transaction succesfully completes will it perform any + // update of the internal transactionLog reference counting and any resulting message data deletion. + // The success or failure of the data deletion is not important to this transaction only that the ack has been + // successfully recorded. } public void commit(StoreContext storeContext) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java index efdadd4922..5c38185696 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java @@ -89,7 +89,7 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap QueueEntry message = _map.remove(deliveryTag); if(message != null) { - _unackedSize -= message.getMessage().getSize(); + _unackedSize -= message.getSize(); } @@ -115,7 +115,7 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap synchronized (_lock) { _map.put(deliveryTag, message); - _unackedSize += message.getMessage().getSize(); + _unackedSize += message.getSize(); _lastDeliveryTag = deliveryTag; } } @@ -174,12 +174,14 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap " When deliveryTag is:" + deliveryTag + "ES:" + _map.entrySet().toString()); } - //Message has been ack so discard it. This will dequeue and decrement the reference. - unacked.getValue().discard(storeContext); + //Message has been ack so dequeueAndDelete it. + // If the message is persistent and this is the last QueueEntry that uses it then the data will be removed + // from the transaciton log + unacked.getValue().dequeueAndDelete(storeContext); it.remove(); - _unackedSize -= unacked.getValue().getMessage().getSize(); + _unackedSize -= unacked.getValue().getSize(); if (unacked.getKey() == deliveryTag) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java deleted file mode 100644 index 31c1b61a21..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration; - -import java.lang.reflect.Field; - -import org.apache.commons.configuration.Configuration; -import org.apache.log4j.Logger; -import org.apache.qpid.configuration.Configured; -import org.apache.qpid.configuration.PropertyException; -import org.apache.qpid.configuration.PropertyUtils; -import org.apache.qpid.server.registry.ApplicationRegistry; - -/** - * This class contains utilities for populating classes automatically from values pulled from configuration - * files. - */ -public class Configurator -{ - private static final Logger _logger = Logger.getLogger(Configurator.class); - - - /** - * Configure a given instance using the supplied configuration. Note that superclasses are <b>not</b> - * currently configured but this could easily be added if required. - * @param instance the instance to configure - * @param config the configuration to use to configure the object - */ - public static void configure(Object instance, Configuration config) - { - - for (Field f : instance.getClass().getDeclaredFields()) - { - Configured annotation = f.getAnnotation(Configured.class); - if (annotation != null) - { - setValueInField(f, instance, config, annotation); - } - } - } - - - - /** - * Configure a given instance using the application configuration. Note that superclasses are <b>not</b> - * currently configured but this could easily be added if required. - * @param instance the instance to configure - */ - public static void configure(Object instance) - { - configure(instance, ApplicationRegistry.getInstance().getConfiguration()); - } - - private static void setValueInField(Field f, Object instance, Configuration config, Configured annotation) - { - Class fieldClass = f.getType(); - String configPath = annotation.path(); - try - { - if (fieldClass == String.class) - { - String val = config.getString(configPath, annotation.defaultValue()); - val = PropertyUtils.replaceProperties(val); - f.set(instance, val); - } - else if (fieldClass == int.class) - { - int val = config.getInt(configPath, Integer.parseInt(annotation.defaultValue())); - f.setInt(instance, val); - } - else if (fieldClass == long.class) - { - long val = config.getLong(configPath, Long.parseLong(annotation.defaultValue())); - f.setLong(instance, val); - } - else if (fieldClass == double.class) - { - double val = config.getDouble(configPath, Double.parseDouble(annotation.defaultValue())); - f.setDouble(instance, val); - } - else if (fieldClass == boolean.class) - { - boolean val = config.getBoolean(configPath, Boolean.parseBoolean(annotation.defaultValue())); - f.setBoolean(instance, val); - } - else - { - _logger.error("Unsupported field type " + fieldClass + " for " + f + " IGNORING configured value"); - } - } - catch (PropertyException e) - { - _logger.error("Unable to expand property: " + e + " INGORING field " + f, e); - } - catch (IllegalAccessException e) - { - _logger.error("Unable to access field " + f + " IGNORING configured value"); - } - } -} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfiguration.java index 4e48435962..c7cf0c0892 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfiguration.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,34 +18,41 @@ * under the License. * */ -package org.apache.qpid.server.store; +package org.apache.qpid.server.configuration; -import org.apache.qpid.server.queue.MessageMetaData; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.commons.configuration.Configuration; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.List; -/** - * Adds some extra methods to the memory message store for testing purposes. - */ -public class TestMemoryMessageStore extends MemoryMessageStore +public class ExchangeConfiguration { - public TestMemoryMessageStore() + + private Configuration _config; + private String _name; + + public ExchangeConfiguration(String exchName, Configuration subset) + { + _name = exchName; + _config = subset; + } + + public String getName() + { + return _name; + } + + public String getType() { - _metaDataMap = new ConcurrentHashMap<Long, MessageMetaData>(); - _contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>(); + return _config.getString("type","direct"); } - public ConcurrentMap<Long, MessageMetaData> getMessageMetaDataMap() + public boolean getDurable() { - return _metaDataMap; + return _config.getBoolean("durable", false); } - public ConcurrentMap<Long, List<ContentChunk>> getContentBodyMap() + public boolean getAutoDelete() { - return _contentBodyMap; + return _config.getBoolean("autodelete",false); } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java new file mode 100644 index 0000000000..e6c5dee90d --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.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.configuration; + +import java.util.List; +import java.io.File; + +import org.apache.commons.configuration.Configuration; +import org.apache.qpid.server.registry.ApplicationRegistry; + +public class QueueConfiguration +{ + + // FIXME AIDAN XXX -- deal with defaults + + private Configuration _config; + private String _name; + private VirtualHostConfiguration _virtualHostConfiguration; + + public QueueConfiguration(String name, Configuration config, VirtualHostConfiguration virtualHostConfiguration) + { + _virtualHostConfiguration = virtualHostConfiguration; + _config = config; + _name = name; + } + + public VirtualHostConfiguration getVirtualHostConfiguration() + { + return _virtualHostConfiguration; + } + + public boolean getDurable() + { + return _config.getBoolean("durable" ,false); + } + + public boolean getAutoDelete() + { + return _config.getBoolean("autodelete", false); + } + + public String getOwner() + { + return _config.getString("owner", null); + } + + public boolean getPriority() + { + return _config.getBoolean("priority", false); + } + + public int getPriorities() + { + return _config.getInt("priorities", -1); + } + + public String getExchange() + { + return _config.getString("exchange", null); + } + + public List getRoutingKeys() + { + return _config.getList("routingKey"); + } + + public String getName() + { + return _name; + } + + public long getMaximumMessageAge() + { + return _config.getLong("maximumMessageAge", 0); + } + + public long getMaximumQueueDepth() + { + return _config.getLong("maximumQueueDepth", 0); + } + + public long getMaximumMessageSize() + { + return _config.getLong("maximumMessageSize", 0); + } + + public long getMaximumMessageCount() + { + return _config.getLong("maximumMessageCount", 0); + } + + public long getMinimumAlertRepeatGap() + { + return _config.getLong("minimumAlertRepeatGap", 0); + } + + public long getMemoryUsageMaximum() + { + return _config.getLong("maximumMemoryUsage", 100 * 1024 * 1024); //100Meg + } + + public long getMemoryUsageMinimum() + { + return _config.getLong("minimumMemoryUsage", 0); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java new file mode 100644 index 0000000000..5d080f8df1 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + */ + +package org.apache.qpid.server.configuration; + +import org.apache.commons.configuration.Configuration; + +public class SecurityConfiguration +{ + + private Configuration _conf; + + public SecurityConfiguration(Configuration configuration) + { + _conf = configuration; + } + + public Configuration getConfiguration() + { + return _conf; + } + +} 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 new file mode 100644 index 0000000000..c0fe42c5c2 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java @@ -0,0 +1,514 @@ +/* + * 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.configuration; + +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.ConfigurationFactory; +import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; +import org.apache.qpid.tools.messagestore.MessageStoreTool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sun.misc.Signal; +import sun.misc.SignalHandler; + +public class ServerConfiguration implements SignalHandler +{ + + private static Configuration _config; + + private static final int DEFAULT_FRAME_SIZE = 65536; + private static final int DEFAULT_BUFFER_READ_LIMIT_SIZE = 262144; + private static final int DEFAULT_BUFFER_WRITE_LIMIT_SIZE = 262144; + private static final int DEFAULT_PORT = 5672; + private static final int DEFAUL_SSL_PORT = 8672; + private static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L; + private static final int DEFAULT_JMXPORT = 8999; + + private static int _jmxPort = DEFAULT_JMXPORT; + + private Map<String, VirtualHostConfiguration> _virtualHosts = new HashMap<String, VirtualHostConfiguration>(); + private SecurityConfiguration _securityConfiguration = null; + + private File _configFile; + + private Logger _log = LoggerFactory.getLogger(this.getClass()); + + private ConfigurationManagementMBean _mbean; + + + // Map of environment variables to config items + private static final Map<String, String> envVarMap = new HashMap<String, String>(); + + { + envVarMap.put("QPID_PORT", "connector.port"); + envVarMap.put("QPID_ENABLEDIRECTBUFFERS", "advanced.enableDirectBuffers"); + envVarMap.put("QPID_SSLPORT", "connector.ssl.port"); + envVarMap.put("QPID_NIO", "connector.qpidnio"); + envVarMap.put("QPID_WRITEBIASED", "advanced.useWriteBiasedPool"); + envVarMap.put("QPID_JMXPORT", "management.jmxport"); + envVarMap.put("QPID_FRAMESIZE", "advanced.framesize"); + envVarMap.put("QPID_MSGAUTH", "security.msg-auth"); + envVarMap.put("QPID_AUTOREGISTER", "auto_register"); + envVarMap.put("QPID_MANAGEMENTENABLED", "management.enabled"); + envVarMap.put("QPID_HEARTBEATDELAY", "heartbeat.delay"); + envVarMap.put("QPID_HEARTBEATTIMEOUTFACTOR", "heartbeat.timeoutFactor"); + envVarMap.put("QPID_MAXIMUMMESSAGEAGE", "maximumMessageAge"); + envVarMap.put("QPID_MAXIMUMMESSAGECOUNT", "maximumMessageCount"); + envVarMap.put("QPID_MAXIMUMQUEUEDEPTH", "maximumQueueDepth"); + envVarMap.put("QPID_MAXIMUMMESSAGESIZE", "maximumMessageSize"); + envVarMap.put("QPID_MINIMUMALERTREPEATGAP", "minimumAlertRepeatGap"); + envVarMap.put("QPID_SOCKETRECEIVEBUFFER", "connector.socketReceiveBuffer"); + envVarMap.put("QPID_SOCKETWRITEBUFFER", "connector.socketWriteBuffer"); + envVarMap.put("QPID_TCPNODELAY", "connector.tcpNoDelay"); + envVarMap.put("QPID_ENABLEPOOLEDALLOCATOR", "advanced.enablePooledAllocator"); + } + + public ServerConfiguration(File configurationURL) throws ConfigurationException + { + this(parseConfig(configurationURL)); + _configFile = configurationURL; + sun.misc.Signal.handle(new sun.misc.Signal("HUP"), this); + } + + public ServerConfiguration(Configuration conf) throws ConfigurationException + { + _config = conf; + + substituteEnvironmentVariables(); + + _jmxPort = _config.getInt("management.jmxport", 8999); + _securityConfiguration = new SecurityConfiguration(conf.subset("security")); + + setupVirtualHosts(conf); + + } + + private void setupVirtualHosts(Configuration conf) throws ConfigurationException + { + List vhosts = conf.getList("virtualhosts"); + Iterator i = vhosts.iterator(); + while (i.hasNext()) + { + Object thing = i.next(); + if (thing instanceof String) + { + XMLConfiguration vhostConfiguration = new XMLConfiguration((String) thing); + List hosts = vhostConfiguration.getList("virtualhost.name"); + for (int j = 0; j < hosts.size(); j++) + { + String name = (String) hosts.get(j); + CompositeConfiguration mungedConf = new CompositeConfiguration(); + mungedConf.addConfiguration(conf.subset("virtualhosts.virtualhost."+name)); + mungedConf.addConfiguration(vhostConfiguration.subset("virtualhost." + name)); + VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(name, mungedConf, this); + _virtualHosts.put(vhostConfig.getName(), vhostConfig); + } + } + } + } + + private void substituteEnvironmentVariables() + { + for (Entry<String, String> var : envVarMap.entrySet()) + { + String val = System.getenv(var.getKey()); + if (val != null) + { + _config.setProperty(var.getValue(), val); + } + } + } + + private final static Configuration parseConfig(File file) throws ConfigurationException + { + ConfigurationFactory factory = new ConfigurationFactory(); + factory.setConfigurationFileName(file.getAbsolutePath()); + Configuration conf = factory.getConfiguration(); + Iterator keys = conf.getKeys(); + if (!keys.hasNext()) + { + keys = null; + conf = flatConfig(file); + } + return conf; + } + + // Our configuration class needs to make the interpolate method + // public so it can be called below from the config method. + private static class MyConfiguration extends CompositeConfiguration + { + public String interpolate(String obj) + { + return super.interpolate(obj); + } + } + + private final static Configuration flatConfig(File file) throws ConfigurationException + { + // We have to override the interpolate methods so that + // interpolation takes place accross the entirety of the + // composite configuration. Without doing this each + // configuration object only interpolates variables defined + // inside itself. + final MyConfiguration conf = new MyConfiguration(); + conf.addConfiguration(new SystemConfiguration() + { + protected String interpolate(String o) + { + return conf.interpolate(o); + } + }); + conf.addConfiguration(new XMLConfiguration(file) + { + protected String interpolate(String o) + { + return conf.interpolate(o); + } + }); + return conf; + } + + @Override + public void handle(Signal arg0) + { + try + { + reparseConfigFile(); + } + catch (ConfigurationException e) + { + _log.error("Could not reload configuration file", e); + } + } + + public void reparseConfigFile() throws ConfigurationException + { + if (_configFile != null) + { + Configuration newConfig = parseConfig(_configFile); + _securityConfiguration = new SecurityConfiguration(newConfig.subset("security")); + ApplicationRegistry.getInstance().getAccessManager().configurePlugins(_securityConfiguration); + + VirtualHostRegistry vhostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry(); + for (String hostname : _virtualHosts.keySet()) + { + VirtualHost vhost = vhostRegistry.getVirtualHost(hostname); + SecurityConfiguration hostSecurityConfig = new SecurityConfiguration(newConfig.subset("virtualhosts.virtualhost."+hostname+".security")); + vhost.getAccessManager().configureHostPlugins(hostSecurityConfig); + } + } + } + + public String getQpidWork() + { + return System.getProperty("QPID_WORK", System.getProperty("java.io.tmpdir")); + } + + public void setJMXManagementPort(int mport) + { + _jmxPort = mport; + } + + public int getJMXManagementPort() + { + return _jmxPort; + } + + public boolean getPlatformMbeanserver() + { + return _config.getBoolean("management.platform-mbeanserver", true); + } + + public String[] getVirtualHosts() + { + return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]); + } + + public String getPluginDirectory() + { + return _config.getString("plugin-directory"); + } + + public VirtualHostConfiguration getVirtualHostConfig(String name) + { + return _virtualHosts.get(name); + } + + public List<String> getPrincipalDatabaseNames() + { + return _config.getList("security.principal-databases.principal-database.name"); + } + + public List<String> getPrincipalDatabaseClass() + { + return _config.getList("security.principal-databases.principal-database.class"); + } + + public List<String> getPrincipalDatabaseAttributeNames(int index) + { + String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.name"; + return _config.getList(name); + } + + public List<String> getPrincipalDatabaseAttributeValues(int index) + { + String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.value"; + return _config.getList(name); + } + + public List<String> getManagementPrincipalDBs() + { + return _config.getList("security.jmx.principal-database"); + } + + public List<String> getManagementAccessList() + { + return _config.getList("security.jmx.access"); + } + + public int getFrameSize() + { + return _config.getInt("advanced.framesize", DEFAULT_FRAME_SIZE); + } + + public boolean getProtectIOEnabled() + { + return _config.getBoolean("broker.connector.protectio.enabled", false); + } + + public int getBufferReadLimit() + { + return _config.getInt("broker.connector.protectio.readBufferLimitSize", DEFAULT_BUFFER_READ_LIMIT_SIZE); + } + + public int getBufferWriteLimit() + { + return _config.getInt("broker.connector.protectio.writeBufferLimitSize", DEFAULT_BUFFER_WRITE_LIMIT_SIZE); + } + + public boolean getSynchedClocks() + { + return _config.getBoolean("advanced.synced-clocks", false); + } + + public boolean getMsgAuth() + { + return _config.getBoolean("security.msg-auth", false); + } + + public String getJMXPrincipalDatabase() + { + return _config.getString("security.jmx.principal-database"); + } + + public String getManagementKeyStorePath() + { + return _config.getString("management.ssl.keyStorePath", null); + } + + public boolean getManagementSSLEnabled() + { + return _config.getBoolean("management.ssl.enabled", true); + } + + public String getManagementKeyStorePassword() + { + return _config.getString("management.ssl.keyStorePassword"); + } + + public SecurityConfiguration getSecurityConfiguration() + { + return _securityConfiguration; + } + + public boolean getQueueAutoRegister() + { + return _config.getBoolean("queue.auto_register", true); + } + + public boolean getManagementEnabled() + { + return _config.getBoolean("management.enabled", true); + } + + public void setManagementEnabled(boolean enabled) + { + _config.setProperty("management.enabled", enabled); + } + + + public int getHeartBeatDelay() + { + return _config.getInt("heartbeat.delay", 5); + } + + public double getHeartBeatTimeout() + { + return _config.getDouble("heartbeat.timeoutFactor", 2.0); + } + + public int getDeliveryPoolSize() + { + return _config.getInt("delivery.poolsize", 0); + } + + public long getMaximumMessageAge() + { + return _config.getLong("maximumMessageAge", 0); + } + + public long getMaximumMessageCount() + { + return _config.getLong("maximumMessageCount", 0); + } + + public long getMaximumQueueDepth() + { + return _config.getLong("maximumQueueDepth", 0); + } + + public long getMaximumMessageSize() + { + return _config.getLong("maximumMessageSize", 0); + } + + public long getMinimumAlertRepeatGap() + { + return _config.getLong("minimumAlertRepeatGap", 0); + } + + public int getProcessors() + { + return _config.getInt("connector.processors", 4); + } + + public int getPort() + { + return _config.getInt("connector.port", DEFAULT_PORT); + } + + public String getBind() + { + return _config.getString("connector.bind", "wildcard"); + } + + public int getReceiveBufferSize() + { + return _config.getInt("connector.socketReceiveBuffer", 32767); + } + + public int getWriteBufferSize() + { + return _config.getInt("connector.socketWriteBuffer", 32767); + } + + public boolean getTcpNoDelay() + { + return _config.getBoolean("connector.tcpNoDelay", true); + } + + public boolean getEnableExecutorPool() + { + return _config.getBoolean("advanced.filterchain[@enableExecutorPool]", false); + } + + public boolean getEnablePooledAllocator() + { + return _config.getBoolean("advanced.enablePooledAllocator", false); + } + + public boolean getEnableDirectBuffers() + { + return _config.getBoolean("advanced.enableDirectBuffers", false); + } + + public boolean getEnableSSL() + { + return _config.getBoolean("connector.ssl.enabled", false); + } + + public boolean getSSLOnly() + { + return _config.getBoolean("connector.ssl.sslOnly", true); + } + + public int getSSLPort() + { + return _config.getInt("connector.ssl.port", DEFAUL_SSL_PORT); + } + + public String getKeystorePath() + { + return _config.getString("connector.ssl.keystorePath", "none"); + } + + public String getKeystorePassword() + { + return _config.getString("connector.ssl.keystorePassword", "none"); + } + + public String getCertType() + { + return _config.getString("connector.ssl.certType", "SunX509"); + } + + public boolean getQpidNIO() + { + return _config.getBoolean("connector.qpidnio", false); + } + + public boolean getUseBiasedWrites() + { + return _config.getBoolean("advanced.useWriteBiasedPool", false); + } + + public String getDefaultVirtualHost() + { + return _config.getString("virtualhosts.default"); + } + + public void setHousekeepingExpiredMessageCheckPeriod(long value) + { + _config.setProperty("housekeeping.expiredMessageCheckPeriod", value); + } + + public long getHousekeepingCheckPeriod() + { + return _config.getLong("housekeeping.checkPeriod", + _config.getLong("housekeeping.expiredMessageCheckPeriod", + DEFAULT_HOUSEKEEPING_PERIOD)); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java index 02fb57c730..343abe4b5a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java @@ -20,266 +20,150 @@ */ package org.apache.qpid.server.configuration; -import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.XMLConfiguration; -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeFactory; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.transactionlog.TransactionLog; -import org.apache.qpid.server.routing.RoutingTable; +import org.apache.qpid.server.store.MemoryMessageStore; public class VirtualHostConfiguration { - private static final Logger _logger = Logger.getLogger(VirtualHostConfiguration.class); - - private static XMLConfiguration _config; - - private static final String VIRTUALHOST_PROPERTY_BASE = "virtualhost."; - - - public VirtualHostConfiguration(String configFile) throws ConfigurationException - { - _logger.info("Loading Config file:" + configFile); - - _config = new XMLConfiguration(configFile); - - } - - - - private void configureVirtualHost(String virtualHostName, Configuration configuration) throws ConfigurationException, AMQException + private Configuration _config; + private String _name; + private Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>(); + private Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>(); + private ServerConfiguration _serverConfiguration; + + public VirtualHostConfiguration(String name, Configuration config, + ServerConfiguration serverConfiguration) throws ConfigurationException { - _logger.debug("Loding configuration for virtaulhost: "+virtualHostName); - + _serverConfiguration = serverConfiguration; + _config = config; + _name = name; - VirtualHost virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(virtualHostName); + Iterator i = _config.getList("queues.queue.name").iterator(); - - - if(virtualHost == null) + while (i.hasNext()) { - throw new ConfigurationException("Unknown virtual host: " + virtualHostName); + String queueName = (String) i.next(); + CompositeConfiguration mungedConf = new CompositeConfiguration(); + mungedConf.addConfiguration(_config.subset("queues.queue." + queueName)); + mungedConf.addConfiguration(_config.subset("queues")); + _queues.put(queueName, new QueueConfiguration(queueName, mungedConf, this)); } - List exchangeNames = configuration.getList("exchanges.exchange.name"); - - for(Object exchangeNameObj : exchangeNames) + i = _config.getList("exchanges.exchange.name").iterator(); + int count = 0; + while (i.hasNext()) { - String exchangeName = String.valueOf(exchangeNameObj); - configureExchange(virtualHost, exchangeName, configuration); + CompositeConfiguration mungedConf = new CompositeConfiguration(); + mungedConf.addConfiguration(config.subset("exchanges.exchange(" + count++ + ")")); + mungedConf.addConfiguration(_config.subset("exchanges")); + String exchName = (String) i.next(); + _exchanges.put(exchName, new ExchangeConfiguration(exchName, mungedConf)); } - - - List queueNames = configuration.getList("queues.queue.name"); - - for(Object queueNameObj : queueNames) - { - String queueName = String.valueOf(queueNameObj); - configureQueue(virtualHost, queueName, configuration); - } - } - private void configureExchange(VirtualHost virtualHost, String exchangeNameString, Configuration configuration) throws AMQException + /** + * All future usages should use the constructor that takes the ServerConfiguration. + * + * This can be removed after QPID-1696 has been resolved. + * + * @param name + * @param mungedConf + * @throws ConfigurationException + */ + @Deprecated + public VirtualHostConfiguration(String name, Configuration mungedConf) throws ConfigurationException { - - CompositeConfiguration exchangeConfiguration = new CompositeConfiguration(); - - exchangeConfiguration.addConfiguration(configuration.subset("exchanges.exchange."+ exchangeNameString)); - exchangeConfiguration.addConfiguration(configuration.subset("exchanges")); - - ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry(); - ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory(); - - AMQShortString exchangeName = new AMQShortString(exchangeNameString); - - - Exchange exchange; - - - - synchronized (exchangeRegistry) - { - exchange = exchangeRegistry.getExchange(exchangeName); - if(exchange == null) - { - - AMQShortString type = new AMQShortString(exchangeConfiguration.getString("type","direct")); - boolean durable = exchangeConfiguration.getBoolean("durable",false); - boolean autodelete = exchangeConfiguration.getBoolean("autodelete",false); - - Exchange newExchange = exchangeFactory.createExchange(exchangeName,type,durable,autodelete,0); - exchangeRegistry.registerExchange(newExchange); - } - - } + this(name,mungedConf, ApplicationRegistry.getInstance().getConfiguration()); } - public static CompositeConfiguration getDefaultQueueConfiguration(VirtualHost host) + public String getName() { - CompositeConfiguration queueConfiguration = null; - if (_config == null) - return null; - - Configuration vHostConfiguration = _config.subset(VIRTUALHOST_PROPERTY_BASE + host.getName()); - - if (vHostConfiguration == null) - return null; - - Configuration defaultQueueConfiguration = vHostConfiguration.subset("queues"); - if (defaultQueueConfiguration != null) - { - queueConfiguration = new CompositeConfiguration(); - queueConfiguration.addConfiguration(defaultQueueConfiguration); - } - - return queueConfiguration; + return _name; } - private void configureQueue(VirtualHost virtualHost, String queueNameString, Configuration configuration) throws AMQException, ConfigurationException + public long getHousekeepingExpiredMessageCheckPeriod() { - CompositeConfiguration queueConfiguration = new CompositeConfiguration(); - - queueConfiguration.addConfiguration(configuration.subset("queues.queue."+ queueNameString)); - queueConfiguration.addConfiguration(configuration.subset("queues")); - - QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); - RoutingTable routingTable = virtualHost.getRoutingTable(); - ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry(); - - - AMQShortString queueName = new AMQShortString(queueNameString); - - AMQQueue queue; - - synchronized (queueRegistry) - { - queue = queueRegistry.getQueue(queueName); - - if (queue == null) - { - _logger.info("Creating queue '" + queueName + "' on virtual host " + virtualHost.getName()); - - boolean durable = queueConfiguration.getBoolean("durable" ,false); - boolean autodelete = queueConfiguration.getBoolean("autodelete", false); - String owner = queueConfiguration.getString("owner", null); - FieldTable arguments = null; - boolean priority = queueConfiguration.getBoolean("priority", false); - int priorities = queueConfiguration.getInt("priorities", -1); - if(priority || priorities > 0) - { - if(arguments == null) - { - arguments = new FieldTable(); - } - if (priorities < 0) - { - priorities = 10; - } - arguments.put(new AMQShortString("x-qpid-priorities"), priorities); - } - - - queue = AMQQueueFactory.createAMQQueueImpl(queueName, - durable, - owner == null ? null : new AMQShortString(owner) /* These queues will have no owner */, - autodelete /* Therefore autodelete makes no sence */, - virtualHost, - arguments, - queueConfiguration); - - if (queue.isDurable()) - { - routingTable.createQueue(queue); - } - - queueRegistry.registerQueue(queue); - } - else - { - _logger.info("Queue '" + queueNameString + "' already exists on virtual host "+virtualHost.getName()+", not creating."); - } - - String exchangeName = queueConfiguration.getString("exchange", null); - - Exchange exchange = exchangeRegistry.getExchange(exchangeName == null ? null : new AMQShortString(exchangeName)); - - if(exchange == null) - { - exchange = virtualHost.getExchangeRegistry().getDefaultExchange(); - } + return _config.getLong("housekeeping.expiredMessageCheckPeriod", _serverConfiguration.getHousekeepingCheckPeriod()); + } - if (exchange == null) - { - throw new ConfigurationException("Attempt to bind queue to unknown exchange:" + exchangeName); - } + public String getAuthenticationDatabase() + { + return _config.getString("security.authentication.name"); + } - synchronized (exchange) - { - List routingKeys = queueConfiguration.getList("routingKey"); - if(routingKeys == null || routingKeys.isEmpty()) - { - routingKeys = Collections.singletonList(queue.getName()); - } + public List getCustomExchanges() + { + return _config.getList("custom-exchanges.class-name"); + } - for(Object routingKeyNameObj : routingKeys) - { - AMQShortString routingKey = new AMQShortString(String.valueOf(routingKeyNameObj)); - + public SecurityConfiguration getSecurityConfiguration() + { + return new SecurityConfiguration(_config.subset("security")); + } - queue.bind(exchange, routingKey, null); + public Configuration getStoreConfiguration() + { + return _config.subset("store"); + } + public String getRoutingTableClass() + { + return _config.getString("routingtable.class"); + } - _logger.info("Queue '" + queue.getName() + "' bound to exchange:" + exchangeName + " RK:'" + routingKey + "'"); - } + public String getTransactionLogClass() + { + return _config.getString("store.class", MemoryMessageStore.class.getName()); + } - if(exchange != virtualHost.getExchangeRegistry().getDefaultExchange()) - { - queue.bind(virtualHost.getExchangeRegistry().getDefaultExchange(), queue.getName(), null); - } - } + public List getExchanges() + { + return _config.getList("exchanges.exchange.name"); + } - } + public ExchangeConfiguration getExchangeConfiguration(String exchangeName) + { + return _exchanges.get(exchangeName); } + public String[] getQueueNames() + { + return _queues.keySet().toArray(new String[_queues.size()]); + } - public void performBindings() throws AMQException, ConfigurationException + public QueueConfiguration getQueueConfiguration(String queueName) { - List virtualHostNames = _config.getList(VIRTUALHOST_PROPERTY_BASE + "name"); - String defaultVirtualHostName = _config.getString("default"); - if(defaultVirtualHostName != null) - { - ApplicationRegistry.getInstance().getVirtualHostRegistry().setDefaultVirtualHostName(defaultVirtualHostName); - } - _logger.info("Configuring " + virtualHostNames == null ? 0 : virtualHostNames.size() + " virtual hosts: " + virtualHostNames); + return _queues.get(queueName); + } - for(Object nameObject : virtualHostNames) - { - String name = String.valueOf(nameObject); - configureVirtualHost(name, _config.subset(VIRTUALHOST_PROPERTY_BASE + name)); - } + public long getMemoryUsageMaximum() + { + return _config.getLong("queues.maximumMemoryUsage", 0); + } - if (virtualHostNames == null || virtualHostNames.isEmpty()) - { - throw new ConfigurationException( - "Virtualhost Configuration document does not contain a valid virtualhost."); - } + public long getMemoryUsageMinimum() + { + return _config.getLong("queues.minimumMemoryUsage", 0); } + public ServerConfiguration getServerConfiguration() + { + return _serverConfiguration; + } + public static final String FLOW_TO_DISK_PATH = "flowToDiskPath"; + public String getFlowToDiskLocation() + { + return _config.getString(FLOW_TO_DISK_PATH, getServerConfiguration().getQpidWork()); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java new file mode 100644 index 0000000000..8e4bf01c6a --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java @@ -0,0 +1,43 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.management; + +import javax.management.MBeanOperationInfo; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.management.MBeanOperation; + +public interface ConfigurationManagement +{ + + String TYPE = "ConfigurationManagement"; + int VERSION = 1; + + /** + * Reload the + * @throws ConfigurationException + */ + @MBeanOperation(name="reloadSecurityConfiguration", + description = "Force a reload of the security configuration sections", + impact = MBeanOperationInfo.ACTION) + void reloadSecurityConfiguration() throws ConfigurationException; + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AsyncDeliveryConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java index 290fedcf7b..ead6053d70 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AsyncDeliveryConfig.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java @@ -18,39 +18,32 @@ * under the License. * */ -package org.apache.qpid.server.queue; +package org.apache.qpid.server.configuration.management; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; +import javax.management.NotCompliantMBeanException; -import org.apache.qpid.configuration.Configured; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.registry.ApplicationRegistry; -public class AsyncDeliveryConfig +public class ConfigurationManagementMBean extends AMQManagedObject implements ConfigurationManagement { - private Executor _executor; - @Configured(path = "delivery.poolsize", defaultValue = "0") - public int poolSize; + public ConfigurationManagementMBean() throws NotCompliantMBeanException + { + super(ConfigurationManagement.class, ConfigurationManagement.TYPE, ConfigurationManagement.VERSION); + } - public Executor getExecutor() + @Override + public String getObjectInstanceName() { - if (_executor == null) - { - if (poolSize > 0) - { - _executor = Executors.newFixedThreadPool(poolSize); - } - else - { - _executor = Executors.newCachedThreadPool(); - } - } - return _executor; + return ConfigurationManagement.TYPE; } - public static Executor getAsyncDeliveryExecutor() + @Override + public void reloadSecurityConfiguration() throws ConfigurationException { - return ApplicationRegistry.getInstance().getConfiguredObject(AsyncDeliveryConfig.class).getExecutor(); + ApplicationRegistry.getInstance().getConfiguration().reparseConfigFile(); } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java index 8d24626b73..30af09ce4b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java @@ -38,13 +38,9 @@ import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.management.ManagedObjectRegistry; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; -import java.util.List; -import java.util.Map; - public abstract class AbstractExchange implements Exchange, Managable { private AMQShortString _name; @@ -81,7 +77,7 @@ public abstract class AbstractExchange implements Exchange, Managable public ExchangeMBean() throws NotCompliantMBeanException { - super(ManagedExchange.class, ManagedExchange.TYPE); + super(ManagedExchange.class, ManagedExchange.TYPE, ManagedExchange.VERSION); } protected void init() throws OpenDataException @@ -195,7 +191,7 @@ public abstract class AbstractExchange implements Exchange, Managable public String toString() { - return getClass().getName() + "[" + getName() +"]"; + return getClass().getSimpleName() + "[" + getName() +"]"; } public ManagedObject getManagedObject() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java index 9d4c090971..c04b6c559c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java @@ -25,11 +25,11 @@ import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; -import org.apache.commons.configuration.Configuration; import org.apache.qpid.AMQException; import org.apache.qpid.AMQUnknownExchangeType; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -73,7 +73,8 @@ public class DefaultExchangeFactory implements ExchangeFactory return e; } - public void initialise(Configuration hostConfig) + @Override + public void initialise(VirtualHostConfiguration hostConfig) { if (hostConfig == null) @@ -81,7 +82,7 @@ public class DefaultExchangeFactory implements ExchangeFactory return; } - for(Object className : hostConfig.getList("custom-exchanges.class-name")) + for(Object className : hostConfig.getCustomExchanges()) { try { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java index e39c005750..e9af92bad8 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java @@ -168,16 +168,14 @@ public class DirectExchange extends AbstractExchange { if (_logger.isDebugEnabled()) { - _logger.debug("Queue (" + queue.getName() + ")" + queue + " is already registered with routing key " + routingKey); + _logger.debug("Queue (" + queue + ") is already registered with routing key " + routingKey); } } else { if (_logger.isDebugEnabled()) { - _logger.debug("Binding queue(" + queue.getName() + ") " + queue + " with routing key " + routingKey - + (args == null ? "" : " and arguments " + args.toString()) - + " to exchange " + this); + _logger.debug("Binding queue:" + queue + " with routing key '" + routingKey +"' to exchange:" + this); } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java index 0bcfec7181..2f76d41228 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java @@ -26,6 +26,7 @@ import org.apache.commons.configuration.Configuration; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; public interface ExchangeFactory @@ -34,7 +35,7 @@ public interface ExchangeFactory int ticket) throws AMQException; - void initialise(Configuration hostConfig); + void initialise(VirtualHostConfiguration hostConfig); Collection<ExchangeType<? extends Exchange>> getRegisteredTypes(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java index 5d6d68b3c8..317ff385ab 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java @@ -40,6 +40,7 @@ import org.apache.qpid.server.queue.ManagedQueue; public interface ManagedExchange { static final String TYPE = "Exchange"; + static final int VERSION = 1; /** * Returns the name of the managed exchange. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java index 0743e4bb8d..0bb428cd8f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java @@ -1,6 +1,6 @@ package org.apache.qpid.server.flow; -import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.QueueEntry; import java.util.concurrent.atomic.AtomicLong; @@ -49,9 +49,9 @@ public class BytesOnlyCreditManager extends AbstractFlowCreditManager return _bytesCredit.get() > 0L; } - public boolean useCreditForMessage(AMQMessage msg) + public boolean useCreditForMessage(QueueEntry queueEntry) { - final long msgSize = msg.getSize(); + final long msgSize = queueEntry.getSize(); if(hasCredit()) { if(_bytesCredit.addAndGet(-msgSize) >= 0) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java index a249a6e63a..297e5a4826 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java @@ -1,6 +1,7 @@ package org.apache.qpid.server.flow; import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.QueueEntry; /* * @@ -40,5 +41,5 @@ public interface FlowCreditManager public boolean hasCredit(); - public boolean useCreditForMessage(AMQMessage msg); + public boolean useCreditForMessage(QueueEntry queueEntry); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java index d63431c3eb..437b7b0469 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java @@ -1,6 +1,6 @@ package org.apache.qpid.server.flow; -import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.QueueEntry; /* * @@ -37,7 +37,7 @@ public class LimitlessCreditManager extends AbstractFlowCreditManager implements return true; } - public boolean useCreditForMessage(AMQMessage msg) + public boolean useCreditForMessage(QueueEntry queueEntry) { return true; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java index 5f0acec03f..15ecb5f292 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java @@ -1,6 +1,6 @@ package org.apache.qpid.server.flow; -import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.QueueEntry; /* * @@ -52,7 +52,7 @@ public class MessageAndBytesCreditManager extends AbstractFlowCreditManager impl return (_messageCredit > 0L) && ( _bytesCredit > 0L ); } - public synchronized boolean useCreditForMessage(AMQMessage msg) + public synchronized boolean useCreditForMessage(QueueEntry queueEntry) { if(_messageCredit == 0L) { @@ -61,7 +61,7 @@ public class MessageAndBytesCreditManager extends AbstractFlowCreditManager impl } else { - final long msgSize = msg.getSize(); + final long msgSize = queueEntry.getSize(); if(msgSize > _bytesCredit) { setSuspended(true); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java index c1b3a09006..3e28d779b1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java @@ -1,6 +1,6 @@ package org.apache.qpid.server.flow; -import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.QueueEntry; import java.util.concurrent.atomic.AtomicLong; @@ -50,7 +50,7 @@ public class MessageOnlyCreditManager extends AbstractFlowCreditManager implemen return _messageCredit.get() > 0L; } - public boolean useCreditForMessage(AMQMessage msg) + public boolean useCreditForMessage(QueueEntry queueEntry) { if(hasCredit()) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java index be0300f2c1..5cdd3a0328 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.server.flow; -import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.QueueEntry; public class Pre0_10CreditManager extends AbstractFlowCreditManager implements FlowCreditManager { @@ -123,7 +123,7 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F && (_messageCreditLimit == 0L || _messageCredit > 0); } - public synchronized boolean useCreditForMessage(final AMQMessage msg) + public synchronized boolean useCreditForMessage(final QueueEntry queueEntry) { if(_messageCreditLimit != 0L) { @@ -137,10 +137,10 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F } else { - if((_bytesCredit >= msg.getSize()) || (_bytesCredit == _bytesCreditLimit)) + if((_bytesCredit >= queueEntry.getSize()) || (_bytesCredit == _bytesCreditLimit)) { _messageCredit--; - _bytesCredit -= msg.getSize(); + _bytesCredit -= queueEntry.getSize(); return true; } @@ -166,9 +166,9 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F } else { - if((_bytesCredit >= msg.getSize()) || (_bytesCredit == _bytesCreditLimit)) + if((_bytesCredit >= queueEntry.getSize()) || (_bytesCredit == _bytesCreditLimit)) { - _bytesCredit -= msg.getSize(); + _bytesCredit -= queueEntry.getSize(); return true; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java index 0f492a21bb..a626114792 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java @@ -129,7 +129,7 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB public void deliverToClient(final Subscription sub, final QueueEntry entry, final long deliveryTag)
throws AMQException
{
- singleMessageCredit.useCreditForMessage(entry.getMessage());
+ singleMessageCredit.useCreditForMessage(entry);
session.getProtocolOutputConverter().writeGetOk(entry, channel.getChannelId(),
deliveryTag, queue.getMessageCount());
@@ -181,9 +181,9 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB super(channel, protocolSession, consumerTag, filters, noLocal, creditManager, deliveryMethod, recordMethod);
}
- public boolean wouldSuspend(QueueEntry msg)
+ public boolean wouldSuspend(QueueEntry queueEntry)
{
- return !getCreditManager().useCreditForMessage(msg.getMessage());
+ return !getCreditManager().useCreditForMessage(queueEntry);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java index f3cab10ed7..8b04315d33 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java @@ -65,38 +65,38 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR long deliveryTag = body.getDeliveryTag(); - QueueEntry message = channel.getUnacknowledgedMessageMap().get(deliveryTag); + QueueEntry queueEntry = channel.getUnacknowledgedMessageMap().get(deliveryTag); - if (message == null) + if (queueEntry == null) { _logger.warn("Dropping reject request as message is null for tag:" + deliveryTag); // throw evt.getMethod().getChannelException(AMQConstant.NOT_FOUND, "Delivery Tag(" + deliveryTag + ")not known"); } else { - if (message.isQueueDeleted()) + if (queueEntry.isQueueDeleted()) { _logger.warn("Message's Queue as already been purged, unable to Reject. " + "Dropping message should use Dead Letter Queue"); - message = channel.getUnacknowledgedMessageMap().remove(deliveryTag); - if(message != null) + queueEntry = channel.getUnacknowledgedMessageMap().remove(deliveryTag); + if(queueEntry != null) { - message.discard(channel.getStoreContext()); + queueEntry.dequeueAndDelete(channel.getStoreContext()); } //sendtoDeadLetterQueue(msg) return; } - if (!message.getMessage().isReferenced()) + if (queueEntry.isDeleted()) { - _logger.warn("Message as already been purged, unable to Reject."); + _logger.warn("QueueEntry as already been deleted, unable to Reject."); return; } if (_logger.isDebugEnabled()) { - _logger.debug("Rejecting: DT:" + deliveryTag + "-" + message.getMessage().debugIdentity() + + _logger.debug("Rejecting: DT:" + deliveryTag + "-" + queueEntry.debugIdentity() + ": Requeue:" + body.getRequeue() + //": Resend:" + evt.getMethod().resend + " on channel:" + channel.debugIdentity()); @@ -105,7 +105,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR // If we haven't requested message to be resent to this consumer then reject it from ever getting it. //if (!evt.getMethod().resend) { - message.reject(); + queueEntry.reject(); } if (body.getRequeue()) @@ -115,7 +115,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR else { _logger.warn("Dropping message as requeue not required and there is no dead letter queue"); - message = channel.getUnacknowledgedMessageMap().remove(deliveryTag); + queueEntry = channel.getUnacknowledgedMessageMap().remove(deliveryTag); //sendtoDeadLetterQueue(AMQMessage message) // message.queue = channel.getDefaultDeadLetterQueue(); // channel.requeue(deliveryTag); 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 621003be90..a2a6faf21b 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 @@ -25,14 +25,16 @@ import javax.security.sasl.SaslServer; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.ConnectionSecureBody; +import org.apache.qpid.framing.ConnectionSecureOkBody; +import org.apache.qpid.framing.ConnectionTuneBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.protocol.HeartbeatConfig; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; @@ -92,7 +94,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(0xFFFF, ConnectionStartOkMethodHandler.getConfiguredFrameSize(), - HeartbeatConfig.getInstance().getDelay()); + ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay()); session.writeFrame(tuneBody.generateFrame(0)); session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID())); disposeSaslServer(session); 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 f53e56601b..6698ae888a 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 @@ -23,18 +23,19 @@ package org.apache.qpid.server.handler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.*; -import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.ConnectionSecureBody; +import org.apache.qpid.framing.ConnectionStartOkBody; +import org.apache.qpid.framing.ConnectionTuneBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.protocol.HeartbeatConfig; -import org.apache.qpid.server.protocol.AMQMinaProtocolSession; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; @@ -47,8 +48,6 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< private static ConnectionStartOkMethodHandler _instance = new ConnectionStartOkMethodHandler(); - private static final int DEFAULT_FRAME_SIZE = 65536; - public static ConnectionStartOkMethodHandler getInstance() { return _instance; @@ -117,7 +116,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(0xFFFF, getConfiguredFrameSize(), - HeartbeatConfig.getInstance().getDelay()); + ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay()); session.writeFrame(tuneBody.generateFrame(0)); break; case CONTINUE: @@ -153,8 +152,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< static int getConfiguredFrameSize() { - final Configuration config = ApplicationRegistry.getInstance().getConfiguration(); - final int framesize = config.getInt("advanced.framesize", DEFAULT_FRAME_SIZE); + final ServerConfiguration config = ApplicationRegistry.getInstance().getConfiguration(); + final int framesize = config.getFrameSize(); _logger.info("Framesize set to " + framesize); return framesize; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index b1e02aef7a..7f500cfb8a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -20,27 +20,28 @@ */ package org.apache.qpid.server.handler; -import java.util.concurrent.atomic.AtomicInteger; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.configuration.Configured; - -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.QueueDeclareBody; +import org.apache.qpid.framing.QueueDeclareOkBody; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.configuration.Configurator; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.queue.QueueRegistry; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.routing.RoutingTable; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.routing.RoutingTable; public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclareBody> { @@ -53,17 +54,10 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar return _instance; } - @Configured(path = "queue.auto_register", defaultValue = "true") - public boolean autoRegister; + public boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); private final AtomicInteger _counter = new AtomicInteger(); - - protected QueueDeclareHandler() - { - Configurator.configure(this); - } - public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java new file mode 100644 index 0000000000..79d60a6df0 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java @@ -0,0 +1,129 @@ +/* + * 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.logging.management; + +import java.io.IOException; + +import org.apache.qpid.server.management.MBeanAttribute; +import org.apache.qpid.server.management.MBeanOperation; +import org.apache.qpid.server.management.MBeanOperationParameter; + +import javax.management.MBeanOperationInfo; +import javax.management.openmbean.TabularData; + +public interface LoggingManagement +{ + String TYPE = "LoggingManagement"; + int VERSION = 1; + + //TabularType and contained CompositeType key/description information + String[] COMPOSITE_ITEM_NAMES = {"LoggerName", "Level"}; + String[] COMPOSITE_ITEM_DESCRIPTIONS = {"Name of the logger", "Level of the logger"}; + String[] TABULAR_UNIQUE_INDEX = {COMPOSITE_ITEM_NAMES[0]}; + + /** + * Attribute to represent the log4j xml configuration file's LogWatch interval. + * @return The logwatch interval in seconds. + */ + @MBeanAttribute(name="Log4jLogWatchInterval", + description = "The log4j xml configuration file LogWatch interval (in seconds). 0 indicates not being checked.") + Integer getLog4jLogWatchInterval(); + + + //****** log4j runtime operations ****** // + + /** + * Sets the level of an active Log4J logger + * @param logger The name of the logger + * @param level The level to set the logger to + * @return True if successful, false if unsuccessful (eg if an invalid level is specified) + */ + @MBeanOperation(name = "setRuntimeLoggerLevel", description = "Set the runtime logging level for an active log4j logger.", + impact = MBeanOperationInfo.ACTION) + boolean setRuntimeLoggerLevel(@MBeanOperationParameter(name = "logger", description = "Logger name")String logger, + @MBeanOperationParameter(name = "level", description = "Logger level")String level); + + /** + * Retrieves a TabularData set of the active log4j loggers and their levels + * @return TabularData set of CompositeData rows with logger name and level, or null if there is a problem with the TabularData type + */ + @MBeanOperation(name = "viewEffectiveRuntimeLoggerLevels", description = "View the effective runtime logging level " + + "for active log4j logger's.", impact = MBeanOperationInfo.INFO) + TabularData viewEffectiveRuntimeLoggerLevels(); + + /** + * Sets the level of the active Log4J RootLogger + * @param level The level to set the RootLogger to + * @return True if successful, false if unsuccessful (eg if an invalid level is specified) + */ + @MBeanOperation(name = "setRuntimeRootLoggerLevel", description = "Set the runtime logging level for the active log4j Root Logger.", + impact = MBeanOperationInfo.ACTION) + boolean setRuntimeRootLoggerLevel(@MBeanOperationParameter(name = "level", description = "Logger level")String level); + + /** + * Attribute to represent the level of the active Log4J RootLogger + * @return The level of the RootLogger. + */ + @MBeanAttribute(name = "getRuntimeRootLoggerLevel", description = "Get the runtime logging level for the active log4j Root Logger.") + String getRuntimeRootLoggerLevel(); + + + //****** log4j XML configuration file operations ****** // + + /** + * Updates the level of an existing Log4J logger within the xml configuration file + * @param logger The name of the logger + * @param level The level to set the logger to + * @return True if successful, false if unsuccessful (eg if an invalid logger or level is specified) + * @throws IOException if there is an error parsing the configuration file. + */ + @MBeanOperation(name = "setConfigFileLoggerLevel", description = "Set the logging level for an existing logger " + + "in the log4j xml configuration file", impact = MBeanOperationInfo.ACTION) + boolean setConfigFileLoggerLevel(@MBeanOperationParameter(name = "logger", description = "logger name")String logger, + @MBeanOperationParameter(name = "level", description = "Logger level")String level) throws IOException; + + /** + * Retrieves a TabularData set of the existing Log4J loggers within the xml configuration file + * @return TabularData set of CompositeData rows with logger name and level, or null if there is a problem with the TabularData type + * @throws IOException if there is an error parsing the configuration file. + */ + @MBeanOperation(name = "viewConfigFileLoggerLevels", description = "Get the logging level defined for the logger's " + + "in the log4j xml configuration file.", impact = MBeanOperationInfo.INFO) + TabularData viewConfigFileLoggerLevels() throws IOException; + + /** + * Updates the level of the Log4J RootLogger within the xml configuration file if it is present + * @param level The level to set the logger to + * @return True if successful, false if not (eg an invalid level is specified, or root logger level isnt already defined) + * @throws IOException if there is an error parsing the configuration file. + */ + @MBeanOperation(name = "setConfigFileRootLoggerLevel", description = "Set the logging level for the Root Logger " + + "in the log4j xml configuration file.", impact = MBeanOperationInfo.ACTION) + boolean setConfigFileRootLoggerLevel(@MBeanOperationParameter(name = "level", description = "Logger level")String level) throws IOException; + + /** + * Attribute to represent the level of the Log4J RootLogger within the xml configuration file + * @return The level of the RootLogger, or null if it is not present + */ + @MBeanAttribute(name = "getConfigFileRootLoggerLevel", description = "Get the logging level for the Root Logger " + + "in the log4j xml configuration file.") + String getConfigFileRootLoggerLevel() throws IOException; +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java new file mode 100644 index 0000000000..f84cbbd786 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java @@ -0,0 +1,667 @@ +/* + * 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.logging.management; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.AMQManagedObject; + +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.xml.Log4jEntityResolver; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import javax.management.JMException; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + + +/** MBean class for BrokerLoggingManagerMBean. It implements all the management features exposed for managing logging. */ +@MBeanDescription("Logging Management Interface") +public class LoggingManagementMBean extends AMQManagedObject implements LoggingManagement +{ + + private static final Logger _logger = Logger.getLogger(LoggingManagementMBean.class); + private String _log4jConfigFileName; + private int _log4jLogWatchInterval; + + static TabularType _loggerLevelTabularType; + static CompositeType _loggerLevelCompositeType; + + static + { + try + { + OpenType[] loggerLevelItemTypes = new OpenType[]{SimpleType.STRING, SimpleType.STRING}; + + _loggerLevelCompositeType = new CompositeType("LoggerLevelList", "Logger Level Data", + COMPOSITE_ITEM_NAMES, COMPOSITE_ITEM_DESCRIPTIONS, loggerLevelItemTypes); + + _loggerLevelTabularType = new TabularType("LoggerLevel", "List of loggers with levels", + _loggerLevelCompositeType, TABULAR_UNIQUE_INDEX); + } + catch (OpenDataException e) + { + _logger.error("Tabular data setup for viewing logger levels was incorrect."); + _loggerLevelTabularType = null; + } + } + + public LoggingManagementMBean(String log4jConfigFileName, int log4jLogWatchInterval) throws JMException + { + super(LoggingManagement.class, LoggingManagement.TYPE, LoggingManagement.VERSION); + _log4jConfigFileName = log4jConfigFileName; + _log4jLogWatchInterval = log4jLogWatchInterval; + } + + public String getObjectInstanceName() + { + return LoggingManagement.TYPE; + } + + public Integer getLog4jLogWatchInterval() + { + return _log4jLogWatchInterval; + } + + @SuppressWarnings("unchecked") + public synchronized boolean setRuntimeLoggerLevel(String logger, String level) + { + //check specified level is valid + Level newLevel; + try + { + newLevel = getLevel(level); + } + catch (Exception e) + { + return false; + } + + //check specified logger exists + Enumeration loggers = LogManager.getCurrentLoggers(); + Boolean loggerExists = false; + + while(loggers.hasMoreElements()) + { + Logger log = (Logger) loggers.nextElement(); + if (log.getName().equals(logger)) + { + loggerExists = true; + break; + } + } + + if(!loggerExists) + { + return false; + } + + //set the logger to the new level + _logger.info("Setting level to " + level + " for logger: " + logger); + + Logger log = Logger.getLogger(logger); + log.setLevel(newLevel); + + return true; + } + + @SuppressWarnings("unchecked") + public synchronized TabularData viewEffectiveRuntimeLoggerLevels() + { + if (_loggerLevelTabularType == null) + { + _logger.warn("TabluarData type not set up correctly"); + return null; + } + + _logger.info("Getting levels for currently active log4j loggers"); + + Enumeration loggers = LogManager.getCurrentLoggers(); + + TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType); + + Logger logger; + String loggerName; + String level; + + try + { + while(loggers.hasMoreElements()){ + logger = (Logger) loggers.nextElement(); + + loggerName = logger.getName(); + level = logger.getEffectiveLevel().toString(); + + Object[] itemData = {loggerName, level}; + CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData); + loggerLevelList.put(loggerData); + } + } + catch (OpenDataException e) + { + _logger.warn("Unable to create logger level list due to :" + e); + return null; + } + + return loggerLevelList; + + } + + public synchronized String getRuntimeRootLoggerLevel() + { + Logger rootLogger = Logger.getRootLogger(); + + return rootLogger.getLevel().toString(); + } + + public synchronized boolean setRuntimeRootLoggerLevel(String level) + { + Level newLevel; + try + { + newLevel = getLevel(level); + } + catch (Exception e) + { + return false; + } + + _logger.info("Setting RootLogger level to " + level); + + Logger log = Logger.getRootLogger(); + log.setLevel(newLevel); + + return true; + } + + //method to convert from a string to a log4j Level, throws exception if the given value is invalid + private Level getLevel(String level) throws Exception + { + Level newLevel = Level.toLevel(level); + + //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result. + if (newLevel.equals(Level.DEBUG) && !(level.equalsIgnoreCase("debug"))) + { + //received DEBUG but we did not ask for it, the Level request failed. + throw new Exception("Invalid level name"); + } + + return newLevel; + } + + //handler to catch errors signalled by the JAXP parser and throw an appropriate exception + private class SaxErrorHandler implements ErrorHandler + { + + public void error(SAXParseException e) throws SAXException + { + throw new SAXException("Error parsing XML file: " + e.getMessage()); + } + + public void fatalError(SAXParseException e) throws SAXException + { + throw new SAXException("Fatal error parsing XML file: " + e.getMessage()); + } + + public void warning(SAXParseException e) throws SAXException + { + throw new SAXException("Warning parsing XML file: " + e.getMessage()); + } + } + + //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content. + private synchronized Document parseConfigFile(String fileName) throws IOException + { + //check file was specified, exists, and is readable + if(fileName == null) + { + _logger.warn("No log4j XML configuration file has been set"); + throw new IOException("No log4j XML configuration file has been set"); + } + + File configFile = new File(fileName); + + if (!configFile.exists()) + { + _logger.warn("Specified log4j XML configuration file does not exist: " + fileName); + throw new IOException("Specified log4j XML configuration file does not exist"); + } + else if (!configFile.canRead()) + { + _logger.warn("Specified log4j XML configuration file is not readable: " + fileName); + throw new IOException("Specified log4j XML configuration file is not readable"); + } + + //parse it + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder; + Document doc; + + ErrorHandler errHandler = new SaxErrorHandler(); + try + { + docFactory.setValidating(true); + docBuilder = docFactory.newDocumentBuilder(); + docBuilder.setErrorHandler(errHandler); + docBuilder.setEntityResolver(new Log4jEntityResolver()); + doc = docBuilder.parse(fileName); + } + catch (ParserConfigurationException e) + { + _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e); + //recommended that MBeans should use java.* and javax.* exceptions only + throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage()); + } + catch (SAXException e) + { + _logger.warn("The specified log4j XML file is invalid: " + e); + //recommended that MBeans should use standard java.* and javax.* exceptions only + throw new IOException("The specified log4j XML file is invalid: " + e.getMessage()); + } + catch (IOException e) + { + _logger.warn("Unable to parse the specified log4j XML file" + e); + throw new IOException("Unable to parse the specified log4j XML file", e); + } + + return doc; + } + + + private synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException + { + File log4jConfigFile = new File(log4jConfigFileName); + + if (!log4jConfigFile.canWrite()) + { + _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile); + throw new IOException("Specified log4j XML configuration file is not writable"); + } + + Transformer transformer = null; + try + { + transformer = TransformerFactory.newInstance().newTransformer(); + } + catch (Exception e) + { + _logger.warn("Could not create an XML transformer: " +e); + return false; + } + + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd"); + DOMSource source = new DOMSource(doc); + + File tmp; + try + { + tmp = File.createTempFile("LogManMBeanTemp", ".tmp"); + tmp.deleteOnExit(); + StreamResult result = new StreamResult(tmp); + transformer.transform(source, result); + } + catch (TransformerException e) + { + _logger.warn("Could not transform the XML into new file: " +e); + return false; + } + catch (IOException e) + { + _logger.warn("Could not create the new file: " +e); + return false; + } + + // Swap temp file in to replace existing configuration file. + File old = new File(log4jConfigFile.getAbsoluteFile() + ".old"); + if (old.exists()) + { + old.delete(); + } + log4jConfigFile.renameTo(old); + return tmp.renameTo(log4jConfigFile); + } + + + /* The log4j XML configuration file DTD defines three possible element + * combinations for specifying optional logger+level settings. + * Must account for the following: + * + * <category name="x"> <priority value="y"/> </category> OR + * <category name="x"> <level value="y"/> </category> OR + * <logger name="x"> <level value="y"/> </logger> + * + * Noting also that the level/priority child element is optional too, + * and not the only possible child element. + */ + + + public synchronized TabularData viewConfigFileLoggerLevels() throws IOException + { + if (_loggerLevelTabularType == null) + { + _logger.warn("TabluarData type not set up correctly"); + return null; + } + + _logger.info("Getting logger levels from log4j configuration file"); + + Document doc = parseConfigFile(_log4jConfigFileName); + + TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType); + + //retrieve the 'category' element nodes + NodeList categoryElements = doc.getElementsByTagName("category"); + + String categoryName; + String priority = null; + + for (int i = 0; i < categoryElements.getLength(); i++) + { + Element categoryElement = (Element) categoryElements.item(i); + categoryName = categoryElement.getAttribute("name"); + + //retrieve the category's mandatory 'priority' or 'level' element's value. + //It may not be the only child node, so request by tag name. + NodeList priorityElements = categoryElement.getElementsByTagName("priority"); + NodeList levelElements = categoryElement.getElementsByTagName("level"); + + if (priorityElements.getLength() != 0) + { + Element priorityElement = (Element) priorityElements.item(0); + priority = priorityElement.getAttribute("value").toUpperCase(); + } + else if (levelElements.getLength() != 0) + { + Element levelElement = (Element) levelElements.item(0); + priority = levelElement.getAttribute("value").toUpperCase(); + } + else + { + //there is no exiting priority or level to view, move onto next category/logger + continue; + } + + try + { + Object[] itemData = {categoryName, priority}; + CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData); + loggerLevelList.put(loggerData); + } + catch (OpenDataException e) + { + _logger.warn("Unable to create logger level list due to :" + e); + return null; + } + } + + //retrieve the 'logger' element nodes + NodeList loggerElements = doc.getElementsByTagName("logger"); + + String loggerName; + String level; + + for (int i = 0; i < loggerElements.getLength(); i++) + { + Element loggerElement = (Element) loggerElements.item(i); + loggerName = loggerElement.getAttribute("name"); + + //retrieve the logger's mandatory 'level' element's value + //It may not be the only child node, so request by tag name. + NodeList levelElements = loggerElement.getElementsByTagName("level"); + + Element levelElement = (Element) levelElements.item(0); + level = levelElement.getAttribute("value").toUpperCase(); + + try + { + Object[] itemData = {loggerName, level}; + CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData); + loggerLevelList.put(loggerData); + } + catch (OpenDataException e) + { + _logger.warn("Unable to create logger level list due to :" + e); + return null; + } + } + + return loggerLevelList; + } + + public synchronized boolean setConfigFileLoggerLevel(String logger, String level) throws IOException + { + //check that the specified level is a valid log4j Level + try + { + getLevel(level); + } + catch (Exception e) + { + //it isnt a valid level + return false; + } + + _logger.info("Setting level to " + level + " for logger '" + logger + + "' in log4j xml configuration file: " + _log4jConfigFileName); + + Document doc = parseConfigFile(_log4jConfigFileName); + + //retrieve the 'category' and 'logger' element nodes + NodeList categoryElements = doc.getElementsByTagName("category"); + NodeList loggerElements = doc.getElementsByTagName("logger"); + + //collect them into a single elements list + List<Element> logElements = new ArrayList<Element>(); + + for (int i = 0; i < categoryElements.getLength(); i++) + { + logElements.add((Element) categoryElements.item(i)); + } + for (int i = 0; i < loggerElements.getLength(); i++) + { + logElements.add((Element) loggerElements.item(i)); + } + + //try to locate the specified logger/category in the elements retrieved + Element logElement = null; + for (Element e : logElements) + { + if (e.getAttribute("name").equals(logger)) + { + logElement = e; + break; + } + } + + if (logElement == null) + { + //no loggers/categories with given name found, does not exist to update + _logger.warn("Specified logger does not exist in the configuration file: " +logger); + return false; + } + + //retrieve the optional 'priority' or 'level' sub-element value. + //It may not be the only child node, so request by tag name. + NodeList priorityElements = logElement.getElementsByTagName("priority"); + NodeList levelElements = logElement.getElementsByTagName("level"); + + Element levelElement = null; + if (priorityElements.getLength() != 0) + { + levelElement = (Element) priorityElements.item(0); + } + else if (levelElements.getLength() != 0) + { + levelElement = (Element) levelElements.item(0); + } + else + { + //there is no exiting priority or level element to update + return false; + } + + //update the element with the new level/priority + levelElement.setAttribute("value", level); + + //output the new file + return writeUpdatedConfigFile(_log4jConfigFileName, doc); + } + + + /* The log4j XML configuration file DTD defines 2 possible element + * combinations for specifying the optional root logger level settings + * Must account for the following: + * + * <root> <priority value="y"/> </root> OR + * <root> <level value="y"/> </root> + * + * Noting also that the level/priority child element is optional too, + * and not the only possible child element. + */ + + public synchronized String getConfigFileRootLoggerLevel() throws IOException + { + _logger.info("Getting root logger level from log4j configuration file"); + + Document doc = parseConfigFile(_log4jConfigFileName); + + //retrieve the optional 'root' element node + NodeList rootElements = doc.getElementsByTagName("root"); + + if (rootElements.getLength() == 0) + { + //there is not root logger definition + return null; + } + + Element rootElement = (Element) rootElements.item(0); + + //retrieve the optional 'priority' or 'level' element value. + //It may not be the only child node, so request by tag name. + NodeList priorityElements = rootElement.getElementsByTagName("priority"); + NodeList levelElements = rootElement.getElementsByTagName("level"); + String priority = null; + + if (priorityElements.getLength() != 0) + { + Element priorityElement = (Element) priorityElements.item(0); + priority = priorityElement.getAttribute("value"); + } + else if(levelElements.getLength() != 0) + { + Element levelElement = (Element) levelElements.item(0); + priority = levelElement.getAttribute("value"); + } + + if(priority != null) + { + return priority.toUpperCase(); + } + else + { + return null; + } + } + + public synchronized boolean setConfigFileRootLoggerLevel(String level) throws IOException + { + //check that the specified level is a valid log4j Level + try + { + getLevel(level); + } + catch (Exception e) + { + //it isnt a valid level + return false; + } + + _logger.info("Setting level to " + level + " for the Root logger in " + + "log4j xml configuration file: " + _log4jConfigFileName); + + Document doc = parseConfigFile(_log4jConfigFileName); + + //retrieve the optional 'root' element node + NodeList rootElements = doc.getElementsByTagName("root"); + + if (rootElements.getLength() == 0) + { + return false; + } + + Element rootElement = (Element) rootElements.item(0); + + //retrieve the optional 'priority' or 'level' sub-element value. + //It may not be the only child node, so request by tag name. + NodeList priorityElements = rootElement.getElementsByTagName("priority"); + NodeList levelElements = rootElement.getElementsByTagName("level"); + + Element levelElement = null; + if (priorityElements.getLength() != 0) + { + levelElement = (Element) priorityElements.item(0); + } + else if (levelElements.getLength() != 0) + { + levelElement = (Element) levelElements.item(0); + } + else + { + //there is no exiting priority/level to update + return false; + } + + //update the element with the new level/priority + levelElement.setAttribute("value", level); + + //output the new file + return writeUpdatedConfigFile(_log4jConfigFileName, doc); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java index a2c2bd62a2..c6e07f6f48 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java @@ -50,10 +50,10 @@ public abstract class AMQManagedObject extends DefaultManagedObject protected MBeanInfo _mbeanInfo; - protected AMQManagedObject(Class<?> managementInterface, String typeName) + protected AMQManagedObject(Class<?> managementInterface, String typeName, int version) throws NotCompliantMBeanException { - super(managementInterface, typeName); + super(managementInterface, typeName, version); buildMBeanInfo(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java index 84526dbc11..67aee90ba4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java @@ -39,13 +39,15 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana private Class<?> _managementInterface; private String _typeName; + private int _version; - protected DefaultManagedObject(Class<?> managementInterface, String typeName) + protected DefaultManagedObject(Class<?> managementInterface, String typeName, int version) throws NotCompliantMBeanException { super(managementInterface); _managementInterface = managementInterface; _typeName = typeName; + _version = version; } public String getType() @@ -115,6 +117,10 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana objectName.append(getHierarchicalName(this)); objectName.append("name=").append(name); + objectName.append(","); + objectName.append("version=").append(_version); + + return new ObjectName(objectName.toString()); } @@ -132,6 +138,9 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana objectName.append(hierarchyName.substring(0, hierarchyName.lastIndexOf(","))); } + objectName.append(","); + objectName.append("version=").append(_version); + return new ObjectName(objectName.toString()); } 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 a0d2c7dc66..3fc460b325 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 @@ -32,9 +32,12 @@ import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser; import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser; +import javax.management.InstanceNotFoundException; import javax.management.JMException; +import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; +import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; @@ -85,7 +88,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry IApplicationRegistry appRegistry = ApplicationRegistry.getInstance(); // Retrieve the config parameters - boolean platformServer = appRegistry.getConfiguration().getBoolean("management.platform-mbeanserver", true); + boolean platformServer = appRegistry.getConfiguration().getPlatformMbeanserver(); _mbeanServer = platformServer ? ManagementFactory.getPlatformMBeanServer() @@ -104,196 +107,164 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry } IApplicationRegistry appRegistry = ApplicationRegistry.getInstance(); - - boolean jmxmpSecurity = appRegistry.getConfiguration().getBoolean("management.security-enabled", false); - int port = appRegistry.getConfiguration().getInt(MANAGEMENT_PORT_CONFIG_PATH, MANAGEMENT_PORT_DEFAULT); + int port = appRegistry.getConfiguration().getJMXManagementPort(); //retrieve the Principal Database assigned to JMX authentication duties - String jmxDatabaseName = appRegistry.getConfiguration().getString("security.jmx.principal-database"); + String jmxDatabaseName = appRegistry.getConfiguration().getJMXPrincipalDatabase(); Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases(); PrincipalDatabase db = map.get(jmxDatabaseName); final JMXConnectorServer cs; HashMap<String,Object> env = new HashMap<String,Object>(); - if (jmxmpSecurity) + //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration + RMIClientSocketFactory csf; + RMIServerSocketFactory ssf; + + //check ssl enabled option in config, default to true if option is not set + boolean sslEnabled = appRegistry.getConfiguration().getManagementSSLEnabled(); + + if (sslEnabled) { - // For SASL using JMXMP - JMXServiceURL jmxURL = new JMXServiceURL("jmxmp", null, port); + //set the SSL related system properties used by the SSL RMI socket factories to the values + //given in the configuration file, unless command line settings have already been specified + String keyStorePath; - String saslType = null; - if (db instanceof Base64MD5PasswordFilePrincipalDatabase) + if(System.getProperty("javax.net.ssl.keyStore") != null) { - saslType = "SASL/CRAM-MD5"; - env.put("jmx.remote.profiles", "SASL/CRAM-MD5"); - CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser(); - initialiser.initialise(db); - env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler()); + keyStorePath = System.getProperty("javax.net.ssl.keyStore"); } - else if (db instanceof PlainPasswordFilePrincipalDatabase) + else { - saslType = "SASL/PLAIN"; - PlainInitialiser initialiser = new PlainInitialiser(); - initialiser.initialise(db); - env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler()); - env.put("jmx.remote.profiles", "SASL/PLAIN"); + keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath(); } - //workaround NPE generated from env map classloader issue when using Eclipse 3.4 to launch - env.put("jmx.remote.profile.provider.class.loader", this.getClass().getClassLoader()); - - _log.warn("Starting JMXMP based JMX ConnectorServer on port '" + port + "' with " + saslType); - _startupLog.warn("Starting JMXMP based JMX ConnectorServer on port '" + port + "' with " + saslType); - - cs = JMXConnectorServerFactory.newJMXConnectorServer(jmxURL, env, _mbeanServer); - } - else - { - //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration - RMIClientSocketFactory csf; - RMIServerSocketFactory ssf; - - //check ssl enabled option in config, default to true if option is not set - boolean sslEnabled = appRegistry.getConfiguration().getBoolean("management.ssl.enabled", true); - - if (sslEnabled) + //check the keystore path value is valid + if (keyStorePath == null) { - //set the SSL related system properties used by the SSL RMI socket factories to the values - //given in the configuration file, unless command line settings have already been specified - String keyStorePath; - - if(System.getProperty("javax.net.ssl.keyStore") != null) + throw new ConfigurationException("JMX management SSL keystore path not defined, " + + "unable to start SSL protected JMX ConnectorServer"); + } + else + { + //ensure the system property is set + System.setProperty("javax.net.ssl.keyStore", keyStorePath); + + //check the file is usable + File ksf = new File(keyStorePath); + + if (!ksf.exists()) { - keyStorePath = System.getProperty("javax.net.ssl.keyStore"); + throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf + "\n" + + "Check broker configuration, or see create-example-ssl-stores script" + + "in the bin/ directory if you need to generate an example store."); } - else{ - keyStorePath = appRegistry.getConfiguration().getString("management.ssl.keyStorePath", null); + if (!ksf.canRead()) + { + throw new FileNotFoundException("Cannot read JMX management SSL keystore file: " + + ksf + ". Check permissions."); } - //check the keystore path value is valid - if (keyStorePath == null) + _log.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath()); + _startupLog.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath()); + } + + //check the key store password is set + if (System.getProperty("javax.net.ssl.keyStorePassword") == null) + { + + if (appRegistry.getConfiguration().getManagementKeyStorePassword() == null) { - throw new ConfigurationException("JMX management SSL keystore path not defined, " + - "unable to start SSL protected JMX ConnectorServer"); + throw new ConfigurationException("JMX management SSL keystore password not defined, " + + "unable to start requested SSL protected JMX server"); } else { - //ensure the system property is set - System.setProperty("javax.net.ssl.keyStore", keyStorePath); - - //check the file is usable - File ksf = new File(keyStorePath); - - if (!ksf.exists()) - { - throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf); - } - if (!ksf.canRead()) - { - throw new FileNotFoundException("Cannot read JMX management SSL keystore file: " - + ksf + ". Check permissions."); - } - - _log.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath()); - _startupLog.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath()); + System.setProperty("javax.net.ssl.keyStorePassword", + appRegistry.getConfiguration().getManagementKeyStorePassword()); } + } - //check the key store password is set - if (System.getProperty("javax.net.ssl.keyStorePassword") == null) - { - - if (appRegistry.getConfiguration().getString("management.ssl.keyStorePassword") == null) - { - throw new ConfigurationException("JMX management SSL keystore password not defined, " + - "unable to start requested SSL protected JMX server"); - } - else - { - System.setProperty("javax.net.ssl.keyStorePassword", - appRegistry.getConfiguration().getString("management.ssl.keyStorePassword")); - } - } + //create the SSL RMI socket factories + csf = new SslRMIClientSocketFactory(); + ssf = new SslRMIServerSocketFactory(); + + _log.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" + + (port +PORT_EXPORT_OFFSET) + ") with SSL"); + _startupLog.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" + + (port +PORT_EXPORT_OFFSET) + ") with SSL"); + } + else + { + //Do not specify any specific RMI socket factories, resulting in use of the defaults. + csf = null; + ssf = null; - //create the SSL RMI socket factories - csf = new SslRMIClientSocketFactory(); - ssf = new SslRMIServerSocketFactory(); + _log.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")"); + _startupLog.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")"); + } - _log.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" + - (port +PORT_EXPORT_OFFSET) + ") with SSL"); - _startupLog.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" + - (port +PORT_EXPORT_OFFSET) + ") with SSL"); - } - else - { - //Do not specify any specific RMI socket factories, resulting in use of the defaults. - csf = null; - ssf = null; - - _log.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")"); - _startupLog.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")"); - } - - //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server - RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(); - rmipa.setPrincipalDatabase(db); - env.put(JMXConnectorServer.AUTHENTICATOR, rmipa); - - /* - * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub. - * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI. - * As a result, only binds made using the object reference will succeed, thus securing it from external change. - */ - System.setProperty("java.rmi.server.randomIDs", "true"); - _rmiRegistry = LocateRegistry.createRegistry(port, null, new CustomRMIServerSocketFactory()); - - /* - * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls - * to bind the ConnectorServer to the registry, which will now fail as for security we have - * locked it from any RMI based modifications, including our own. Instead, we will manually bind - * the RMIConnectorServer stub to the registry using its object reference, which will still succeed. - * - * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer - * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's. - */ - final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(port+PORT_EXPORT_OFFSET, csf, ssf, env); - final String hostname = InetAddress.getLocalHost().getHostName(); - final JMXServiceURL externalUrl = new JMXServiceURL( - "service:jmx:rmi://"+hostname+":"+(port+PORT_EXPORT_OFFSET)+"/jndi/rmi://"+hostname+":"+port+"/jmxrmi"); - - final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port+PORT_EXPORT_OFFSET); - cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer) + //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server + RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(); + rmipa.setPrincipalDatabase(db); + env.put(JMXConnectorServer.AUTHENTICATOR, rmipa); + + /* + * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub. + * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI. + * As a result, only binds made using the object reference will succeed, thus securing it from external change. + */ + System.setProperty("java.rmi.server.randomIDs", "true"); + _rmiRegistry = LocateRegistry.createRegistry(port, null, new CustomRMIServerSocketFactory()); + + /* + * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls + * to bind the ConnectorServer to the registry, which will now fail as for security we have + * locked it from any RMI based modifications, including our own. Instead, we will manually bind + * the RMIConnectorServer stub to the registry using its object reference, which will still succeed. + * + * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer + * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's. + */ + final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(port+PORT_EXPORT_OFFSET, csf, ssf, env); + final String hostname = InetAddress.getLocalHost().getHostName(); + final JMXServiceURL externalUrl = new JMXServiceURL( + "service:jmx:rmi://"+hostname+":"+(port+PORT_EXPORT_OFFSET)+"/jndi/rmi://"+hostname+":"+port+"/jmxrmi"); + + final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port+PORT_EXPORT_OFFSET); + cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer) + { + @Override + public synchronized void start() throws IOException { - @Override - public synchronized void start() throws IOException + try { - try - { - //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent - _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub); - } - catch (AlreadyBoundException abe) - { - //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means. - - //IOExceptions are the only checked type throwable by the method, wrap and rethrow - IOException ioe = new IOException(abe.getMessage()); - ioe.initCause(abe); - throw ioe; - } - - //now do the normal tasks - super.start(); - } - - @Override - public JMXServiceURL getAddress() - { - //must return our pre-crafted url that includes the full details, inc JNDI details - return externalUrl; - } + //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent + _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub); + } + catch (AlreadyBoundException abe) + { + //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means. - }; - } + //IOExceptions are the only checked type throwable by the method, wrap and rethrow + IOException ioe = new IOException(abe.getMessage()); + ioe.initCause(abe); + throw ioe; + } + + //now do the normal tasks + super.start(); + } + + @Override + public JMXServiceURL getAddress() + { + //must return our pre-crafted url that includes the full details, inc JNDI details + return externalUrl; + } + + }; + //Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer. MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance(); @@ -379,6 +350,17 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry // Stopping the RMI registry UnicastRemoteObject.unexportObject(_rmiRegistry, true); } + for (ObjectName name : _mbeanServer.queryNames(null, null)) + { + try + { + _mbeanServer.unregisterMBean(name); + } + catch (JMException e) + { + // Really shouldn't happen, but we'll ignore that... + } + } } } 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 a0ecc2bd85..e9b4d85e66 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 @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.management; +import org.apache.qpid.server.configuration.management.ConfigurationManagement; +import org.apache.qpid.server.logging.management.LoggingManagement; import org.apache.qpid.server.security.access.management.UserManagement; import org.apache.log4j.Logger; @@ -37,6 +39,8 @@ import java.lang.reflect.Method; import java.security.AccessController; import java.security.Principal; import java.security.AccessControlContext; +import java.util.ArrayList; +import java.util.HashSet; import java.util.Set; import java.util.Properties; @@ -53,9 +57,16 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler public final static String READWRITE = "readwrite"; public final static String READONLY = "readonly"; private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate"; - private MBeanServer mbs; + private MBeanServer _mbs; private static Properties _userRoles = new Properties(); + private static HashSet<String> _adminOnlyMethods = new HashSet<String>(); + { + _adminOnlyMethods.add(UserManagement.TYPE); + _adminOnlyMethods.add(LoggingManagement.TYPE); + _adminOnlyMethods.add(ConfigurationManagement.TYPE); + } + public static MBeanServerForwarder newProxyInstance() { final InvocationHandler handler = new MBeanInvocationHandlerImpl(); @@ -71,7 +82,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler if (methodName.equals("getMBeanServer")) { - return mbs; + return _mbs; } if (methodName.equals("setMBeanServer")) @@ -80,11 +91,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler { throw new IllegalArgumentException("Null MBeanServer"); } - if (mbs != null) + if (_mbs != null) { throw new IllegalArgumentException("MBeanServer object already initialized"); } - mbs = (MBeanServer) args[0]; + _mbs = (MBeanServer) args[0]; return null; } @@ -95,12 +106,12 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler // Allow operations performed locally on behalf of the connector server itself if (subject == null) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } if (args == null || DELEGATE.equals(args[0])) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } // Restrict access to "createMBean" and "unregisterMBean" to any user @@ -124,7 +135,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler { if (isAdmin(identity)) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } else { @@ -135,14 +146,14 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler // Following users can perform any operation other than "createMBean" and "unregisterMBean" if (isAllowedToModify(identity)) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } // These users can only call "getAttribute" on the MBeanServerDelegate MBean // Here we can add other fine grained permissions like specific method for a particular mbean if (isReadOnlyUser(identity) && isReadOnlyMethod(method, args)) { - return method.invoke(mbs, args); + return method.invoke(_mbs, args); } throw new SecurityException("Access denied"); @@ -153,9 +164,9 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler if (args[0] instanceof ObjectName) { ObjectName object = (ObjectName) args[0]; - return UserManagement.TYPE.equals(object.getKeyProperty("type")); + + return _adminOnlyMethods.contains(object.getKeyProperty("type")); } - return false; } @@ -196,7 +207,10 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler private boolean isReadOnlyMethod(Method method, Object[] args) { String methodName = method.getName(); - if (methodName.startsWith("query") || methodName.startsWith("get")) + + //handle standard get/set/query and select 'is' methods from MBeanServer + if (methodName.startsWith("query") || methodName.startsWith("get") + ||methodName.startsWith("isInstanceOf") || methodName.startsWith("isRegistered")) { return true; } @@ -205,8 +219,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler return false; } + //handle invocation of other methods on mbeans if ((args[0] instanceof ObjectName) && (methodName.equals("invoke"))) { + + //get invoked method name String mbeanMethod = (args.length > 1) ? (String) args[1] : null; if (mbeanMethod == null) { @@ -215,7 +232,8 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler try { - MBeanInfo mbeanInfo = mbs.getMBeanInfo((ObjectName) args[0]); + //check if the given method is tagged with an INFO impact attribute + MBeanInfo mbeanInfo = _mbs.getMBeanInfo((ObjectName) args[0]); if (mbeanInfo != null) { MBeanOperationInfo[] opInfos = mbeanInfo.getOperations(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java index 45e2e91ed7..c18417fc43 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java @@ -40,12 +40,13 @@ public interface ManagedBroker { static final String TYPE = "VirtualHostManager"; + static final int VERSION = 1 ; + /** * Creates a new Exchange. * @param name * @param type * @param durable - * @param passive * @throws IOException * @throws JMException */ @@ -73,7 +74,6 @@ public interface ManagedBroker * @param queueName * @param durable * @param owner - * @param autoDelete * @throws IOException * @throws JMException */ diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java index 1b7919e8b7..dbfcefb6ab 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java @@ -34,7 +34,9 @@ import org.apache.qpid.server.security.access.ACLPlugin; import org.apache.qpid.server.security.access.ACLPluginFactory; import org.apache.qpid.server.security.access.plugins.AllowAll; import org.apache.qpid.server.security.access.plugins.DenyAll; +import org.apache.qpid.server.security.access.plugins.LegacyAccessPlugin; import org.apache.qpid.server.security.access.plugins.SimpleXML; +import org.apache.qpid.server.security.access.plugins.network.FirewallPlugin; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleException; import org.osgi.util.tracker.ServiceTracker; @@ -165,6 +167,8 @@ public class PluginManager _securityPlugins.put(SimpleXML.class.getName(), SimpleXML.FACTORY); _securityPlugins.put(AllowAll.class.getName(), AllowAll.FACTORY); _securityPlugins.put(DenyAll.class.getName(), DenyAll.FACTORY); + _securityPlugins.put(LegacyAccessPlugin.class.getName(), LegacyAccessPlugin.FACTORY); + _securityPlugins.put(FirewallPlugin.class.getName(), FirewallPlugin.FACTORY); } return _securityPlugins; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index 4b69842c49..205ca73f13 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -582,7 +582,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable if (delay > 0) { _minaProtocolSession.setIdleTime(IdleStatus.WRITER_IDLE, delay); - _minaProtocolSession.setIdleTime(IdleStatus.READER_IDLE, HeartbeatConfig.getInstance().getTimeout(delay)); + _minaProtocolSession.setIdleTime(IdleStatus.READER_IDLE, (int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay)); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java index d8dbf97e49..0dbefd8798 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java @@ -20,6 +20,9 @@ */ package org.apache.qpid.server.protocol; +import java.io.IOException; +import java.net.InetSocketAddress; + import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; import org.apache.mina.common.IdleStatus; @@ -34,15 +37,19 @@ import org.apache.mina.filter.executor.ExecutorFilter; import org.apache.mina.util.SessionUtil; import org.apache.qpid.AMQException; import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.framing.AMQProtocolHeaderException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.HeartbeatBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.ProtocolInitiation; +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.transport.ConnectorConfiguration; import org.apache.qpid.ssl.SSLContextFactory; -import java.io.IOException; -import java.net.InetSocketAddress; - /** * The protocol handler handles "protocol events" for all connections. The state * associated with an individual connection is accessed through the protocol session. @@ -56,9 +63,6 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter private final IApplicationRegistry _applicationRegistry; - private static String DEFAULT_BUFFER_READ_LIMIT_SIZE = "262144"; - private static String DEFAULT_BUFFER_WRITE_LIMIT_SIZE = "262144"; - private final int BUFFER_READ_LIMIT_SIZE; private final int BUFFER_WRITE_LIMIT_SIZE; @@ -72,8 +76,8 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter _applicationRegistry = applicationRegistry; // Read the configuration from the application registry - BUFFER_READ_LIMIT_SIZE = Integer.parseInt(_applicationRegistry.getConfiguration().getString("broker.connector.protectio.readBufferLimitSize", DEFAULT_BUFFER_READ_LIMIT_SIZE)); - BUFFER_WRITE_LIMIT_SIZE = Integer.parseInt(_applicationRegistry.getConfiguration().getString("broker.connector.protectio.writeBufferLimitSize", DEFAULT_BUFFER_WRITE_LIMIT_SIZE)); + BUFFER_READ_LIMIT_SIZE = _applicationRegistry.getConfiguration().getBufferReadLimit(); + BUFFER_WRITE_LIMIT_SIZE = _applicationRegistry.getConfiguration().getBufferWriteLimit(); _logger.debug("AMQPFastProtocolHandler created"); } @@ -92,17 +96,22 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter _logger.info("Protocol session created for:" + protocolSession.getRemoteAddress()); final QpidProtocolCodecFilter pcf = new QpidProtocolCodecFilter(codecFactory); - - ConnectorConfiguration connectorConfig = ApplicationRegistry.getInstance(). - getConfiguredObject(ConnectorConfiguration.class); - if (connectorConfig.enableExecutorPool) + final ServerConfiguration config = _applicationRegistry.getConfiguration(); + + String keystorePath = config.getKeystorePath(); + String keystorePassword = config.getKeystorePassword(); + String certType = config.getCertType(); + SSLContextFactory sslContextFactory = null; + boolean isSsl = false; + if (config.getEnableSSL() && isSSLClient(config, protocolSession)) { - if (connectorConfig.enableSSL && isSSLClient(connectorConfig, protocolSession)) + sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType); + isSsl = true; + } + if (config.getEnableExecutorPool()) + { + if (isSsl) { - String keystorePath = connectorConfig.keystorePath; - String keystorePassword = connectorConfig.keystorePassword; - String certType = connectorConfig.certType; - SSLContextFactory sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType); protocolSession.getFilterChain().addAfter("AsynchronousReadFilter", "sslFilter", new SSLFilter(sslContextFactory.buildServerContext())); } @@ -111,19 +120,14 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter else { protocolSession.getFilterChain().addLast("protocolFilter", pcf); - if (connectorConfig.enableSSL && isSSLClient(connectorConfig, protocolSession)) + if (isSsl) { - String keystorePath = connectorConfig.keystorePath; - String keystorePassword = connectorConfig.keystorePassword; - String certType = connectorConfig.certType; - SSLContextFactory sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType); protocolSession.getFilterChain().addBefore("protocolFilter", "sslFilter", new SSLFilter(sslContextFactory.buildServerContext())); } - } - if (ApplicationRegistry.getInstance().getConfiguration().getBoolean("broker.connector.protectio.enabled", false)) + if (ApplicationRegistry.getInstance().getConfiguration().getProtectIOEnabled()) { try { @@ -271,10 +275,10 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter } } - protected boolean isSSLClient(ConnectorConfiguration connectionConfig, + protected boolean isSSLClient(ServerConfiguration connectionConfig, IoSession protocolSession) { InetSocketAddress addr = (InetSocketAddress) protocolSession.getLocalAddress(); - return addr.getPort() == connectionConfig.sslPort; + return addr.getPort() == connectionConfig.getSSLPort(); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java index bd072985c4..5dd3cc075a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java @@ -37,7 +37,6 @@ */ package org.apache.qpid.server.protocol; -import java.security.Principal; import java.util.Date; import java.util.List; @@ -58,7 +57,6 @@ import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.MethodRegistry; @@ -93,7 +91,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed @MBeanConstructor("Creates an MBean exposing an AMQ Broker Connection") public AMQProtocolSessionMBean(AMQMinaProtocolSession session) throws NotCompliantMBeanException, OpenDataException { - super(ManagedConnection.class, ManagedConnection.TYPE); + super(ManagedConnection.class, ManagedConnection.TYPE, ManagedConnection.VERSION); _session = session; String remote = getRemoteAddress(); remote = "anonymous".equals(remote) ? (remote + hashCode()) : remote; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java deleted file mode 100644 index 310deaaf55..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.protocol; - -import org.apache.qpid.configuration.Configured; -import org.apache.qpid.server.registry.ApplicationRegistry; - -public class HeartbeatConfig -{ - @Configured(path = "heartbeat.delay", defaultValue = "5") - public int delay = 5;//in secs - @Configured(path = "heartbeat.timeoutFactor", defaultValue = "2.0") - public double timeoutFactor = 2; - - public double getTimeoutFactor() - { - return timeoutFactor; - } - - public void setTimeoutFactor(double timeoutFactor) - { - this.timeoutFactor = timeoutFactor; - } - - public int getDelay() - { - return delay; - } - - public void setDelay(int delay) - { - this.delay = delay; - } - - int getTimeout(int writeDelay) - { - return (int) (timeoutFactor * writeDelay); - } - - public static HeartbeatConfig getInstance() - { - return ApplicationRegistry.getInstance().getConfiguredObject(HeartbeatConfig.class); - } - - public String toString() - { - return "HeartBeatConfig{delay = " + delay + " timeoutFactor = " + timeoutFactor + "}"; - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java index e6e713ac6d..e75b09a0cb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java @@ -41,6 +41,7 @@ import org.apache.qpid.server.management.MBeanOperationParameter; public interface ManagedConnection { static final String TYPE = "Connection"; + static final int VERSION = 1; @MBeanAttribute(name = "ClientId", description = "Client Id") String getClientId(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java index 2bd6e612f8..8dac12fe24 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java @@ -60,30 +60,6 @@ public interface AMQMessage //Check the status of this message - /** - * Called selectors to determin if the message has already been sent - * - * @return _deliveredToConsumer - */ - boolean getDeliveredToConsumer(); - - /** - * Called to enforce the 'immediate' flag. - * - * @returns true if the message is marked for immediate delivery but has not been marked as delivered - * to a consumer - */ - boolean immediateAndNotDelivered(); - - /** - * Checks to see if the message has expired. If it has the message is dequeued. - * - * @return true if the message has expire - * - * @throws org.apache.qpid.AMQException - */ - boolean expired() throws AMQException; - /** Is this a persistent message * * @return true if the message is persistent @@ -91,13 +67,8 @@ public interface AMQMessage boolean isPersistent(); - /** - * Called when this message is delivered to a consumer. (used to implement the 'immediate' flag functionality). - * And for selector efficiency. - */ - void setDeliveredToConsumer(); + boolean isImmediate(); - void setExpiration(long expiration); void setClientIdentifier(AMQProtocolSession.ProtocolSessionIdentifier sessionIdentifier); @@ -113,22 +84,16 @@ public interface AMQMessage void addContentBodyFrame(StoreContext storeContext, ContentChunk contentChunk, boolean isLastContentBody) throws AMQException; + void recoverFromMessageMetaData(MessageMetaData mmd); + + void recoverContentBodyFrame(ContentChunk contentChunk, boolean isLastContentBody) throws AMQException; - void removeMessage(StoreContext storeContext) throws AMQException; String toString(); String debugIdentity(); - // Reference counting methods - - void decrementReference(StoreContext storeContext) throws MessageCleanupException; - - boolean incrementReference(int queueCount); - - boolean incrementReference(); - - AMQMessage takeReference(); + void setExpiration(long expiration); - boolean isReferenced(); + long getExpiration(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java deleted file mode 100644 index 93ac21fc7c..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.queue; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.framing.abstraction.ContentChunk; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; - -/** - * A pluggable way of getting message data. Implementations can provide intelligent caching for example or - * even no caching at all to minimise the broker memory footprint. - */ -public interface AMQMessageHandle -{ - ContentHeaderBody getContentHeaderBody(StoreContext context) throws AMQException; - - /** - * - * @return the messageId for the message associated with this handle - */ - Long getMessageId(); - - - /** - * @return the number of body frames associated with this message - */ - int getBodyCount(StoreContext context) throws AMQException; - - /** - * @return the size of the body - */ - long getBodySize(StoreContext context) throws AMQException; - - /** - * Get a particular content body - * @param index the index of the body to retrieve, must be between 0 and getBodyCount() - 1 - * @return a content body - * @throws IllegalArgumentException if the index is invalid - */ - ContentChunk getContentChunk(StoreContext context, int index) throws IllegalArgumentException, AMQException; - - void addContentBodyFrame(StoreContext storeContext, ContentChunk contentBody, boolean isLastContentBody) throws AMQException; - - MessagePublishInfo getMessagePublishInfo(StoreContext context) throws AMQException; - - boolean isPersistent(); - - void setPublishAndContentHeaderBody(StoreContext storeContext, MessagePublishInfo messagePublishInfo, - ContentHeaderBody contentHeaderBody) - throws AMQException; - - void removeMessage(StoreContext storeContext) throws AMQException; - - long getArrivalTime(); -} 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 34a70c6969..00dec57ed5 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 @@ -36,12 +36,12 @@ public class AMQPriorityQueue extends SimpleAMQQueue int priorities) throws AMQException { - super(name, durable, owner, autoDelete, virtualHost, new PriorityQueueList.Factory(priorities)); + super(name, durable, owner, autoDelete, virtualHost, new PriorityQueueEntryList.Factory(priorities)); } public int getPriorities() { - return ((PriorityQueueList) _entries).getPriorities(); + return ((PriorityQueueEntryList) _entries).getPriorities(); } @Override @@ -68,4 +68,10 @@ public class AMQPriorityQueue extends SimpleAMQQueue } } + @Override + public String getType() + { + return getClass().getSimpleName() + "[" + getName() + "][Priorities:" + getPriorities() + "]"; + } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java index 2d4a9c4b40..43ec6c4d15 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java @@ -20,9 +20,10 @@ */ package org.apache.qpid.server.queue; -import org.apache.commons.configuration.Configuration; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.configuration.QueueConfiguration; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.subscription.Subscription; @@ -67,6 +68,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> boolean isEmpty(); + boolean isFlowed(); + int getMessageCount(); int getUndeliveredMessageCount(); @@ -80,25 +83,18 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> boolean isDeleted(); - int delete() throws AMQException; - QueueEntry enqueue(StoreContext storeContext, AMQMessage message) throws AMQException; void requeue(StoreContext storeContext, QueueEntry entry) throws AMQException; void dequeue(StoreContext storeContext, QueueEntry entry) throws FailedDequeueException; - - boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException; - - void addQueueDeleteTask(final Task task); - List<QueueEntry> getMessagesOnTheQueue(); List<QueueEntry> getMessagesOnTheQueue(long fromMessageId, long toMessageId); @@ -117,7 +113,15 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> void removeMessagesFromQueue(long fromMessageId, long toMessageId, StoreContext storeContext); + long getMemoryUsageMaximum(); + void setMemoryUsageMaximum(long maximumMemoryUsage); + + long getMemoryUsageMinimum(); + + void setMemoryUsageMinimum(long minimumMemoryUsage); + + long getMemoryUsageCurrent(); long getMaximumMessageSize(); @@ -141,6 +145,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> long getMinimumAlertRepeatGap(); + void setMinimumAlertRepeatGap(long value); + void deleteMessageFromTop(StoreContext storeContext) throws AMQException; @@ -162,7 +168,6 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> void stop(); - /** * ExistingExclusiveSubscription signals a failure to create a subscription, because an exclusive subscription * already exists. @@ -210,6 +215,4 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> { public void doTask(AMQQueue queue) throws AMQException; } - - void configure(Configuration virtualHostDefaultQueueConfiguration); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java index be8c19d18f..6ba22321f1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java @@ -20,45 +20,49 @@ */ package org.apache.qpid.server.queue; -import org.apache.commons.configuration.Configuration; +import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.configuration.QueueConfiguration; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.AMQException; - public class AMQQueueFactory { public static final AMQShortString X_QPID_PRIORITIES = new AMQShortString("x-qpid-priorities"); + public static final AMQShortString QPID_MAX_COUNT = new AMQShortString("qpid.max_count"); + public static final AMQShortString QPID_MAX_SIZE = new AMQShortString("qpid.max_size"); + public static final AMQShortString QPID_POLICY_TYPE = new AMQShortString("qpid.policy_type"); + public static final String QPID_FLOW_TO_DISK = "flow_to_disk"; public static AMQQueue createAMQQueueImpl(AMQShortString name, - boolean durable, - AMQShortString owner, - boolean autoDelete, - VirtualHost virtualHost, final FieldTable arguments) - - throws AMQException - { - - return createAMQQueueImpl(name, durable, owner, autoDelete, - virtualHost, arguments, - VirtualHostConfiguration.getDefaultQueueConfiguration(virtualHost)); - } - - public static AMQQueue createAMQQueueImpl(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, - VirtualHost virtualHost, final FieldTable arguments, - Configuration queueConfiguration) + VirtualHost virtualHost, final FieldTable arguments) throws AMQException { - final int priorities = arguments == null ? 1 : arguments.containsKey(X_QPID_PRIORITIES) ? arguments.getInteger(X_QPID_PRIORITIES) : 1; + int priorities = 1; + + if (arguments != null && arguments.containsKey(X_QPID_PRIORITIES)) + { + Integer priority = arguments.getInteger(X_QPID_PRIORITIES); + + if (priority != null) + { + priorities = priority.intValue(); + } + else + { + throw new AMQException(AMQConstant.INVALID_ARGUMENT, + "Queue create request with non integer value for :" + X_QPID_PRIORITIES + "=" + arguments.get(X_QPID_PRIORITIES), null); + } + + } AMQQueue q = null; - if(priorities > 1) + if (priorities > 1) { q = new AMQPriorityQueue(name, durable, owner, autoDelete, virtualHost, priorities); } @@ -66,13 +70,77 @@ public class AMQQueueFactory { q = new SimpleAMQQueue(name, durable, owner, autoDelete, virtualHost); } - if (q != null && queueConfiguration != null) + + final String queuePolicyType = arguments == null ? null : + arguments.containsKey(QPID_POLICY_TYPE) ? arguments.getString(QPID_POLICY_TYPE) : null; + + if (queuePolicyType != null) { - q.configure(queueConfiguration); + if (queuePolicyType.equals(QPID_FLOW_TO_DISK)) + { + if (arguments.containsKey(QPID_MAX_SIZE)) + { + + final long queueSize = arguments.getInteger(QPID_MAX_SIZE); + + if (queueSize < 0) + { + throw new AMQException(AMQConstant.INVALID_ARGUMENT, + "Queue create request with negative size:" + queueSize, null); + } + + q.setMemoryUsageMaximum(queueSize); + } + else + { + throw new AMQException(AMQConstant.INVALID_ARGUMENT, + "Queue create request with no qpid.max_size value,", null); + } + } + else + { + throw new AMQException(AMQConstant.NOT_IMPLEMENTED, + "Queue create request with unknown Policy Type:" + queuePolicyType, null); + } + } //Register the new queue virtualHost.getQueueRegistry().registerQueue(q); return q; } + + public static AMQQueue createAMQQueueImpl(QueueConfiguration config, VirtualHost host) throws AMQException + { + AMQShortString queueName = new AMQShortString(config.getName()); + + boolean durable = config.getDurable(); + boolean autodelete = config.getAutoDelete(); + AMQShortString owner = (config.getOwner() != null) ? new AMQShortString(config.getOwner()) : null; + FieldTable arguments = null; + boolean priority = config.getPriority(); + int priorities = config.getPriorities(); + if (priority || priorities > 0) + { + if (arguments == null) + { + arguments = new FieldTable(); + } + if (priorities < 0) + { + priorities = 10; + } + arguments.put(new AMQShortString("x-qpid-priorities"), priorities); + } + + AMQQueue q = createAMQQueueImpl(queueName, durable, owner, autodelete, host, arguments); + q.setMaximumMessageAge(config.getMaximumMessageAge()); + q.setMaximumQueueDepth(config.getMaximumQueueDepth()); + q.setMaximumMessageSize(config.getMaximumMessageSize()); + q.setMaximumMessageCount(config.getMaximumMessageCount()); + q.setMinimumAlertRepeatGap(config.getMinimumAlertRepeatGap()); + q.setMemoryUsageMaximum(config.getMemoryUsageMaximum()); + q.setMemoryUsageMinimum(config.getMemoryUsageMinimum()); + return q; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java index a08719875d..2ff54fb748 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java @@ -100,7 +100,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que @MBeanConstructor("Creates an MBean exposing an AMQQueue") public AMQQueueMBean(AMQQueue queue) throws JMException { - super(ManagedQueue.class, ManagedQueue.TYPE); + super(ManagedQueue.class, ManagedQueue.TYPE, ManagedQueue.VERSION); _queue = queue; _queueName = jmxEncode(new StringBuffer(queue.getName()), 0).toString(); } @@ -221,11 +221,12 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que _queue.setMaximumMessageCount(value); } + /** + * returns the maximum total size of messages(bytes) in the queue. + */ public Long getMaximumQueueDepth() { - long queueDepthInBytes = _queue.getMaximumQueueDepth(); - - return queueDepthInBytes >> 10; + return _queue.getMaximumQueueDepth(); } public void setMaximumQueueDepth(Long value) @@ -233,20 +234,49 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que _queue.setMaximumQueueDepth(value); } + public Long getMemoryUsageMaximum() + { + return _queue.getMemoryUsageMaximum(); + } + + public void setMemoryUsageMaximum(Long maximumMemoryUsage) + { + _queue.setMemoryUsageMaximum(maximumMemoryUsage); + } + + public Long getMemoryUsageMinimum() + { + return _queue.getMemoryUsageMinimum(); + } + + public void setMemoryUsageMinimum(Long minimumMemoryUsage) + { + _queue.setMemoryUsageMinimum(minimumMemoryUsage); + } + + public Long getMemoryUsageCurrent() + { + return _queue.getMemoryUsageCurrent(); + } + + public boolean isFlowed() + { + return _queue.isFlowed(); + } + /** - * returns the size of messages(KB) in the queue. + * returns the total size of messages(bytes) in the queue. */ public Long getQueueDepth() throws JMException { - long queueBytesSize = _queue.getQueueDepth(); - - return queueBytesSize >> 10; + return _queue.getQueueDepth(); } /** * Checks if there is any notification to be send to the listeners + * @param queueEntry */ - public void checkForNotification(AMQMessage msg) throws AMQException + public void checkForNotification(QueueEntry queueEntry) throws AMQException { final Set<NotificationCheck> notificationChecks = _queue.getNotificationChecks(); @@ -260,7 +290,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que { if (check.isMessageSpecific() || (_lastNotificationTimes[check.ordinal()] < thresholdTime)) { - if (check.notifyIfNecessary(msg, _queue, this)) + if (check.notifyIfNecessary(queueEntry, _queue, this)) { _lastNotificationTimes[check.ordinal()] = currentTime; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java new file mode 100644 index 0000000000..a22eea2b5e --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java @@ -0,0 +1,380 @@ +/* + * + * 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 org.apache.log4j.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.util.FileUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public class FileQueueBackingStore implements QueueBackingStore +{ + private static final Logger _log = Logger.getLogger(FileQueueBackingStore.class); + + private String _flowToDiskLocation; + + public FileQueueBackingStore(String location) + { + _flowToDiskLocation = location; + } + + public AMQMessage load(Long messageId) + { + _log.info("Loading Message (ID:" + messageId + ")"); + + MessageMetaData mmd; + + File handle = getFileHandle(messageId); + + ObjectInputStream input = null; + + Exception error = null; + try + { + input = new ObjectInputStream(new FileInputStream(handle)); + + long arrivaltime = input.readLong(); + + final AMQShortString exchange = new AMQShortString(input.readUTF()); + final AMQShortString routingKey = new AMQShortString(input.readUTF()); + final boolean mandatory = input.readBoolean(); + final boolean immediate = input.readBoolean(); + + int bodySize = input.readInt(); + byte[] underlying = new byte[bodySize]; + + input.readFully(underlying, 0, bodySize); + + ByteBuffer buf = ByteBuffer.wrap(underlying); + + ContentHeaderBody chb = ContentHeaderBody.createFromBuffer(buf, bodySize); + + int chunkCount = input.readInt(); + + // There are WAY to many annonymous MPIs in the code this should be made concrete. + MessagePublishInfo info = new MessagePublishInfo() + { + + public AMQShortString getExchange() + { + return exchange; + } + + public void setExchange(AMQShortString exchange) + { + + } + + public boolean isImmediate() + { + return immediate; + } + + public boolean isMandatory() + { + return mandatory; + } + + public AMQShortString getRoutingKey() + { + return routingKey; + } + }; + + mmd = new MessageMetaData(info, chb, chunkCount); + mmd.setArrivalTime(arrivaltime); + + AMQMessage message; + if (((BasicContentHeaderProperties) chb.properties).getDeliveryMode() == 2) + { + message = new PersistentAMQMessage(messageId, null); + } + else + { + message = new TransientAMQMessage(messageId); + } + + message.recoverFromMessageMetaData(mmd); + + for (int chunk = 0; chunk < chunkCount; chunk++) + { + int length = input.readInt(); + + byte[] data = new byte[length]; + + input.readFully(data, 0, length); + + try + { + message.recoverContentBodyFrame(new RecoverDataBuffer(length, data), (chunk + 1 == chunkCount)); + } + catch (AMQException e) + { + //ignore as this will not occur. + // It is thrown by the _transactionLog method in load on PersistentAMQMessage + // but we have created the message with a null log and will never call that method. + } + } + + return message; + } + catch (Exception e) + { + error = e; + } + finally + { + try + { + if (input != null) + { + input.close(); + } + } + catch (IOException e) + { + _log.info("Unable to close input on message(" + messageId + ") recovery due to:" + e.getMessage()); + } + } + + throw new UnableToRecoverMessageException(error); + } + + /** + * Thread safety is ensured here by synchronizing on the message object. + * + * This is safe as load() calls will fail until the first thread through here has created the file on disk + * and fully written the content. + * + * After this point new AMQMessages can exist that reference the same data thus breaking the synchronisation. + * + * Thread safety is maintained here as the existence of the file is checked allowing then subsequent unload() calls + * to skip the writing. + * + * Multiple unload() calls will initially be blocked using the synchronization until the data exists on disk thus + * safely allowing any reference to the message to be cleared prompting a load call. + * + * @param message the message to unload + * @throws UnableToFlowMessageException + */ + public void unload(AMQMessage message) throws UnableToFlowMessageException + { + //Synchorize on the message to ensure that one only thread can unload at a time. + // If a second unload is attempted then it will block until the unload has completed. + synchronized (message) + { + long messageId = message.getMessageId(); + + File handle = getFileHandle(messageId); + + //If we have written the data once then we don't need to do it again. + if (handle.exists()) + { + if (_log.isDebugEnabled()) + { + _log.debug("Message(ID:" + messageId + ") already unloaded."); + } + return; + } + + if (_log.isInfoEnabled()) + { + _log.info("Unloading Message (ID:" + messageId + ")"); + } + + ObjectOutputStream writer = null; + Exception error = null; + + try + { + writer = new ObjectOutputStream(new FileOutputStream(handle)); + + writer.writeLong(message.getArrivalTime()); + + MessagePublishInfo mpi = message.getMessagePublishInfo(); + writer.writeUTF(String.valueOf(mpi.getExchange())); + writer.writeUTF(String.valueOf(mpi.getRoutingKey())); + writer.writeBoolean(mpi.isMandatory()); + writer.writeBoolean(mpi.isImmediate()); + ContentHeaderBody chb = message.getContentHeaderBody(); + + // write out the content header body + final int bodySize = chb.getSize(); + byte[] underlying = new byte[bodySize]; + ByteBuffer buf = ByteBuffer.wrap(underlying); + chb.writePayload(buf); + + writer.writeInt(bodySize); + writer.write(underlying, 0, bodySize); + + int bodyCount = message.getBodyCount(); + writer.writeInt(bodyCount); + + //WriteContentBody + for (int index = 0; index < bodyCount; index++) + { + ContentChunk chunk = message.getContentChunk(index); + int length = chunk.getSize(); + + byte[] chunk_underlying = new byte[length]; + + ByteBuffer chunk_buf = chunk.getData(); + + chunk_buf.duplicate().rewind().get(chunk_underlying); + + writer.writeInt(length); + writer.write(chunk_underlying, 0, length); + } + } + catch (FileNotFoundException e) + { + error = e; + } + catch (IOException e) + { + error = e; + } + finally + { + // In a FileNotFound situation writer will be null. + if (writer != null) + { + try + { + writer.flush(); + writer.close(); + } + catch (IOException e) + { + error = e; + } + } + } + + if (error != null) + { + _log.error("Unable to unload message(" + messageId + ") to disk, restoring state."); + handle.delete(); + throw new UnableToFlowMessageException(messageId, error); + } + } + } + + /** + * Use the messageId to calculate the file path on disk. + * + * Current implementation will give us 256 bins. + * Therefore the maximum messages that can be flowed before error/platform is: + * ext3 : 256 bins * 32000 = 8192000 + * FAT32 : 256 bins * 65534 = 16776704 + * Other FS have much greater limits than we need to worry about. + * + * @param messageId the Message we need a file Handle for. + * + * @return the File handle + */ + private File getFileHandle(long messageId) + { + // grab the 8 LSB to give us 256 bins + long bin = messageId & 0xFFL; + + String bin_path = _flowToDiskLocation + File.separator + bin; + File bin_dir = new File(bin_path); + + if (!bin_dir.exists()) + { + bin_dir.mkdirs(); + } + + String id = bin_path + File.separator + messageId; + + return new File(id); + } + + public void delete(Long messageId) + { + File handle = getFileHandle(messageId); + + if (handle.exists()) + { + if (_log.isInfoEnabled()) + { + _log.info("Message(" + messageId + ") delete flowToDisk."); + } + if (!handle.delete()) + { + throw new RuntimeException("Unable to delete flowToDisk data"); + } + } + } + + public void close() + { + _log.info("Closing Backing store at:" + _flowToDiskLocation); + if (!FileUtils.delete(new File(_flowToDiskLocation), true)) + { + _log.error("Unable to fully delete backing store location"); + } + } + + private class RecoverDataBuffer implements ContentChunk + { + private int _length; + private ByteBuffer _dataBuffer; + + public RecoverDataBuffer(int length, byte[] data) + { + _length = length; + _dataBuffer = ByteBuffer.wrap(data); + } + + public int getSize() + { + return _length; + } + + public ByteBuffer getData() + { + return _dataBuffer; + } + + public void reduceToFit() + { + + } + + } + +} + diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java new file mode 100644 index 0000000000..21073c22ae --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java @@ -0,0 +1,166 @@ +/* + * + * 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 org.apache.commons.configuration.ConfigurationException; +import org.apache.log4j.Logger; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.util.FileUtils; + +import java.io.File; + +public class FileQueueBackingStoreFactory implements QueueBackingStoreFactory +{ + private static final Logger _log = Logger.getLogger(FileQueueBackingStoreFactory.class); + + private String _flowToDiskLocation; + private static final String QUEUE_BACKING_DIR = "queueBacking"; + + public void configure(VirtualHost virtualHost, VirtualHostConfiguration config) throws ConfigurationException + { + setFlowToDisk(virtualHost.getName(), config.getFlowToDiskLocation()); + } + + private void setFlowToDisk(String vHostName, String location) throws ConfigurationException + { + if (vHostName == null) + { + throw new ConfigurationException("Unable to setup to Flow to Disk as Virtualhost name was not specified"); + } + + if (location == null) + { + throw new ConfigurationException("Unable to setup to Flow to Disk as location was not specified."); + } + + _flowToDiskLocation = location; + + _flowToDiskLocation += File.separator + QUEUE_BACKING_DIR + File.separator + vHostName; + + //Check the location we will create QUEUE_BACKING_DIR in. + File root = new File(location); + if (!root.exists()) + { + throw new ConfigurationException("Specified Flow to Disk root does not exist:" + root.getAbsolutePath()); + } + else + { + + if (root.isFile()) + { + throw new ConfigurationException("Unable to create Temporary Flow to Disk store as specified root is a file:" + + root.getAbsolutePath()); + } + + if (!root.canWrite()) + { + throw new ConfigurationException("Unable to create Temporary Flow to Disk store. Unable to write to specified root:" + + root.getAbsolutePath()); + } + + } + + // if we don't mark QUEUE_BAKCING_DIR as a deleteOnExit it will remain. + File backingDir = new File(location + File.separator + QUEUE_BACKING_DIR); + if (backingDir.exists()) + { + if (!FileUtils.delete(backingDir, true)) + { + throw new ConfigurationException("Unable to delete existing Flow to Disk root at:" + + backingDir.getAbsolutePath()); + } + + if (backingDir.isFile()) + { + throw new ConfigurationException("Unable to create Temporary Flow to Disk root as specified location is a file:" + + backingDir.getAbsolutePath()); + } + } + + backingDir.deleteOnExit(); + if (!backingDir.mkdirs()) + { + throw new ConfigurationException("Unable to create Temporary Flow to Disk root:" + location + File.separator + QUEUE_BACKING_DIR); + } + + + File store = new File(_flowToDiskLocation); + if (store.exists()) + { + if (!FileUtils.delete(store, true)) + { + throw new ConfigurationException("Unable to delete existing Flow to Disk store at:" + + store.getAbsolutePath()); + } + + if (store.isFile()) + { + throw new ConfigurationException("Unable to create Temporary Flow to Disk store as specified location is a file:" + + store.getAbsolutePath()); + } + + } + + _log.info("Creating Flow to Disk Store : " + store.getAbsolutePath()); + store.deleteOnExit(); + if (!store.mkdir()) + { + throw new ConfigurationException("Unable to create Temporary Flow to Disk store:" + store.getAbsolutePath()); + } + } + + public QueueBackingStore createBacking(AMQQueue queue) + { + return new FileQueueBackingStore(createStore(queue.getName().toString())); + } + + private String createStore(String name) + { + return createStore(name, 0); + } + + private String createStore(String name, int index) + { + + String store = _flowToDiskLocation + File.separator + name; + if (index > 0) + { + store += "-" + index; + } + + //TODO ensure store is safe for the OS + + File storeFile = new File(store); + + if (storeFile.exists()) + { + return createStore(name, index + 1); + } + + storeFile.mkdirs(); + + storeFile.deleteOnExit(); + + return store; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java new file mode 100644 index 0000000000..5e5901bcd7 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java @@ -0,0 +1,485 @@ +/* + * + * 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 org.apache.log4j.Logger; +import org.apache.qpid.pool.ReferenceCountingExecutorService; +import org.apache.qpid.server.virtualhost.VirtualHost; + +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +/** This is an abstract base class to handle */ +public abstract class FlowableBaseQueueEntryList implements QueueEntryList +{ + protected static final Logger _log = Logger.getLogger(FlowableBaseQueueEntryList.class); + + private final AtomicInteger _atomicQueueCount = new AtomicInteger(0); + private final AtomicLong _atomicQueueSize = new AtomicLong(0L); + protected final AtomicLong _atomicQueueInMemory = new AtomicLong(0L); + /** The maximum amount of memory that is allocated to this queue. Beyond this the queue will flow to disk. */ + + protected long _memoryUsageMaximum = -1L; + + /** The minimum amount of memory that is allocated to this queue. If the queueDepth hits this level then more flowed data can be read in. */ + protected long _memoryUsageMinimum = 0; + private volatile AtomicBoolean _flowed; + private QueueBackingStore _backingStore; + protected AMQQueue _queue; + private Executor _inhaler; + private Executor _purger; + private AtomicBoolean _stopped; + private AtomicReference<MessageInhaler> _asynchronousInhaler = new AtomicReference(null); + protected boolean _disabled; + private AtomicReference<MessagePurger> _asynchronousPurger = new AtomicReference(null); + private static final int BATCH_PROCESS_COUNT = 100; + + FlowableBaseQueueEntryList(AMQQueue queue) + { + _queue = queue; + _flowed = new AtomicBoolean(false); + VirtualHost vhost = queue.getVirtualHost(); + if (vhost != null) + { + _backingStore = vhost.getQueueBackingStoreFactory().createBacking(queue); + } + + _stopped = new AtomicBoolean(false); + _inhaler = ReferenceCountingExecutorService.getInstance().acquireExecutorService(); + _purger = ReferenceCountingExecutorService.getInstance().acquireExecutorService(); + _disabled = true; + } + + public void setFlowed(boolean flowed) + { + if (_flowed.get() != flowed) + { + _log.warn("Marking Queue(" + _queue.getName() + ") as flowed (" + flowed + ")"); + _flowed.set(flowed); + } + } + + protected void showUsage() + { + showUsage(""); + } + + protected void showUsage(String prefix) + { + if (_log.isDebugEnabled()) + { + _log.debug(prefix + " Queue(" + _queue + ":" + _queue.getName() + ") usage:" + memoryUsed() + + "/" + getMemoryUsageMinimum() + "<>" + getMemoryUsageMaximum() + + "/" + dataSize()); + } + } + + public boolean isFlowed() + { + return _flowed.get(); + } + + public int size() + { + return _atomicQueueCount.get(); + } + + public long dataSize() + { + return _atomicQueueSize.get(); + } + + public long memoryUsed() + { + return _atomicQueueInMemory.get(); + } + + public void setMemoryUsageMaximum(long maximumMemoryUsage) + { + _memoryUsageMaximum = maximumMemoryUsage; + + if (maximumMemoryUsage >= 0) + { + _disabled = false; + } + + // Don't attempt to start the inhaler/purger unless we have a minimum value specified. + if (_memoryUsageMaximum >= 0) + { + setMemoryUsageMinimum(_memoryUsageMaximum / 2); + + // if we have now have to much memory in use we need to purge. + if (_memoryUsageMaximum < _atomicQueueInMemory.get()) + { + setFlowed(true); + startPurger(); + } + } + else + { + if (_log.isInfoEnabled()) + { + _log.info("Disabling Flow to Disk for queue:" + _queue.getName()); + } + _disabled = true; + } + } + + public long getMemoryUsageMaximum() + { + return _memoryUsageMaximum; + } + + public void setMemoryUsageMinimum(long minimumMemoryUsage) + { + _memoryUsageMinimum = minimumMemoryUsage; + + // Don't attempt to start the inhaler unless we have a minimum value specified. + if (_memoryUsageMinimum > 0) + { + checkAndStartInhaler(); + } + } + + private void checkAndStartInhaler() + { + // If we've increased the minimum memory above what we have in memory then + // we need to inhale more if there is more + if (!_disabled && _atomicQueueInMemory.get() < _memoryUsageMinimum && _atomicQueueSize.get() > 0) + { + startInhaler(); + } + } + + private void startInhaler() + { + MessageInhaler inhaler = new MessageInhaler(); + + if (_asynchronousInhaler.compareAndSet(null, inhaler)) + { + _inhaler.execute(inhaler); + } + } + + private void startPurger() + { + MessagePurger purger = new MessagePurger(); + + if (_asynchronousPurger.compareAndSet(null, purger)) + { + _purger.execute(purger); + } + } + + public long getMemoryUsageMinimum() + { + return _memoryUsageMinimum; + } + + /** + * Only to be called by the QueueEntry + * + * @param queueEntry the entry to unload + */ + public void entryUnloadedUpdateMemory(QueueEntry queueEntry) + { + if (!_disabled && _atomicQueueInMemory.addAndGet(-queueEntry.getSize()) < 0) + { + _log.error("InMemory Count just went below 0:" + queueEntry.debugIdentity()); + } + + checkAndStartInhaler(); + } + + /** + * Only to be called from the QueueEntry + * + * @param queueEntry the entry to load + */ + public void entryLoadedUpdateMemory(QueueEntry queueEntry) + { + if (!_disabled && _atomicQueueInMemory.addAndGet(queueEntry.getSize()) > _memoryUsageMaximum) + { + _log.error("Loaded to much data!:" + _atomicQueueInMemory.get() + "/" + _memoryUsageMaximum); + setFlowed(true); + startPurger(); + } + } + + public void stop() + { + if (!_stopped.getAndSet(true)) + { + // The SimpleAMQQueue keeps running when stopped so we should just release the services + // rather than actively shutdown our threads. + //Shutdown thread for inhaler. + ReferenceCountingExecutorService.getInstance().releaseExecutorService(); + ReferenceCountingExecutorService.getInstance().releaseExecutorService(); + + _backingStore.close(); + } + } + + protected void incrementCounters(final QueueEntryImpl queueEntry) + { + _atomicQueueCount.incrementAndGet(); + _atomicQueueSize.addAndGet(queueEntry.getSize()); + long inUseMemory = _atomicQueueInMemory.addAndGet(queueEntry.getSize()); + + if (!_disabled && inUseMemory > _memoryUsageMaximum) + { + setFlowed(true); + queueEntry.unload(); + } + } + + protected void dequeued(QueueEntryImpl queueEntry) + { + _atomicQueueCount.decrementAndGet(); + _atomicQueueSize.addAndGet(-queueEntry.getSize()); + if (!queueEntry.isFlowed()) + { + if (_atomicQueueInMemory.addAndGet(-queueEntry.getSize()) < 0) + { + _log.error("InMemory Count just went below 0 on dequeue."); + } + } + } + + public QueueBackingStore getBackingStore() + { + return _backingStore; + } + + private class MessageInhaler implements Runnable + { + public void run() + { + String threadName = Thread.currentThread().getName(); + Thread.currentThread().setName("Inhaler-" + _queue.getVirtualHost().getName() + "-" + _queue.getName()); + try + { + inhaleList(this); + } + finally + { + Thread.currentThread().setName(threadName); + } + } + } + + private void inhaleList(MessageInhaler messageInhaler) + { + if (_log.isInfoEnabled()) + { + _log.info("Inhaler Running:" + _queue.getName()); + showUsage("Inhaler Running:" + _queue.getName()); + } + // If in memory count is at or over max then we can't inhale + if (_atomicQueueInMemory.get() >= _memoryUsageMaximum) + { + if (_log.isDebugEnabled()) + { + _log.debug("Unable to start inhaling as we are already over quota:" + + _atomicQueueInMemory.get() + ">=" + _memoryUsageMaximum); + } + return; + } + + _asynchronousInhaler.compareAndSet(messageInhaler, null); + int inhaled = 1; + + while ((_atomicQueueInMemory.get() < _memoryUsageMaximum) // we havn't filled our max memory + && (_atomicQueueInMemory.get() < _atomicQueueSize.get()) // we haven't loaded all that is available + && (inhaled < BATCH_PROCESS_COUNT) // limit the number of runs we do + && (inhaled > 0) // ensure we could inhale something + && _asynchronousInhaler.compareAndSet(null, messageInhaler)) // Ensure we are the running inhaler + { + inhaled = 0; + QueueEntryIterator iterator = iterator(); + + // If the inhaler is running and delivery rate picks up ensure that we just don't chase the delivery thread. + while ((_atomicQueueInMemory.get() < _memoryUsageMaximum) + && !iterator.getNode().isAvailable() && iterator.advance()) + { + //Find first AVAILABLE node + } + + // Because the above loop checks then moves on to the next entry a check for atTail will return true but + // we won't have checked the last entry to see if we can load it. So create atEndofList and update it based + // on the return from advance() which returns true if it can advance. + boolean atEndofList = false; + while ((_atomicQueueInMemory.get() < _memoryUsageMaximum) // we havn't filled our max memory + && (inhaled < BATCH_PROCESS_COUNT) // limit the number of runs we do + && !atEndofList) // We have reached end of list QueueEntries + { + QueueEntry entry = iterator.getNode(); + + if (entry.isAvailable() && entry.isFlowed()) + { + if (_atomicQueueInMemory.get() + entry.getSize() > _memoryUsageMaximum) + { + // We don't have space for this message so we need to stop inhaling. + if (_log.isDebugEnabled()) + { + _log.debug("Entry won't fit in memory stopping inhaler:" + entry.debugIdentity()); + } + inhaled = BATCH_PROCESS_COUNT; + } + else + { + entry.load(); + inhaled++; + } + } + + atEndofList = !iterator.advance(); + } + + if (iterator.atTail()) + { + setFlowed(false); + } + + _asynchronousInhaler.set(null); + } + + if (_log.isInfoEnabled()) + { + _log.info("Inhaler Stopping:" + _queue.getName()); + showUsage("Inhaler Stopping:" + _queue.getName()); + } + + //If we have become flowed or have more capacity since we stopped then schedule the thread to run again. + if (_flowed.get() && _atomicQueueInMemory.get() < _memoryUsageMaximum) + { + if (_log.isInfoEnabled()) + { + _log.info("Rescheduling Inhaler:" + _queue.getName()); + } + _inhaler.execute(messageInhaler); + } + + } + + private class MessagePurger implements Runnable + { + public void run() + { + String threadName = Thread.currentThread().getName(); + Thread.currentThread().setName("Purger-" + _queue.getVirtualHost().getName() + "-" + _queue.getName()); + try + { + purgeList(this); + } + finally + { + Thread.currentThread().setName(threadName); + } + } + } + + private void purgeList(MessagePurger messagePurger) + { + // If in memory count is at or over max then we can't inhale + if (_atomicQueueInMemory.get() <= _memoryUsageMinimum) + { + if (_log.isDebugEnabled()) + { + _log.debug("Unable to start purging as we are already below our minimum cache level:" + + _atomicQueueInMemory.get() + "<=" + _memoryUsageMinimum); + } + return; + } + + if (_log.isInfoEnabled()) + { + _log.info("Purger Running:" + _queue.getName()); + showUsage("Purger Running:" + _queue.getName()); + } + + _asynchronousPurger.compareAndSet(messagePurger, null); + int purged = 0; + + while ((_atomicQueueInMemory.get() > _memoryUsageMinimum) + && purged < BATCH_PROCESS_COUNT + && _asynchronousPurger.compareAndSet(null, messagePurger)) + { + QueueEntryIterator iterator = iterator(); + + //There are potentially AQUIRED messages that can be purged but we can't purge the last AQUIRED message + // as it may have just become AQUIRED and not yet delivered. + + //To be safe only purge available messages. This should be fine as long as we have a small prefetch. + while (!iterator.getNode().isAvailable() && iterator.advance()) + { + //Find first AVAILABLE node + } + + // Count up the memory usage to find our minimum point + long memoryUsage = 0; + boolean atTail = false; + while ((memoryUsage < _memoryUsageMaximum) && !atTail) + { + QueueEntry entry = iterator.getNode(); + + if (entry.isAvailable() && !entry.isFlowed()) + { + memoryUsage += entry.getSize(); + } + + atTail = !iterator.advance(); + } + + //Purge remainging mesages on queue + while (!atTail && (purged < BATCH_PROCESS_COUNT)) + { + QueueEntry entry = iterator.getNode(); + + if (entry.isAvailable() && !entry.isFlowed()) + { + entry.unload(); + purged++; + } + + atTail = !iterator.advance(); + } + + _asynchronousPurger.set(null); + } + + if (_log.isInfoEnabled()) + { + _log.info("Purger Stopping:" + _queue.getName()); + showUsage("Purger Stopping:" + _queue.getName()); + } + + //If we are still flowed and are over the minimum value then schedule to run again. + if (_flowed.get() && _atomicQueueInMemory.get() > _memoryUsageMinimum) + { + _log.info("Rescheduling Purger:" + _queue.getName()); + _purger.execute(messagePurger); + } + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java index 94580a00ac..5eafd281c0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java @@ -43,7 +43,7 @@ public class IncomingMessage implements Filterable<RuntimeException> private static final Logger _logger = Logger.getLogger(IncomingMessage.class); private static final boolean SYNCHED_CLOCKS = - ApplicationRegistry.getInstance().getConfiguration().getBoolean("advanced.synced-clocks", false); + ApplicationRegistry.getInstance().getConfiguration().getSynchedClocks(); private final MessagePublishInfo _messagePublishInfo; private ContentHeaderBody _contentHeaderBody; @@ -51,7 +51,7 @@ public class IncomingMessage implements Filterable<RuntimeException> private final TransactionalContext _txnContext; private static final boolean MSG_AUTH = - ApplicationRegistry.getInstance().getConfiguration().getBoolean("security.msg-auth", false); + ApplicationRegistry.getInstance().getConfiguration().getMsgAuth(); /** @@ -78,6 +78,10 @@ public class IncomingMessage implements Filterable<RuntimeException> final AMQProtocolSession publisher, TransactionLog messasgeStore) { + if (publisher == null) + { + throw new NullPointerException("Message Publisher cannot be null"); + } _messagePublishInfo = info; _txnContext = txnContext; _publisher = publisher; @@ -152,8 +156,7 @@ public class IncomingMessage implements Filterable<RuntimeException> _logger.debug("Delivering message " + getMessageId() + " to " + _destinationQueues); } - try - { + // first we allow the handle to know that the message has been fully received. This is useful if it is // maintaining any calculated values based on content chunks _message.setPublishAndContentHeaderBody(_txnContext.getStoreContext(), _messagePublishInfo, getContentHeaderBody()); @@ -192,7 +195,6 @@ public class IncomingMessage implements Filterable<RuntimeException> { int offset; final int queueCount = _destinationQueues.size(); - _message.incrementReference(queueCount); if(queueCount == 1) { offset = 0; @@ -218,12 +220,8 @@ public class IncomingMessage implements Filterable<RuntimeException> } return _message; - } - finally - { - // Remove refence for routing process . Reference count should now == delivered queue count - if(_message != null) _message.decrementReference(_txnContext.getStoreContext()); - } + + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java index 2bc94995e9..d91d45a446 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java @@ -41,6 +41,7 @@ import org.apache.qpid.server.management.MBeanOperationParameter; public interface ManagedQueue { static final String TYPE = "Queue"; + static final int VERSION = 2; /** * Returns the Name of the ManagedQueue. @@ -71,7 +72,7 @@ public interface ManagedQueue * @return * @throws IOException */ - @MBeanAttribute(name="QueueDepth", description="Size of messages(KB) in the queue") + @MBeanAttribute(name="QueueDepth", description="The total size(Bytes) of messages in the queue") Long getQueueDepth() throws IOException, JMException; /** @@ -115,22 +116,22 @@ public interface ManagedQueue boolean isAutoDelete() throws IOException; /** - * Returns the maximum age of a message (expiration time) + * Returns the maximum age of a message (expiration time) in milliseconds * @return the maximum age * @throws IOException */ Long getMaximumMessageAge() throws IOException; /** - * Sets the maximum age of a message + * Sets the maximum age of a message in milliseconds * @param age maximum age of message. * @throws IOException */ - @MBeanAttribute(name="MaximumMessageAge", description="Threshold high value for message age on the broker") + @MBeanAttribute(name="MaximumMessageAge", description="Threshold high value(milliseconds) for message age") void setMaximumMessageAge(Long age) throws IOException; /** - * Returns the maximum size of a message (in kbytes) allowed to be accepted by the + * Returns the maximum size of a message (in Bytes) allowed to be accepted by the * ManagedQueue. This is useful in setting notifications or taking * appropriate action, if the size of the message received is more than * the allowed size. @@ -141,12 +142,12 @@ public interface ManagedQueue Long getMaximumMessageSize() throws IOException; /** - * Sets the maximum size of the message (in kbytes) that is allowed to be + * Sets the maximum size of the message (in Bytes) that is allowed to be * accepted by the Queue. * @param size maximum size of message. * @throws IOException */ - @MBeanAttribute(name="MaximumMessageSize", description="Threshold high value(KB) for a message size") + @MBeanAttribute(name="MaximumMessageSize", description="Threshold high value(Bytes) for a message size") void setMaximumMessageSize(Long size) throws IOException; /** @@ -180,9 +181,65 @@ public interface ManagedQueue * @param value * @throws IOException */ - @MBeanAttribute(name="MaximumQueueDepth", description="The threshold high value(KB) for Queue Depth") + @MBeanAttribute(name="MaximumQueueDepth", description="The threshold high value(Bytes) for Queue Depth") void setMaximumQueueDepth(Long value) throws IOException; + /** + * View the limit on the memory that this queue will utilise. + * + * Used by Flow to Disk. + * + * @return The maximum memory(B) that the queue will occuy. + */ + public Long getMemoryUsageMaximum(); + + /** + * Place a limit on the memory that this queue will utilise. + * + * Used by Flow to Disk + * + * @param maximumMemoryUsage The new maximum memory(B) to be used by this queue + */ + @MBeanAttribute(name="MemoryUsageMaximum", description="The maximum memory(Bytes) that the queue will occupy.") + public void setMemoryUsageMaximum(Long maximumMemoryUsage); + + /** + * View the minimum amount of memory that has been defined for this queue. + * + * Used by Flow to Disk + * + * @return The minimum amount of queue data(B) that the queue will attempt to keep in memory + */ + public Long getMemoryUsageMinimum(); + + /** + * Set the minimum amount of memory that has been defined for this queue. + * + * Used by Flow to Disk + * + * @param minimumMemoryUsage The new minimum memory(B) level to be used by this queue + */ + @MBeanAttribute(name="MemoryUsageMinimum", description="The minimum memory(Bytes) that the queue will occupy.") + public void setMemoryUsageMinimum(Long minimumMemoryUsage); + + /** + * View the amount of memory(B) that this queue is using. + * + * @return The current memory(B) usage of this queue. + */ + @MBeanAttribute(name="MemoryUsageCurrent", description="The current amount of memory(Bytes) used by this queue.") + public Long getMemoryUsageCurrent(); + + /** + * When a queue exceeds its MemoryUsageMaximum value then the Queue will start flowing to disk. + * + * This boolean is used to show that change in state. + * + * @return true if the Queue is currently flowing to disk + */ + @MBeanAttribute(name="isFlowed", description="true if the queue is currently flowing to disk.") + public boolean isFlowed(); + //********** Operations *****************// diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java index e5e0b6e312..9924733178 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java @@ -42,19 +42,19 @@ public class MessageFactory _messageId = new AtomicLong(0L); } - public void start() + public void recoveryComplete() { _state = State.OPEN; } /** - * Only used by test as test suite is run in a single VM we need to beable to re-enable recovery mode. - */ - protected void enableRecover() + * Only to be used by tests as this will cause violate the principal that message IDs should not be reused. + */ + public void reset() { _state = State.RECOVER; + _messageId = new AtomicLong(0L); } - /** * Normal message creation path diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java index e33b0c83c7..a83d661de2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java @@ -20,14 +20,12 @@ */
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
-
public enum NotificationCheck
{
MESSAGE_COUNT_ALERT
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
int msgCount;
final long maximumMessageCount = queue.getMaximumMessageCount();
@@ -41,19 +39,19 @@ public enum NotificationCheck },
MESSAGE_SIZE_ALERT(true)
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
final long maximumMessageSize = queue.getMaximumMessageSize();
if(maximumMessageSize != 0)
{
// Check for threshold message size
- long messageSize = (msg == null) ? 0 : msg.getContentHeaderBody().bodySize;
+ long messageSize = (queueEntry == null) ? 0 : queueEntry.getSize();
if (messageSize >= maximumMessageSize)
{
listener.notifyClients(this, queue, messageSize + "b : Maximum message size threshold (" +
maximumMessageSize + ") breached. [Message ID=" +
- (msg == null ? "null" : msg.getMessageId()) + "]");
+ (queueEntry == null ? "null" : queueEntry.getMessageId()) + "]");
return true;
}
}
@@ -63,7 +61,7 @@ public enum NotificationCheck },
QUEUE_DEPTH_ALERT
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
// Check for threshold queue depth in bytes
final long maximumQueueDepth = queue.getMaximumQueueDepth();
@@ -84,7 +82,7 @@ public enum NotificationCheck },
MESSAGE_AGE_ALERT
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
final long maxMessageAge = queue.getMaximumMessageAge();
@@ -126,6 +124,6 @@ public enum NotificationCheck return _messageSpecific;
}
- abstract boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener);
+ abstract boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java index 804bb29ecd..9c644cc010 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java @@ -52,30 +52,19 @@ public class PersistentAMQMessage extends TransientAMQMessage throws AMQException { super.setPublishAndContentHeaderBody(storeContext, messagePublishInfo, contentHeaderBody); - MessageMetaData mmd = new MessageMetaData(messagePublishInfo, contentHeaderBody, _contentBodies == null ? 0 : _contentBodies.size(), _arrivalTime); + MessageMetaData mmd = new MessageMetaData(messagePublishInfo, contentHeaderBody, + _contentBodies == null ? 0 : _contentBodies.size(), _arrivalTime); _transactionLog.storeMessageMetaData(storeContext, _messageId, mmd); } @Override - public void removeMessage(StoreContext storeContext) throws AMQException - { - _transactionLog.removeMessage(storeContext, _messageId); - } - - @Override public boolean isPersistent() { return true; } - public void recoverFromMessageMetaData(MessageMetaData mmd) - { - _arrivalTime = mmd.getArrivalTime(); - _contentHeaderBody = mmd.getContentHeaderBody(); - _messagePublishInfo = mmd.getMessagePublishInfo(); - } - + @Override public void recoverContentBodyFrame(ContentChunk contentChunk, boolean isLastContentBody) throws AMQException { super.addContentBodyFrame(null, contentChunk, isLastContentBody); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java new file mode 100644 index 0000000000..d5271295dd --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java @@ -0,0 +1,466 @@ +/* +* +* 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 org.apache.qpid.framing.CommonContentHeaderProperties; + +public class PriorityQueueEntryList extends FlowableBaseQueueEntryList implements QueueEntryList +{ + private final AMQQueue _queue; + private final QueueEntryList[] _priorityLists; + private final int _priorities; + private final int _priorityOffset; + + public PriorityQueueEntryList(AMQQueue queue, int priorities) + { + super(queue); + _queue = queue; + _priorityLists = new QueueEntryList[priorities]; + _priorities = priorities; + _priorityOffset = 5 - ((priorities + 1) / 2); + for (int i = 0; i < priorities; i++) + { + _priorityLists[i] = new SimpleQueueEntryList(queue); + } + + showUsage("Created:" + _queue.getName()); + } + + public int getPriorities() + { + return _priorities; + } + + public AMQQueue getQueue() + { + return _queue; + } + + public QueueEntry add(AMQMessage message) + { + int index = ((CommonContentHeaderProperties) ((message.getContentHeaderBody().properties))).getPriority() - _priorityOffset; + if (index >= _priorities) + { + index = _priorities - 1; + } + else if (index < 0) + { + index = 0; + } + + long requriedSize = message.getSize(); + // Check and see if list would flow on adding message + if (!_disabled && !isFlowed() && _priorityLists[index].memoryUsed() + requriedSize > _priorityLists[index].getMemoryUsageMaximum()) + { + if (_log.isDebugEnabled()) + { + _log.debug("Message(" + message.debugIdentity() + ") Add of size (" + + requriedSize + ") will cause flow. Searching for space"); + } + + long reclaimed = 0; + + //work down the priorities looking for memory + + //First: Don't take all the memory. So look for a queue that has more than 50% free + long currentMax; + int scavangeIndex = 0; + + if (scavangeIndex == index) + { + scavangeIndex++; + } + + while (scavangeIndex < _priorities && reclaimed <= requriedSize) + { + currentMax = _priorityLists[scavangeIndex].getMemoryUsageMaximum(); + long used = _priorityLists[scavangeIndex].memoryUsed(); + + if (used < currentMax / 2) + { + long newMax = currentMax / 2; + + _priorityLists[scavangeIndex].setMemoryUsageMaximum(newMax); + + reclaimed += currentMax - newMax; + if (_log.isDebugEnabled()) + { + _log.debug("Reclaiming(1) :" + (currentMax - newMax) + "(" + reclaimed + "/" + requriedSize + ") from queue:" + scavangeIndex); + } + break; + } + else + { + scavangeIndex++; + if (scavangeIndex == index) + { + scavangeIndex++; + } + } + } + + //Second: Just take the free memory we need + if (scavangeIndex == _priorities) + { + scavangeIndex = 0; + if (scavangeIndex == index) + { + scavangeIndex++; + } + + while (scavangeIndex < _priorities && reclaimed <= requriedSize) + { + currentMax = _priorityLists[scavangeIndex].getMemoryUsageMaximum(); + long used = _priorityLists[scavangeIndex].memoryUsed(); + + if (used < currentMax) + { + long newMax = currentMax - used; + + // if there are no messages at this priority just take it all + if (newMax == currentMax) + { + newMax = 0; + } + + _priorityLists[scavangeIndex].setMemoryUsageMaximum(newMax); + + reclaimed += currentMax - newMax; + if (_log.isDebugEnabled()) + { + _log.debug("Reclaiming(2) :" + (currentMax - newMax) + "(" + reclaimed + "/" + requriedSize + ") from queue:" + scavangeIndex); + } + break; + } + else + { + scavangeIndex++; + if (scavangeIndex == index) + { + scavangeIndex++; + } + } + } + + //Third: Take required memory + if (scavangeIndex == _priorities) + { + scavangeIndex = 0; + if (scavangeIndex == index) + { + scavangeIndex++; + } + while (scavangeIndex < _priorities && reclaimed <= requriedSize) + { + currentMax = _priorityLists[scavangeIndex].getMemoryUsageMaximum(); + + if (currentMax > 0 ) + { + long newMax = currentMax; + // Just take the amount of space required for this message. + if (newMax > requriedSize) + { + newMax = requriedSize; + } + _priorityLists[scavangeIndex].setMemoryUsageMaximum(newMax); + + reclaimed += currentMax - newMax; + if (_log.isDebugEnabled()) + { + _log.debug("Reclaiming(3) :" + (currentMax - newMax) + "(" + reclaimed + "/" + requriedSize + ") from queue:" + scavangeIndex); + } + break; + } + else + { + scavangeIndex++; + if (scavangeIndex == index) + { + scavangeIndex++; + } + } + } + } + } + + //Increment Maximum + if (reclaimed > 0) + { + if (_log.isDebugEnabled()) + { + _log.debug("Increasing queue(" + index + ") maximum by " + reclaimed + + " to " + (_priorityLists[index].getMemoryUsageMaximum() + reclaimed)); + } + _priorityLists[index].setMemoryUsageMaximum(_priorityLists[index].getMemoryUsageMaximum() + reclaimed); + } + else + { + _log.debug("No space found."); + } + + if (_log.isTraceEnabled()) + { + showUsage("Add"); + } + } + + return _priorityLists[index].add(message); + } + + @Override + protected void showUsage(String prefix) + { + if (_log.isDebugEnabled()) + { + if (prefix.length() != 0) + { + _log.debug(prefix); + } + for (int index = 0; index < _priorities; index++) + { + QueueEntryList queueEntryList = _priorityLists[index]; + _log.debug("Queue (" + _queue.getName() + ")[" + index + "] usage:" + queueEntryList.memoryUsed() + + "/" + queueEntryList.getMemoryUsageMaximum() + + "/" + queueEntryList.dataSize()); + } + } + } + + public QueueEntry next(QueueEntry node) + { + QueueEntryImpl nodeImpl = (QueueEntryImpl) node; + QueueEntry next = nodeImpl.getNext(); + + if (next == null) + { + QueueEntryList nodeEntryList = nodeImpl.getQueueEntryList(); + int index; + for (index = _priorityLists.length - 1; _priorityLists[index] != nodeEntryList; index--) + { + ; + } + + while (next == null && index != 0) + { + index--; + next = ((QueueEntryImpl) _priorityLists[index].getHead()).getNext(); + } + + } + return next; + } + + private final class PriorityQueueEntryListIterator implements QueueEntryIterator + { + private final QueueEntryIterator[] _iterators = new QueueEntryIterator[_priorityLists.length]; + private QueueEntry _lastNode; + + PriorityQueueEntryListIterator() + { + for (int i = 0; i < _priorityLists.length; i++) + { + _iterators[i] = _priorityLists[i].iterator(); + } + _lastNode = _iterators[_iterators.length - 1].getNode(); + } + + public boolean atTail() + { + for (int i = 0; i < _iterators.length; i++) + { + if (!_iterators[i].atTail()) + { + return false; + } + } + return true; + } + + public QueueEntry getNode() + { + return _lastNode; + } + + public boolean advance() + { + for (int i = _iterators.length - 1; i >= 0; i--) + { + if (_iterators[i].advance()) + { + _lastNode = _iterators[i].getNode(); + return true; + } + } + return false; + } + } + + public QueueEntryIterator iterator() + { + return new PriorityQueueEntryListIterator(); + } + + public QueueEntry getHead() + { + return _priorityLists[_priorities - 1].getHead(); + } + + static class Factory implements QueueEntryListFactory + { + private final int _priorities; + + Factory(int priorities) + { + _priorities = priorities; + } + + public QueueEntryList createQueueEntryList(AMQQueue queue) + { + return new PriorityQueueEntryList(queue, _priorities); + } + } + + @Override + public boolean isFlowed() + { + boolean flowed = false; + boolean full = true; + + if (_log.isTraceEnabled()) + { + showUsage("isFlowed"); + } + + for (QueueEntryList queueEntryList : _priorityLists) + { + //full = full && queueEntryList.getMemoryUsageMaximum() == queueEntryList.memoryUsed(); + full = full && queueEntryList.getMemoryUsageMaximum() <= queueEntryList.dataSize(); + flowed = flowed || (queueEntryList.isFlowed()); + } + return flowed && full; + } + + @Override + public int size() + { + int size = 0; + for (QueueEntryList queueEntryList : _priorityLists) + { + size += queueEntryList.size(); + } + + return size; + } + + @Override + public long dataSize() + { + int dataSize = 0; + for (QueueEntryList queueEntryList : _priorityLists) + { + dataSize += queueEntryList.dataSize(); + } + + return dataSize; + } + + @Override + public long memoryUsed() + { + int memoryUsed = 0; + for (QueueEntryList queueEntryList : _priorityLists) + { + memoryUsed += queueEntryList.memoryUsed(); + } + + return memoryUsed; + } + + @Override + public void setMemoryUsageMaximum(long maximumMemoryUsage) + { + _memoryUsageMaximum = maximumMemoryUsage; + + if (maximumMemoryUsage >= 0) + { + _disabled = false; + } + + long share = maximumMemoryUsage / _priorities; + + //Apply a share of the maximum To each prioirty quue + for (QueueEntryList queueEntryList : _priorityLists) + { + queueEntryList.setMemoryUsageMaximum(share); + } + + if (maximumMemoryUsage < 0) + { + if (_log.isInfoEnabled()) + { + _log.info("Disabling Flow to Disk for queue:" + _queue.getName()); + } + _disabled = true; + return; + } + + //ensure we use the full allocation of memory + long remainder = maximumMemoryUsage - (share * _priorities); + if (remainder > 0) + { + _priorityLists[_priorities - 1].setMemoryUsageMaximum(share + remainder); + } + } + + @Override + public long getMemoryUsageMaximum() + { + return _memoryUsageMaximum; + } + + @Override + public void setMemoryUsageMinimum(long minimumMemoryUsage) + { + _memoryUsageMinimum = minimumMemoryUsage; + + //Apply a share of the minimum To each prioirty quue + for (QueueEntryList queueEntryList : _priorityLists) + { + queueEntryList.setMemoryUsageMaximum(minimumMemoryUsage / _priorities); + } + } + + @Override + public long getMemoryUsageMinimum() + { + return _memoryUsageMinimum; + } + + @Override + public void stop() + { + super.stop(); + for (QueueEntryList queueEntryList : _priorityLists) + { + queueEntryList.stop(); + } + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java deleted file mode 100644 index 7be2827e0f..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java +++ /dev/null @@ -1,160 +0,0 @@ -/* -* -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -* -*/ -package org.apache.qpid.server.queue; - -import org.apache.qpid.framing.CommonContentHeaderProperties; -import org.apache.qpid.AMQException; - -public class PriorityQueueList implements QueueEntryList -{ - private final AMQQueue _queue; - private final QueueEntryList[] _priorityLists; - private final int _priorities; - private final int _priorityOffset; - - public PriorityQueueList(AMQQueue queue, int priorities) - { - _queue = queue; - _priorityLists = new QueueEntryList[priorities]; - _priorities = priorities; - _priorityOffset = 5-((priorities + 1)/2); - for(int i = 0; i < priorities; i++) - { - _priorityLists[i] = new SimpleQueueEntryList(queue); - } - } - - public int getPriorities() - { - return _priorities; - } - - public AMQQueue getQueue() - { - return _queue; - } - - public QueueEntry add(AMQMessage message) - { - int index = ((CommonContentHeaderProperties)((message.getContentHeaderBody().properties))).getPriority() - _priorityOffset; - if(index >= _priorities) - { - index = _priorities-1; - } - else if(index < 0) - { - index = 0; - } - return _priorityLists[index].add(message); - } - - public QueueEntry next(QueueEntry node) - { - QueueEntryImpl nodeImpl = (QueueEntryImpl)node; - QueueEntry next = nodeImpl.getNext(); - - if(next == null) - { - QueueEntryList nodeEntryList = nodeImpl.getQueueEntryList(); - int index; - for(index = _priorityLists.length-1; _priorityLists[index] != nodeEntryList; index--); - - while(next == null && index != 0) - { - index--; - next = ((QueueEntryImpl)_priorityLists[index].getHead()).getNext(); - } - - } - return next; - } - - private final class PriorityQueueEntryListIterator implements QueueEntryIterator - { - private final QueueEntryIterator[] _iterators = new QueueEntryIterator[ _priorityLists.length ]; - private QueueEntry _lastNode; - - PriorityQueueEntryListIterator() - { - for(int i = 0; i < _priorityLists.length; i++) - { - _iterators[i] = _priorityLists[i].iterator(); - } - _lastNode = _iterators[_iterators.length - 1].getNode(); - } - - - public boolean atTail() - { - for(int i = 0; i < _iterators.length; i++) - { - if(!_iterators[i].atTail()) - { - return false; - } - } - return true; - } - - public QueueEntry getNode() - { - return _lastNode; - } - - public boolean advance() - { - for(int i = _iterators.length-1; i >= 0; i--) - { - if(_iterators[i].advance()) - { - _lastNode = _iterators[i].getNode(); - return true; - } - } - return false; - } - } - - public QueueEntryIterator iterator() - { - return new PriorityQueueEntryListIterator(); - } - - public QueueEntry getHead() - { - return _priorityLists[_priorities-1].getHead(); - } - - static class Factory implements QueueEntryListFactory - { - private final int _priorities; - - Factory(int priorities) - { - _priorities = priorities; - } - - public QueueEntryList createQueueEntryList(AMQQueue queue) - { - return new PriorityQueueList(queue, _priorities); - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java new file mode 100644 index 0000000000..5c65cb6424 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java @@ -0,0 +1,64 @@ +/* + * + * 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 org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.commons.configuration.ConfigurationException; + +public interface QueueBackingStore +{ + /** + * Retrieve the message with a given ID + * + * This method must be thread safe. + * + * Multiple calls to load with a given messageId DO NOT need to return the same object. + * + * @param messageId the id of the message to retreive. + * @return + */ + AMQMessage load(Long messageId); + + /** + * Store a message in the BackingStore. + * + * This method must be thread safe understanding that multiple message objects may be the same data. + * + * Allowing a thread to return from this method means that it is safe to call load() + * + * Implementer guide: + * Until the message has been loaded the message references will all be the same object. + * + * One appraoch as taken by the @see FileQueueBackingStore is to block aimulataneous calls to this method + * until the message is fully on disk. This can be done by synchronising on message as initially it is always the + * same object. Only after a load has taken place will there be a discrepency. + * + * + * @param message the message to unload + * @throws UnableToFlowMessageException + */ + void unload(AMQMessage message) throws UnableToFlowMessageException; + + void delete(Long messageId); + + void close(); +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java new file mode 100644 index 0000000000..3dd23a2f40 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java @@ -0,0 +1,32 @@ +/* + * + * 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 org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.commons.configuration.ConfigurationException; + +public interface QueueBackingStoreFactory +{ + void configure(VirtualHost virtualHost, VirtualHostConfiguration config) throws ConfigurationException; + + public QueueBackingStore createBacking(AMQQueue queue); +} 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 0df976a620..fb23edb3c5 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 @@ -49,7 +49,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept public abstract State getState(); } - public final class AvailableState extends EntryState { @@ -59,7 +58,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept } } - public final class DequeuedState extends EntryState { @@ -69,7 +67,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept } } - public final class DeletedState extends EntryState { @@ -88,7 +85,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept } } - public final class NonSubscriptionAcquiredState extends EntryState { public State getState() @@ -106,7 +102,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept _subscription = subscription; } - public State getState() { return State.ACQUIRED; @@ -118,42 +113,83 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept } } - final static EntryState AVAILABLE_STATE = new AvailableState(); final static EntryState DELETED_STATE = new DeletedState(); final static EntryState DEQUEUED_STATE = new DequeuedState(); final static EntryState EXPIRED_STATE = new ExpiredState(); final static EntryState NON_SUBSCRIPTION_ACQUIRED_STATE = new NonSubscriptionAcquiredState(); + /** Flag to indicate that this message requires 'immediate' delivery. */ + + final static byte IMMEDIATE = 0x01; + + /** + * Flag to indicate whether this message has been delivered to a consumer. Used in implementing return functionality + * for messages published with the 'immediate' flag. + */ + final static byte DELIVERED_TO_CONSUMER = 0x02; AMQQueue getQueue(); AMQMessage getMessage(); + Long getMessageId(); + long getSize(); + /** + * Called selectors to determin if the message has already been sent + * + * @return _deliveredToConsumer + */ boolean getDeliveredToConsumer(); + /** + * Checks to see if the message has expired. If it has the message is dequeued. + * + * @return true if the message has expire + * + * @throws org.apache.qpid.AMQException + */ boolean expired() throws AMQException; + public void setExpiration(final long expiration); + boolean isAcquired(); + boolean isAvailable(); + boolean acquire(); + boolean acquire(Subscription sub); boolean delete(); + boolean isDeleted(); boolean acquiredBySubscription(); - + + /** + * Called when this message is delivered to a consumer. (used to implement the 'immediate' flag functionality). + * And for selector efficiency. + * + * This is now also used to unload the message if this entry is on a flowed queue. As a result this method should + * only be called after the message has been sent. + */ void setDeliveredToSubscription(); void release(); String debugIdentity(); + /** + * Called to enforce the 'immediate' flag. + * + * @returns true if the message is marked for immediate delivery but has not been marked as delivered + * to a consumer + */ boolean immediateAndNotDelivered(); void setRedelivered(boolean b); @@ -170,12 +206,28 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept void dequeue(final StoreContext storeContext) throws FailedDequeueException; - void dispose(final StoreContext storeContext) throws MessageCleanupException; - - void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException; + /** + * Message has been ack so dequeueAndDelete it. + * If the message is persistent and this is the last QueueEntry that uses it then the data will be removed + * from the transaciton log + * + * @param storeContext the transactional Context in which to perform the deletion + * + * @throws FailedDequeueException + * @throws MessageCleanupException + */ + void dequeueAndDelete(StoreContext storeContext) throws FailedDequeueException; boolean isQueueDeleted(); void addStateChangeListener(StateChangeListener listener); + boolean removeStateChangeListener(StateChangeListener listener); -} + + void unload(); + + AMQMessage load(); + + boolean isFlowed(); + +}
\ No newline at end of file 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 ba14be5580..b6e6365189 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 @@ -20,30 +20,29 @@ */ package org.apache.qpid.server.queue; +import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.subscription.Subscription; -import org.apache.log4j.Logger; -import java.util.Set; import java.util.HashSet; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; - +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; public class QueueEntryImpl implements QueueEntry { - /** - * Used for debugging purposes. - */ + /** Used for debugging purposes. */ private static final Logger _log = Logger.getLogger(QueueEntryImpl.class); private final SimpleQueueEntryList _queueEntryList; - private AMQMessage _message; + private AtomicReference<AMQMessage> _messageRef; private boolean _redelivered; @@ -52,44 +51,51 @@ public class QueueEntryImpl implements QueueEntry private volatile EntryState _state = AVAILABLE_STATE; private static final - AtomicReferenceFieldUpdater<QueueEntryImpl, EntryState> + AtomicReferenceFieldUpdater<QueueEntryImpl, EntryState> _stateUpdater = - AtomicReferenceFieldUpdater.newUpdater - (QueueEntryImpl.class, EntryState.class, "_state"); - + AtomicReferenceFieldUpdater.newUpdater + (QueueEntryImpl.class, EntryState.class, "_state"); private volatile Set<StateChangeListener> _stateChangeListeners; private static final - AtomicReferenceFieldUpdater<QueueEntryImpl, Set> - _listenersUpdater = - AtomicReferenceFieldUpdater.newUpdater - (QueueEntryImpl.class, Set.class, "_stateChangeListeners"); - + AtomicReferenceFieldUpdater<QueueEntryImpl, Set> + _listenersUpdater = + AtomicReferenceFieldUpdater.newUpdater + (QueueEntryImpl.class, Set.class, "_stateChangeListeners"); private static final - AtomicLongFieldUpdater<QueueEntryImpl> + AtomicLongFieldUpdater<QueueEntryImpl> _entryIdUpdater = - AtomicLongFieldUpdater.newUpdater - (QueueEntryImpl.class, "_entryId"); - + AtomicLongFieldUpdater.newUpdater + (QueueEntryImpl.class, "_entryId"); private volatile long _entryId; volatile QueueEntryImpl _next; + private long _messageSize; + private QueueBackingStore _backingStore; + private AtomicBoolean _flowed; + private Long _messageId; + + private byte _flags = 0; + + private long _expiration; + + private static final byte IMMEDIATE_AND_DELIVERED = (byte) (IMMEDIATE | DELIVERED_TO_CONSUMER); + private boolean _persistent; + private boolean _hasBeenUnloaded = false; QueueEntryImpl(SimpleQueueEntryList queueEntryList) { - this(queueEntryList,null,Long.MIN_VALUE); + this(queueEntryList, null, Long.MIN_VALUE); _state = DELETED_STATE; } - public QueueEntryImpl(SimpleQueueEntryList queueEntryList, AMQMessage message, final long entryId) { - _queueEntryList = queueEntryList; - _message = message; + this(queueEntryList, message); _entryIdUpdater.set(this, entryId); } @@ -97,7 +103,21 @@ public class QueueEntryImpl implements QueueEntry public QueueEntryImpl(SimpleQueueEntryList queueEntryList, AMQMessage message) { _queueEntryList = queueEntryList; - _message = message; + _messageRef = new AtomicReference<AMQMessage>(message); + if (message != null) + { + _messageId = message.getMessageId(); + _messageSize = message.getSize(); + + if (message.isImmediate()) + { + _flags |= IMMEDIATE; + } + _expiration = message.getExpiration(); + _persistent = message.isPersistent(); + } + _backingStore = queueEntryList.getBackingStore(); + _flowed = new AtomicBoolean(false); } protected void setEntryId(long entryId) @@ -117,22 +137,50 @@ public class QueueEntryImpl implements QueueEntry public AMQMessage getMessage() { - return _message; + return load(); + } + + public Long getMessageId() + { + return _messageId; } public long getSize() { - return getMessage().getSize(); + return _messageSize; } public boolean getDeliveredToConsumer() { - return getMessage().getDeliveredToConsumer(); + return (_flags & DELIVERED_TO_CONSUMER) != 0; + } + + public void setDeliveredToSubscription() + { + _flags |= DELIVERED_TO_CONSUMER; + + // We have delivered this message so we can unload it if we are flowed. + if (_queueEntryList.isFlowed()) + { + unload(); + } } public boolean expired() throws AMQException { - return getMessage().expired(); + if (_expiration != 0L) + { + long now = System.currentTimeMillis(); + + return (now > _expiration); + } + + return false; + } + + public void setExpiration(final long expiration) + { + _expiration = expiration; } public boolean isAcquired() @@ -140,6 +188,11 @@ public class QueueEntryImpl implements QueueEntry return _state.getState() == State.ACQUIRED; } + public boolean isAvailable() + { + return _state.getState() == State.AVAILABLE; + } + public boolean acquire() { return acquire(NON_SUBSCRIPTION_ACQUIRED_STATE); @@ -147,8 +200,8 @@ public class QueueEntryImpl implements QueueEntry private boolean acquire(final EntryState state) { - boolean acquired = _stateUpdater.compareAndSet(this,AVAILABLE_STATE, state); - if(acquired && _stateChangeListeners != null) + boolean acquired = _stateUpdater.compareAndSet(this, AVAILABLE_STATE, state); + if (acquired && _stateChangeListeners != null) { notifyStateChange(State.AVAILABLE, State.ACQUIRED); } @@ -167,35 +220,41 @@ public class QueueEntryImpl implements QueueEntry return (_state instanceof SubscriptionAcquiredState); } - public void setDeliveredToSubscription() - { - getMessage().setDeliveredToConsumer(); - } - public void release() { - _stateUpdater.set(this,AVAILABLE_STATE); + _stateUpdater.set(this, AVAILABLE_STATE); } public String debugIdentity() { - return getMessage().debugIdentity(); - } + String entry = "[State:" + _state.getState().name() + "]"; + AMQMessage message = _messageRef.get(); - public boolean immediateAndNotDelivered() + if (message == null) + { + return entry + "(Message Unloaded ID:" + _messageId + ")"; + } + else + { + + return entry + message.debugIdentity(); + } + } + + public boolean immediateAndNotDelivered() { - return _message.immediateAndNotDelivered(); + return (_flags & IMMEDIATE_AND_DELIVERED) == IMMEDIATE; } public ContentHeaderBody getContentHeaderBody() throws AMQException { - return _message.getContentHeaderBody(); + return getMessage().getContentHeaderBody(); } public boolean isPersistent() throws AMQException { - return _message.isPersistent(); + return _persistent; } public boolean isRedelivered() @@ -206,21 +265,21 @@ public class QueueEntryImpl implements QueueEntry public void setRedelivered(boolean redelivered) { _redelivered = redelivered; - // todo - here we could mark this message as redelivered so we don't have to mark - // all messages on recover as redelivered. + // todo - here we could record this message as redelivered on this queue in the transactionLog + // so we don't have to mark all messages on recover as redelivered. } public Subscription getDeliveredSubscription() { - EntryState state = _state; - if (state instanceof SubscriptionAcquiredState) - { - return ((SubscriptionAcquiredState) state).getSubscription(); - } - else - { - return null; - } + EntryState state = _state; + if (state instanceof SubscriptionAcquiredState) + { + return ((SubscriptionAcquiredState) state).getSubscription(); + } + else + { + return null; + } } @@ -247,7 +306,7 @@ public class QueueEntryImpl implements QueueEntry } public boolean isRejectedBy(Subscription subscription) - { + { if (_rejectedBy != null) // We have subscriptions that rejected this message { @@ -259,11 +318,10 @@ public class QueueEntryImpl implements QueueEntry } } - public void requeue(final StoreContext storeContext) throws AMQException { getQueue().requeue(storeContext, this); - if(_stateChangeListeners != null) + if (_stateChangeListeners != null) { notifyStateChange(QueueEntry.State.ACQUIRED, QueueEntry.State.AVAILABLE); } @@ -273,7 +331,7 @@ public class QueueEntryImpl implements QueueEntry { EntryState state = _state; - if((state.getState() == State.ACQUIRED) &&_stateUpdater.compareAndSet(this, state, DEQUEUED_STATE)) + if ((state.getState() == State.ACQUIRED) && _stateUpdater.compareAndSet(this, state, DEQUEUED_STATE)) { if (state instanceof SubscriptionAcquiredState) { @@ -281,41 +339,34 @@ public class QueueEntryImpl implements QueueEntry s.restoreCredit(this); } + _queueEntryList.dequeued(this); + getQueue().dequeue(storeContext, this); - if(_stateChangeListeners != null) + + if (_stateChangeListeners != null) { - notifyStateChange(state.getState() , QueueEntry.State.DEQUEUED); + notifyStateChange(state.getState(), QueueEntry.State.DEQUEUED); } - } - } private void notifyStateChange(final State oldState, final State newState) { - for(StateChangeListener l : _stateChangeListeners) + for (StateChangeListener l : _stateChangeListeners) { l.stateChanged(this, oldState, newState); } } - public void dispose(final StoreContext storeContext) throws MessageCleanupException + public void dequeueAndDelete(StoreContext storeContext) throws FailedDequeueException { - if(delete()) - { - getMessage().decrementReference(storeContext); - } - } - - public void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException - { - //if the queue is null then the message is waiting to be acked, but has been removed. + //if the queue is null (i.e. queue.delete()'d) then the message is waiting to be acked, but has already be delete()'d; if (getQueue() != null) { dequeue(storeContext); } - dispose(storeContext); + delete(); } public boolean isQueueDeleted() @@ -326,7 +377,7 @@ public class QueueEntryImpl implements QueueEntry public void addStateChangeListener(StateChangeListener listener) { Set<StateChangeListener> listeners = _stateChangeListeners; - if(listeners == null) + if (listeners == null) { _listenersUpdater.compareAndSet(this, null, new CopyOnWriteArraySet<StateChangeListener>()); listeners = _stateChangeListeners; @@ -338,7 +389,7 @@ public class QueueEntryImpl implements QueueEntry public boolean removeStateChangeListener(StateChangeListener listener) { Set<StateChangeListener> listeners = _stateChangeListeners; - if(listeners != null) + if (listeners != null) { return listeners.remove(listener); } @@ -346,10 +397,108 @@ public class QueueEntryImpl implements QueueEntry return false; } + public void unload() + { + //Get the currently loaded message + AMQMessage message = _messageRef.get(); + + // If we have a message in memory and we have a valid backingStore attempt to unload + if (message != null && _backingStore != null) + { + try + { + // The backingStore will now handle concurrent calls to unload and safely synchronize to ensure + // multiple initial unloads are unloads + _backingStore.unload(message); + _hasBeenUnloaded = true; + _messageRef.set(null); + + if (_log.isDebugEnabled()) + { + _log.debug("Unloaded:" + debugIdentity()); + } + + + // Clear the message reference if the loaded message is still the one we are processing. + + //Update the memoryState if this load call resulted in the message being purged from memory + if (!_flowed.getAndSet(true)) + { + _queueEntryList.entryUnloadedUpdateMemory(this); + } + + } + catch (UnableToFlowMessageException utfme) + { + // There is no recovery needed as the memory states remain unchanged. + if (_log.isDebugEnabled()) + { + _log.debug("Unable to Flow message:" + debugIdentity() + ", due to:" + utfme.getMessage()); + } + } + } + } + + public AMQMessage load() + { + // MessageId and Backing store are null in test scenarios, normally this is not the case. + if (_messageId != null && _backingStore != null) + { + // See if we have the message currently in memory to return + AMQMessage message = _messageRef.get(); + // if we don't then we need to start a load process. + if (message == null) + { + //Synchronize here to ensure only the first thread that attempts to load will perform the load from the + // backing store. + synchronized (this) + { + // Check again to see if someone else ahead of us loaded the message + message = _messageRef.get(); + // if we still don't have the message then we need to start a load process. + if (message == null) + { + // Load the message and keep a reference to it + message = _backingStore.load(_messageId); + // Set the message reference + _messageRef.set(message); + } + else + { + // If someone else loaded the message then we can jump out here as the Memory Updates will + // have been performed by the loading thread + return message; + } + } + + if (_log.isDebugEnabled()) + { + _log.debug("Loaded:" + debugIdentity()); + } + + //Update the memoryState if this load call resulted in the message comming in to memory + if (_flowed.getAndSet(false)) + { + _queueEntryList.entryLoadedUpdateMemory(this); + } + } + + // Return the message that was either already in memory or the value we just loaded. + return message; + } + // This can be null but only in the case where we have no messageId + // in the case where we have no backingStore then we will never have unloaded the message + return _messageRef.get(); + } + + public boolean isFlowed() + { + return _flowed.get(); + } public int compareTo(final QueueEntry o) { - QueueEntryImpl other = (QueueEntryImpl)o; + QueueEntryImpl other = (QueueEntryImpl) o; return getEntryId() > other.getEntryId() ? 1 : getEntryId() < other.getEntryId() ? -1 : 0; } @@ -357,13 +506,13 @@ public class QueueEntryImpl implements QueueEntry { QueueEntryImpl next = nextNode(); - while(next != null && next.isDeleted()) + while (next != null && next.isDeleted()) { final QueueEntryImpl newNext = next.nextNode(); - if(newNext != null) + if (newNext != null) { - SimpleQueueEntryList._nextUpdater.compareAndSet(this,next, newNext); + SimpleQueueEntryList._nextUpdater.compareAndSet(this, next, newNext); next = nextNode(); } else @@ -389,9 +538,13 @@ public class QueueEntryImpl implements QueueEntry { EntryState state = _state; - if(state != DELETED_STATE && _stateUpdater.compareAndSet(this,state,DELETED_STATE)) + if (state != DELETED_STATE && _stateUpdater.compareAndSet(this, state, DELETED_STATE)) { - _queueEntryList.advanceHead(); + _queueEntryList.advanceHead(); + if (_backingStore != null && _hasBeenUnloaded) + { + _backingStore.delete(_messageId); + } return true; } else @@ -404,4 +557,5 @@ public class QueueEntryImpl implements QueueEntry { return _queueEntryList; } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java index 313e076f61..a58c6eaf7d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java @@ -1,23 +1,23 @@ /* -* -* 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. -* -*/ + * + * 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; public interface QueueEntryList @@ -31,4 +31,36 @@ public interface QueueEntryList QueueEntryIterator iterator(); QueueEntry getHead(); + + void setFlowed(boolean flowed); + + boolean isFlowed(); + + int size(); + + long dataSize(); + + long memoryUsed(); + + void setMemoryUsageMaximum(long maximumMemoryUsage); + + long getMemoryUsageMaximum(); + + void setMemoryUsageMinimum(long minimumMemoryUsage); + + long getMemoryUsageMinimum(); + + /** + * Immediately update memory usage based on the unload of this queueEntry, potentially start inhaler. + * @param queueEntry the entry that has been unloaded + */ + void entryUnloadedUpdateMemory(QueueEntry queueEntry); + + /** + * Immediately update memory usage based on the load of this queueEntry + * @param queueEntry the entry that has been loaded + */ + void entryLoadedUpdateMemory(QueueEntry queueEntry); + + void stop(); } 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 a08e4e2667..ed9b1eb8d7 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 @@ -1,28 +1,9 @@ package org.apache.qpid.server.queue; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.configuration.Configurator; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.subscription.SubscriptionList; -import org.apache.qpid.server.output.ProtocolOutputConverter; -import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.transactionlog.TransactionLog; -import org.apache.qpid.AMQException; -import org.apache.qpid.pool.ReadWriteRunnable; -import org.apache.qpid.pool.ReferenceCountingExecutorService; -import org.apache.qpid.configuration.Configured; -import org.apache.commons.configuration.Configuration; -import org.apache.log4j.Logger; - -import javax.management.JMException; -import java.util.List; -import java.util.Set; import java.util.ArrayList; import java.util.EnumSet; +import java.util.List; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -30,6 +11,24 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import javax.management.JMException; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.pool.ReadWriteRunnable; +import org.apache.qpid.pool.ReferenceCountingExecutorService; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.output.ProtocolOutputConverter; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.subscription.SubscriptionList; +import org.apache.qpid.server.transactionlog.TransactionLog; +import org.apache.qpid.server.virtualhost.VirtualHost; + /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -73,10 +72,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener private final List<Task> _deleteTaskList = new CopyOnWriteArrayList<Task>(); - private final AtomicInteger _atomicQueueCount = new AtomicInteger(0); - - private final AtomicLong _atomicQueueSize = new AtomicLong(0L); - private final AtomicInteger _activeSubscriberCount = new AtomicInteger(); protected final SubscriptionList _subscriptionList = new SubscriptionList(this); @@ -91,24 +86,20 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener private final AtomicLong _totalMessagesReceived = new AtomicLong(); /** max allowed size(KB) of a single message */ - @Configured(path = "maximumMessageSize", defaultValue = "0") - public long _maximumMessageSize; + public long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize(); /** max allowed number of messages on a queue. */ - @Configured(path = "maximumMessageCount", defaultValue = "0") - public long _maximumMessageCount; + public long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount(); /** max queue depth for the queue */ - @Configured(path = "maximumQueueDepth", defaultValue = "0") - public long _maximumQueueDepth; + public long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth(); /** maximum message age before alerts occur */ - @Configured(path = "maximumMessageAge", defaultValue = "0") - public long _maximumMessageAge; + public long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge(); + + /** the minimum interval between sending out consecutive alerts of the same type */ + public long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap(); - /** the minimum interval between sending out consequetive alerts of the same type */ - @Configured(path = "minimumAlertRepeatGap", defaultValue = "0") - public long _minimumAlertRepeatGap; private static final int MAX_ASYNC_DELIVERIES = 10; @@ -164,10 +155,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener } resetNotifications(); - } - private void resetNotifications() + public void resetNotifications() { // This ensure that the notification checks for the configured alerts are created. setMaximumMessageAge(_maximumMessageAge); @@ -193,6 +183,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener return _autoDelete; } + public boolean isFlowed() + { + return _entries.isFlowed(); + } + public AMQShortString getOwner() { return _owner; @@ -326,10 +321,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener public QueueEntry enqueue(StoreContext storeContext, AMQMessage message) throws AMQException { - - incrementQueueCount(); - incrementQueueSize(message); - _totalMessagesReceived.incrementAndGet(); QueueEntry entry; @@ -413,8 +404,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener if (entry.immediateAndNotDelivered()) { - dequeue(storeContext, entry); - entry.dispose(storeContext); + //We acquire the message here to ensure that the dequeueAndDelete will correctly remove the content + // from the transactionLog. This saves us from having to have a custom dequeueAndDelete that checks + // for the AVAILABLE state of an entry rather than the ACQUIRED state that it currently uses. + entry.acquire(); + entry.dequeueAndDelete(storeContext); } else if (!(entry.isAcquired() || entry.isDeleted())) { @@ -423,7 +417,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener deliverAsync(); } - _managedObject.checkForNotification(entry.getMessage()); + _managedObject.checkForNotification(entry); return entry; } @@ -467,20 +461,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener // Simple Queues don't :-) } - private void incrementQueueSize(final AMQMessage message) - { - getAtomicQueueSize().addAndGet(message.getSize()); - } - - private void incrementQueueCount() - { - getAtomicQueueCount().incrementAndGet(); - } - private void deliverMessage(final Subscription sub, final QueueEntry entry) throws AMQException { _deliveredMessages.incrementAndGet(); + sub.send(entry); } @@ -567,10 +552,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener } + /** + * Only call from queue Entry + * @param storeContext + * @param entry + * @throws FailedDequeueException + */ public void dequeue(StoreContext storeContext, QueueEntry entry) throws FailedDequeueException { - decrementQueueCount(); - decrementQueueSize(entry); if (entry.acquiredBySubscription()) { _deliveredMessages.decrementAndGet(); @@ -578,12 +567,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener try { - AMQMessage msg = entry.getMessage(); - if (msg.isPersistent()) + if (entry.isPersistent()) { - _virtualHost.getTransactionLog().dequeueMessage(storeContext, this, msg.getMessageId()); + _virtualHost.getTransactionLog().dequeueMessage(storeContext, this, entry.getMessageId()); } - //entry.dispose(storeContext); } catch (MessageCleanupException e) @@ -601,15 +588,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener } - private void decrementQueueSize(final QueueEntry entry) - { - getAtomicQueueSize().addAndGet(-entry.getMessage().getSize()); - } - - void decrementQueueCount() - { - getAtomicQueueCount().decrementAndGet(); - } public boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException { @@ -655,14 +633,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener return getMessageCount() == 0; } + public long getMemoryUsageCurrent() + { + return getQueueInMemory(); + } + public int getMessageCount() { - return getAtomicQueueCount().get(); + return getQueueCount(); } public long getQueueDepth() { - return getAtomicQueueSize().get(); + return getQueueSize(); } public int getUndeliveredMessageCount() @@ -738,14 +721,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener return _name.compareTo(o.getName()); } - public AtomicInteger getAtomicQueueCount() + public int getQueueCount() { - return _atomicQueueCount; + return _entries.size(); } - public AtomicLong getAtomicQueueSize() + public long getQueueSize() { - return _atomicQueueSize; + return _entries.dataSize(); + } + + public long getQueueInMemory() + { + return _entries.memoryUsed(); } private boolean isExclusiveSubscriber() @@ -772,7 +760,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener public boolean accept(QueueEntry entry) { - final long messageId = entry.getMessage().getMessageId(); + final long messageId = entry.getMessageId(); return messageId >= fromMessageId && messageId <= toMessageId; } @@ -791,7 +779,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener public boolean accept(QueueEntry entry) { - _complete = entry.getMessage().getMessageId() == messageId; + _complete = entry.getMessageId() == messageId; return _complete; } @@ -819,11 +807,18 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener } + public void moveMessagesToAnotherQueue(final long fromMessageId, final long toMessageId, String queueName, StoreContext storeContext) { + // The move is a two step process. First the messages are moved in the _transactionLog. + // That is persistent messages are moved queues on disk for recovery and the QueueEntries removed from the + // existing queue. + // This is done as Queue.enqueue() does not write the data to the transactionLog. In normal message delivery + // this is done as the message is recieved. + // So The final step is to enqueue the messages on the new queue. AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); TransactionLog transactionLog = getVirtualHost().getTransactionLog(); @@ -833,7 +828,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener public boolean accept(QueueEntry entry) { - final long messageId = entry.getMessage().getMessageId(); + final long messageId = entry.getMessageId(); return (messageId >= fromMessageId) && (messageId <= toMessageId) && entry.acquire(); @@ -849,16 +844,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener { transactionLog.beginTran(storeContext); - // Move the messages in on the transaction log. + // Move the messages in the transaction log. for (QueueEntry entry : entries) { - AMQMessage message = entry.getMessage(); - - if (message.isPersistent() && toQueue.isDurable()) + if (entry.isPersistent() && toQueue.isDurable()) { - transactionLog.enqueueMessage(storeContext, toQueue, message.getMessageId()); + transactionLog.enqueueMessage(storeContext, toQueue, entry.getMessageId()); } - // dequeue does not decrement the refence count + // dequeue will remove the messages from the queue entry.dequeue(storeContext); } @@ -887,10 +880,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener try { + // Add messages to new queue for (QueueEntry entry : entries) { toQueue.enqueue(storeContext, entry.getMessage()); - + // As we only did a dequeue above now that we have moved the message we should perform a delete. + // We cannot do this earlier as the message will be lost if flowed. + //entry.delete(); } } catch (MessageCleanupException e) @@ -917,13 +913,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener public boolean accept(QueueEntry entry) { - final long messageId = entry.getMessage().getMessageId(); + final long messageId = entry.getMessageId(); if ((messageId >= fromMessageId) && (messageId <= toMessageId)) { if (!entry.isDeleted()) { - return entry.getMessage().incrementReference(); + return true; } } @@ -943,11 +939,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener // Move the messages in on the transaction log. for (QueueEntry entry : entries) { - AMQMessage message = entry.getMessage(); - - if (message.isReferenced() && message.isPersistent() && toQueue.isDurable()) + if (!entry.isDeleted() && entry.isPersistent() && toQueue.isDurable()) { - transactionLog.enqueueMessage(storeContext, toQueue, message.getMessageId()); + transactionLog.enqueueMessage(storeContext, toQueue, entry.getMessageId()); } } @@ -978,7 +972,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener { for (QueueEntry entry : entries) { - if (entry.getMessage().isReferenced()) + if (!entry.isDeleted()) { toQueue.enqueue(storeContext, entry.getMessage()); } @@ -1006,14 +1000,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener { QueueEntry node = queueListIterator.getNode(); - final long messageId = node.getMessage().getMessageId(); + final long messageId = node.getMessageId(); if ((messageId >= fromMessageId) && (messageId <= toMessageId) && !node.isDeleted() && node.acquire()) { - node.discard(storeContext); + node.dequeueAndDelete(storeContext); } } @@ -1037,7 +1031,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener QueueEntry node = queueListIterator.getNode(); if (!node.isDeleted() && node.acquire()) { - node.discard(storeContext); + node.dequeueAndDelete(storeContext); noDeletes = false; } @@ -1055,7 +1049,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener QueueEntry node = queueListIterator.getNode(); if (!node.isDeleted() && node.acquire()) { - node.discard(storeContext); + node.dequeueAndDelete(storeContext); count++; } @@ -1106,6 +1100,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener if (!_stopped.getAndSet(true)) { ReferenceCountingExecutorService.getInstance().releaseExecutorService(); + _entries.stop(); } } @@ -1320,8 +1315,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener { if (node.acquire()) { + // creating a new final store context per message seems wasteful. final StoreContext reapingStoreContext = new StoreContext(); - node.discard(reapingStoreContext); + node.dequeueAndDelete(reapingStoreContext); } } QueueEntry newNode = _entries.next(node); @@ -1423,7 +1419,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener } } - @Override + public void checkMessageStatus() throws AMQException { @@ -1436,16 +1432,37 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener QueueEntry node = queueListIterator.getNode(); if (!node.isDeleted() && node.expired() && node.acquire()) { - node.discard(storeContext); + node.dequeueAndDelete(storeContext); } else { - _managedObject.checkForNotification(node.getMessage()); + _managedObject.checkForNotification(node); } } } + + public long getMemoryUsageMaximum() + { + return _entries.getMemoryUsageMaximum(); + } + + public void setMemoryUsageMaximum(long maximumMemoryUsage) + { + _entries.setMemoryUsageMaximum(maximumMemoryUsage); + } + + public long getMemoryUsageMinimum() + { + return _entries.getMemoryUsageMinimum(); + } + + public void setMemoryUsageMinimum(long minimumMemoryUsage) + { + _entries.setMemoryUsageMinimum(minimumMemoryUsage); + } + public long getMinimumAlertRepeatGap() { return _minimumAlertRepeatGap; @@ -1586,14 +1603,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener for (int i = 0; i < num && !it.atTail(); i++) { it.advance(); - ids.add(it.getNode().getMessage().getMessageId()); + ids.add(it.getNode().getMessageId()); } return ids; } - public void configure(Configuration queueConfiguration) + + public String getType() { - Configurator.configure(this, queueConfiguration); - resetNotifications(); + return getClass().getSimpleName() + "[" + getName() +"]"; + } + + public String toString() + { + return getType() + "[Owner:" + _owner + "][Durable:" + _durable + "]"; } -}
\ No newline at end of file +} 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 a46c5ae2e8..a10e332ef5 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 @@ -22,8 +22,9 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; * under the License. * */ -public class SimpleQueueEntryList implements QueueEntryList +public class SimpleQueueEntryList extends FlowableBaseQueueEntryList { + private final QueueEntryImpl _head; private volatile QueueEntryImpl _tail; @@ -41,12 +42,9 @@ public class SimpleQueueEntryList implements QueueEntryList AtomicReferenceFieldUpdater.newUpdater (QueueEntryImpl.class, QueueEntryImpl.class, "_next"); - - - - public SimpleQueueEntryList(AMQQueue queue) { + super(queue); _queue = queue; _head = new QueueEntryImpl(this); _tail = _head; @@ -77,6 +75,9 @@ public class SimpleQueueEntryList implements QueueEntryList public QueueEntry add(AMQMessage message) { QueueEntryImpl node = new QueueEntryImpl(this, message); + + incrementCounters(node); + for (;;) { QueueEntryImpl tail = _tail; @@ -101,12 +102,12 @@ public class SimpleQueueEntryList implements QueueEntryList } } + public QueueEntry next(QueueEntry node) { return ((QueueEntryImpl)node).getNext(); } - public class QueueEntryIteratorImpl implements QueueEntryIterator { @@ -172,7 +173,9 @@ public class SimpleQueueEntryList implements QueueEntryList { return new SimpleQueueEntryList(queue); } + } - + + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java index 8c62e046f8..4c9fe81439 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java @@ -32,21 +32,17 @@ import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.store.StoreContext; +import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Collections; -import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; -/** - * A deliverable message. - */ +/** A deliverable message. */ public class TransientAMQMessage implements AMQMessage { /** Used for debugging purposes. */ - private static final Logger _log = Logger.getLogger(AMQMessage.class); - - private final AtomicInteger _referenceCount = new AtomicInteger(1); + protected static final Logger _log = Logger.getLogger(AMQMessage.class); protected ContentHeaderBody _contentHeaderBody; @@ -59,24 +55,10 @@ public class TransientAMQMessage implements AMQMessage protected final Long _messageId; - - /** Flag to indicate that this message requires 'immediate' delivery. */ - - private static final byte IMMEDIATE = 0x01; - - /** - * Flag to indicate whether this message has been delivered to a consumer. Used in implementing return functionality - * for messages published with the 'immediate' flag. - */ - - private static final byte DELIVERED_TO_CONSUMER = 0x02; - private byte _flags = 0; - private long _expiration; - private AMQProtocolSession.ProtocolSessionIdentifier _sessionIdentifier; - private static final byte IMMEDIATE_AND_DELIVERED = (byte) (IMMEDIATE | DELIVERED_TO_CONSUMER); + private long _expiration; /** * Used to iterate through all the body frames associated with this message. Will not keep all the data in memory @@ -143,23 +125,23 @@ public class TransientAMQMessage implements AMQMessage /** * Used by SimpleAMQQueueTest, TxAckTest.TestMessage, AbstractHeaderExchangeTestBase.Message * These all need refactoring to some sort of MockAMQMessageFactory. - */ + */ @Deprecated protected TransientAMQMessage(AMQMessage message) throws AMQException { _messageId = message.getMessageId(); - _flags = ((TransientAMQMessage)message)._flags; + _flags = ((TransientAMQMessage) message)._flags; _contentHeaderBody = message.getContentHeaderBody(); _messagePublishInfo = message.getMessagePublishInfo(); } - /** * Normal message creation via the MessageFactory uses this constructor * Package scope limited as MessageFactory should be used - * @see MessageFactory * * @param messageId + * + * @see MessageFactory */ TransientAMQMessage(Long messageId) { @@ -168,17 +150,17 @@ public class TransientAMQMessage implements AMQMessage public String debugIdentity() { - return "(HC:" + System.identityHashCode(this) + " ID:" + getMessageId() + " Ref:" + _referenceCount.get() + ")"; + return "(HC:" + System.identityHashCode(this) + " ID:" + getMessageId() +")"; } - public void setExpiration(final long expiration) + public void setExpiration(long expiration) { _expiration = expiration; } - public boolean isReferenced() + public long getExpiration() { - return _referenceCount.get() > 0; + return _expiration; } public Iterator<AMQDataBlock> getBodyFrameIterator(AMQProtocolSession protocolSession, int channel) @@ -191,7 +173,6 @@ public class TransientAMQMessage implements AMQMessage return new BodyContentIterator(); } - public ContentHeaderBody getContentHeaderBody() { return _contentHeaderBody; @@ -202,139 +183,6 @@ public class TransientAMQMessage implements AMQMessage return _messageId; } - /** - * Creates a long-lived reference to this message, and increments the count of such references, as an atomic - * operation. - */ - public AMQMessage takeReference() - { - incrementReference(); // _referenceCount.incrementAndGet(); - - return this; - } - - public boolean incrementReference() - { - return incrementReference(1); - } - - /* Threadsafe. Increment the reference count on the message. */ - public boolean incrementReference(int count) - { - if(_referenceCount.addAndGet(count) <= 1) - { - _referenceCount.addAndGet(-count); - return false; - } - else - { - return true; - } - - } - - /** - * Threadsafe. This will decrement the reference count and when it reaches zero will remove the message from the - * message store. - * - * @param storeContext - * - * @throws MessageCleanupException when an attempt was made to remove the message from the message store and that - * failed - */ - public void decrementReference(StoreContext storeContext) throws MessageCleanupException - { - - int count = _referenceCount.decrementAndGet(); - - // note that the operation of decrementing the reference count and then removing the message does not - // have to be atomic since the ref count starts at 1 and the exchange itself decrements that after - // the message has been passed to all queues. i.e. we are - // not relying on the all the increments having taken place before the delivery manager decrements. - if (count == 0) - { - // set the reference count way below 0 so that we can detect that the message has been deleted - // this is to guard against the message being spontaneously recreated (from the mgmt console) - // by copying from other queues at the same time as it is being removed. - _referenceCount.set(Integer.MIN_VALUE/2); - - try - { - // must check if the handle is null since there may be cases where we decide to throw away a message - // and the handle has not yet been constructed - // no need to perform persistent check anymore as TransientAMQM.removeMessage() is a no-op - removeMessage(storeContext); - } - catch (AMQException e) - { - // to maintain consistency, we revert the count - incrementReference(); - throw new MessageCleanupException(getMessageId(), e); - } - } - else - { - if (count < 0) - { - throw new MessageCleanupException("Reference count for message id " + debugIdentity() - + " has gone below 0."); - } - } - } - - - /** - * Called selectors to determin if the message has already been sent - * - * @return _deliveredToConsumer - */ - public boolean getDeliveredToConsumer() - { - return (_flags & DELIVERED_TO_CONSUMER) != 0; - } - - /** - * Called to enforce the 'immediate' flag. - * - * @returns true if the message is marked for immediate delivery but has not been marked as delivered - * to a consumer - */ - public boolean immediateAndNotDelivered() - { - - return (_flags & IMMEDIATE_AND_DELIVERED) == IMMEDIATE; - - } - - /** - * Checks to see if the message has expired. If it has the message is dequeued. - * - * @return true if the message has expire - * - * @throws AMQException - */ - public boolean expired() throws AMQException - { - - if (_expiration != 0L) - { - long now = System.currentTimeMillis(); - - return (now > _expiration); - } - - return false; - } - - /** - * Called when this message is delivered to a consumer. (used to implement the 'immediate' flag functionality). - * And for selector efficiency. - */ - public void setDeliveredToConsumer() - { - _flags |= DELIVERED_TO_CONSUMER; - } - public long getSize() { @@ -345,7 +193,7 @@ public class TransientAMQMessage implements AMQMessage { return _sessionIdentifier.getSessionInstance(); } - + public Object getPublisherIdentifier() { return _sessionIdentifier.getSessionIdentifier(); @@ -356,7 +204,7 @@ public class TransientAMQMessage implements AMQMessage _sessionIdentifier = sessionIdentifier; } - /** From AMQMessageHandle **/ + /** From AMQMessageHandle * */ public int getBodyCount() { @@ -365,7 +213,7 @@ public class TransientAMQMessage implements AMQMessage public ContentChunk getContentChunk(int index) { - if(_contentBodies == null) + if (_contentBodies == null) { throw new RuntimeException("No ContentBody has been set"); } @@ -381,9 +229,9 @@ public class TransientAMQMessage implements AMQMessage public void addContentBodyFrame(StoreContext storeContext, ContentChunk contentChunk, boolean isLastContentBody) throws AMQException { - if(_contentBodies == null) + if (_contentBodies == null) { - if(isLastContentBody) + if (isLastContentBody) { _contentBodies = Collections.singletonList(contentChunk); } @@ -409,11 +257,17 @@ public class TransientAMQMessage implements AMQMessage return false; } + public boolean isImmediate() + { + return _messagePublishInfo.isImmediate(); + } + /** * This is called when all the content has been received. + * * @param storeContext - *@param messagePublishInfo - * @param contentHeaderBody @throws AMQException + * @param messagePublishInfo + * @param contentHeaderBody @throws AMQException */ public void setPublishAndContentHeaderBody(StoreContext storeContext, MessagePublishInfo messagePublishInfo, ContentHeaderBody contentHeaderBody) @@ -425,26 +279,18 @@ public class TransientAMQMessage implements AMQMessage throw new NullPointerException("HeaderBody cannot be null"); } - if( messagePublishInfo == null) + if (messagePublishInfo == null) { throw new NullPointerException("PublishInfo cannot be null"); } - _messagePublishInfo = messagePublishInfo; - _contentHeaderBody = contentHeaderBody; - + _arrivalTime = System.currentTimeMillis(); - if( contentHeaderBody.bodySize == 0) - { - _contentBodies = Collections.EMPTY_LIST; - } - _arrivalTime = System.currentTimeMillis(); + _contentHeaderBody = contentHeaderBody; + _messagePublishInfo = messagePublishInfo; - if(messagePublishInfo.isImmediate()) - { - _flags |= IMMEDIATE; - } + updateHeaderAndFlags(); } public long getArrivalTime() @@ -452,9 +298,26 @@ public class TransientAMQMessage implements AMQMessage return _arrivalTime; } - public void removeMessage(StoreContext storeContext) throws AMQException + public void recoverFromMessageMetaData(MessageMetaData mmd) + { + _arrivalTime = mmd.getArrivalTime(); + _contentHeaderBody = mmd.getContentHeaderBody(); + _messagePublishInfo = mmd.getMessagePublishInfo(); + + updateHeaderAndFlags(); + } + + private void updateHeaderAndFlags() + { + if (_contentHeaderBody.bodySize == 0) + { + _contentBodies = Collections.EMPTY_LIST; + } + } + + public void recoverContentBodyFrame(ContentChunk contentChunk, boolean isLastContentBody) throws AMQException { - //no-op + addContentBodyFrame(null, contentChunk, isLastContentBody); } @@ -463,7 +326,7 @@ public class TransientAMQMessage implements AMQMessage // return "Message[" + debugIdentity() + "]: " + _messageId + "; ref count: " + _referenceCount + "; taken : " + // _taken + " by :" + _takenBySubcription; - return "Message[" + debugIdentity() + "]: " + getMessageId() + "; ref count: " + _referenceCount; + return "Message[" + debugIdentity() + "]: " + getMessageId() ; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java new file mode 100644 index 0000000000..03cfed8533 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java @@ -0,0 +1,29 @@ +/* + * + * 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; + +public class UnableToFlowMessageException extends Exception +{ + public UnableToFlowMessageException(long messageId, Exception error) + { + super("Unable to Flow Message:"+messageId, error); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java new file mode 100644 index 0000000000..cae5bc6327 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java @@ -0,0 +1,29 @@ +/* + * + * 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; + +public class UnableToRecoverMessageException extends RuntimeException +{ + public UnableToRecoverMessageException(Exception error) + { + super(error); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java index 02124a3737..22b4623ae1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java @@ -20,24 +20,21 @@ */ package org.apache.qpid.server.registry; -import org.apache.commons.configuration.Configuration; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.Configurator; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; +import org.apache.mina.common.IoAcceptor; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.management.ManagedObjectRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager; -import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager; -import org.apache.qpid.server.security.access.ACLPlugin; -import org.apache.qpid.server.security.access.ACLManager; import org.apache.qpid.server.plugins.PluginManager; -import org.apache.mina.common.IoAcceptor; - -import java.util.HashMap; -import java.util.Map; -import java.net.InetSocketAddress; +import org.apache.qpid.server.security.access.ACLManager; +import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; /** * An abstract application registry that provides access to configuration information and handles the @@ -53,7 +50,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry private final Map<Class<?>, Object> _configuredObjects = new HashMap<Class<?>, Object>(); - protected final Configuration _configuration; + protected final ServerConfiguration _configuration; public static final int DEFAULT_INSTANCE = 1; public static final String DEFAULT_APPLICATION_REGISTRY = "org.apache.qpid.server.util.NullApplicationRegistry"; @@ -154,7 +151,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } } - protected ApplicationRegistry(Configuration configuration) + protected ApplicationRegistry(ServerConfiguration configuration) { _configuration = configuration; } @@ -242,7 +239,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } } - public Configuration getConfiguration() + public ServerConfiguration getConfiguration() { return _configuration; } @@ -255,26 +252,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } } - public <T> T getConfiguredObject(Class<T> instanceType) - { - T instance = (T) _configuredObjects.get(instanceType); - if (instance == null) - { - try - { - instance = instanceType.newInstance(); - } - catch (Exception e) - { - _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor"); - throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e); - } - Configurator.configure(instance); - _configuredObjects.put(instanceType, instance); - } - return instance; - } - public static void setDefaultApplicationRegistry(String clazz) { _APPLICATION_REGISTRY = clazz; @@ -285,9 +262,9 @@ public abstract class ApplicationRegistry implements IApplicationRegistry return _virtualHostRegistry; } - public ACLManager getAccessManager() + public ACLManager getAccessManager() throws ConfigurationException { - return new ACLManager(_configuration, _pluginManager); + return new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager); } public ManagedObjectRegistry getManagedObjectRegistry() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java index c34c4bf80a..39164883f9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java @@ -21,71 +21,25 @@ package org.apache.qpid.server.registry; import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.SystemConfiguration; -import org.apache.commons.configuration.XMLConfiguration; +import org.apache.qpid.AMQException; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.management.JMXManagedObjectRegistry; -import org.apache.qpid.server.management.ManagedObjectRegistry; -import org.apache.qpid.server.management.ManagementConfiguration; import org.apache.qpid.server.management.NoopManagedObjectRegistry; import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.access.ACLManager; import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager; -import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager; import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.access.ACLPlugin; -import org.apache.qpid.server.security.access.ACLManager; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -import org.apache.qpid.AMQException; public class ConfigurationFileApplicationRegistry extends ApplicationRegistry { public ConfigurationFileApplicationRegistry(File configurationURL) throws ConfigurationException { - super(config(configurationURL)); - } - - // Our configuration class needs to make the interpolate method - // public so it can be called below from the config method. - private static class MyConfiguration extends CompositeConfiguration - { - public String interpolate(String obj) - { - return super.interpolate(obj); - } - } - - private static final Configuration config(File url) throws ConfigurationException - { - // We have to override the interpolate methods so that - // interpolation takes place accross the entirety of the - // composite configuration. Without doing this each - // configuration object only interpolates variables defined - // inside itself. - final MyConfiguration conf = new MyConfiguration(); - conf.addConfiguration(new SystemConfiguration() - { - protected String interpolate(String o) - { - return conf.interpolate(o); - } - }); - conf.addConfiguration(new XMLConfiguration(url) - { - protected String interpolate(String o) - { - return conf.interpolate(o); - } - }); - return conf; + super(new ServerConfiguration(configurationURL)); } public void initialise() throws Exception @@ -94,9 +48,9 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry _virtualHostRegistry = new VirtualHostRegistry(); - _pluginManager = new PluginManager(_configuration.getString("plugin-directory")); + _pluginManager = new PluginManager(_configuration.getPluginDirectory()); - _accessManager = new ACLManager(_configuration, _pluginManager); + _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager); _databaseManager = new ConfigurationFilePrincipalDatabaseManager(_configuration); @@ -111,18 +65,17 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry } private void initialiseVirtualHosts() throws Exception - { - for (String name : getVirtualHostNames()) + { + for (String name : _configuration.getVirtualHosts()) { - - _virtualHostRegistry.registerVirtualHost(new VirtualHost(name, getConfiguration().subset("virtualhosts.virtualhost." + name))); + _virtualHostRegistry.registerVirtualHost(new VirtualHost(_configuration.getVirtualHostConfig(name))); } + getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost()); } private void initialiseManagedObjectRegistry() throws AMQException { - ManagementConfiguration config = getConfiguredObject(ManagementConfiguration.class); - if (config.enabled) + if (_configuration.getManagementEnabled()) { _managedObjectRegistry = new JMXManagedObjectRegistry(); } @@ -131,10 +84,4 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry _managedObjectRegistry = new NoopManagedObjectRegistry(); } } - - public Collection<String> getVirtualHostNames() - { - return getConfiguration().getList("virtualhosts.virtualhost.name"); - } - } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java index e68dca285c..bbfda3addc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java @@ -24,6 +24,8 @@ import java.util.Collection; import java.net.InetSocketAddress; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.management.ManagedObjectRegistry; import org.apache.qpid.server.plugins.PluginManager; import org.apache.qpid.server.security.auth.manager.AuthenticationManager; @@ -49,21 +51,11 @@ public interface IApplicationRegistry void close() throws Exception; /** - * This gets access to a "configured object". A configured object has fields populated from a the configuration - * object (Commons Configuration) automatically, where it has the appropriate attributes defined on fields. - * Application registry implementations can choose the refresh strategy or caching approach. - * @param instanceType the type of object you want initialised. This must be unique - i.e. you can only - * have a single object of this type in the system. - * @return the configured object - */ - <T> T getConfiguredObject(Class<T> instanceType); - - /** * Get the low level configuration. For use cases where the configured object approach is not required * you can get the complete configuration information. * @return a Commons Configuration instance */ - Configuration getConfiguration(); + ServerConfiguration getConfiguration(); ManagedObjectRegistry getManagedObjectRegistry(); @@ -71,11 +63,9 @@ public interface IApplicationRegistry AuthenticationManager getAuthenticationManager(); - Collection<String> getVirtualHostNames(); - VirtualHostRegistry getVirtualHostRegistry(); - ACLManager getAccessManager(); + ACLManager getAccessManager() throws ConfigurationException; PluginManager getPluginManager(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java index 6344127b24..0c62638710 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.routing; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -41,7 +42,7 @@ public interface RoutingTable * * @throws Exception If any error occurs that means the store is unable to configure itself. */ - void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception; + void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception; /** * Called to close and cleanup any resources used by the message store. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java index 356ee815dd..6f7f66fad2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java @@ -28,8 +28,12 @@ import java.util.Map; import java.util.Map.Entry; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.SecurityConfiguration; +import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.plugins.PluginManager; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -46,12 +50,12 @@ public class ACLManager private Map<String, ACLPlugin> _globalPlugins = new HashMap<String, ACLPlugin>(); private Map<String, ACLPlugin> _hostPlugins = new HashMap<String, ACLPlugin>(); - public ACLManager(Configuration configuration, PluginManager manager) + public ACLManager(SecurityConfiguration configuration, PluginManager manager) throws ConfigurationException { this(configuration, manager, null); } - public ACLManager(Configuration configuration, PluginManager manager, ACLPluginFactory securityPlugin) + public ACLManager(SecurityConfiguration configuration, PluginManager manager, ACLPluginFactory securityPlugin) throws ConfigurationException { _pluginManager = manager; @@ -70,14 +74,14 @@ public class ACLManager } - public void configureHostPlugins(Configuration hostConfig) + public void configureHostPlugins(SecurityConfiguration hostConfig) throws ConfigurationException { _hostPlugins = configurePlugins(hostConfig); } - public Map<String, ACLPlugin> configurePlugins(Configuration configuration) + public Map<String, ACLPlugin> configurePlugins(SecurityConfiguration hostConfig) throws ConfigurationException { - Configuration securityConfig = configuration.subset("security"); + Configuration securityConfig = hostConfig.getConfiguration(); Map<String, ACLPlugin> plugins = new HashMap<String, ACLPlugin>(); Iterator keys = securityConfig.getKeys(); Collection<String> handledTags = new HashSet(); @@ -86,7 +90,6 @@ public class ACLManager // Splitting the string is necessary here because of the way that getKeys() returns only // bottom level children String tag = ((String) keys.next()).split("\\.", 2)[0]; - if (!handledTags.contains(tag)) { for (ACLPluginFactory plugin : _allSecurityPlugins.values()) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java index ca760f3360..032184ec39 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.security.access; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -36,7 +37,7 @@ public interface ACLPlugin ABSTAIN } - void setConfiguration(Configuration config); + void setConfiguration(Configuration config) throws ConfigurationException; // These return true if the plugin thinks the action should be allowed, and false if not. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java index aee6af93d0..256f093477 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java @@ -21,12 +21,13 @@ package org.apache.qpid.server.security.access; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; public interface ACLPluginFactory { public boolean supportsTag(String name); - public ACLPlugin newInstance(Configuration config); + public ACLPlugin newInstance(Configuration config) throws ConfigurationException; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java index f04aecd0a5..121f571abe 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java @@ -64,9 +64,9 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class); private PrincipalDatabase _principalDatabase; - private String _accessFileName; private Properties _accessRights; - // private File _accessFile; + private File _accessFile; + private ReentrantLock _accessRightsUpdate = new ReentrantLock(); // Setup for the TabularType @@ -104,7 +104,7 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana public AMQUserManagementMBean() throws JMException { - super(UserManagement.class, UserManagement.TYPE); + super(UserManagement.class, UserManagement.TYPE, UserManagement.VERSION); } public String getObjectInstanceName() @@ -129,9 +129,10 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana public boolean setRights(String username, boolean read, boolean write, boolean admin) { - if (_accessRights.get(username) == null) + Object oldRights = null; + if ((oldRights =_accessRights.get(username)) == null) { - // If the user doesn't exist in the user rights file check that they at least have an account. + // If the user doesn't exist in the access rights file check that they at least have an account. if (_principalDatabase.getUser(username) == null) { return false; @@ -140,7 +141,6 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana try { - _accessRightsUpdate.lock(); // Update the access rights @@ -166,8 +166,29 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana _accessRights.remove(username); } } + + //save the rights file + try + { + saveAccessFile(); + } + catch (IOException e) + { + _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e); - saveAccessFile(); + //the rights file was not successfully saved, restore user rights to previous value + _logger.warn("Reverting attempted rights update for user'" + username + "'"); + if (oldRights != null) + { + _accessRights.put(username, oldRights); + } + else + { + _accessRights.remove(username); + } + + return false; + } } finally { @@ -184,9 +205,23 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana { if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password)) { - _accessRights.put(username, ""); - - return setRights(username, read, write, admin); + if (!setRights(username, read, write, admin)) + { + //unable to set rights for user, remove account + try + { + _principalDatabase.deletePrincipal(new UsernamePrincipal(username)); + } + catch (AccountNotFoundException e) + { + //ignore + } + return false; + } + else + { + return true; + } } return false; @@ -194,7 +229,6 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana public boolean deleteUser(String username) { - try { if (_principalDatabase.deletePrincipal(new UsernamePrincipal(username))) @@ -204,7 +238,16 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana _accessRightsUpdate.lock(); _accessRights.remove(username); - saveAccessFile(); + + try + { + saveAccessFile(); + } + catch (IOException e) + { + _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e); + return false; + } } finally { @@ -213,15 +256,15 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana _accessRightsUpdate.unlock(); } } - return true; } } catch (AccountNotFoundException e) { _logger.warn("Attempt to delete user (" + username + ") that doesn't exist"); + return false; } - return false; + return true; } public boolean reloadData() @@ -233,12 +276,12 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana } catch (ConfigurationException e) { - _logger.info("Reload failed due to:" + e); + _logger.warn("Reload failed due to:" + e); return false; } catch (IOException e) { - _logger.info("Reload failed due to:" + e); + _logger.warn("Reload failed due to:" + e); return false; } // Reload successful @@ -320,10 +363,24 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana */ public void setAccessFile(String accessFile) throws IOException, ConfigurationException { - _accessFileName = accessFile; - - if (_accessFileName != null) + if (accessFile != null) { + _accessFile = new File(accessFile); + if (!_accessFile.exists()) + { + throw new ConfigurationException("'" + _accessFile + "' does not exist"); + } + + if (!_accessFile.canRead()) + { + throw new ConfigurationException("Cannot read '" + _accessFile + "'."); + } + + if (!_accessFile.canWrite()) + { + _logger.warn("Unable to write to access rights file '" + _accessFile + "', changes will not be preserved."); + } + loadAccessFile(); } else @@ -334,39 +391,34 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana private void loadAccessFile() throws IOException, ConfigurationException { - try + if(_accessFile == null) { - _accessRightsUpdate.lock(); - - Properties accessRights = new Properties(); - - File accessFile = new File(_accessFileName); - - if (!accessFile.exists()) + _logger.error("No jmx access rights file has been specified."); + return; + } + + if(_accessFile.exists()) + { + try { - throw new ConfigurationException("'" + _accessFileName + "' does not exist"); - } + _accessRightsUpdate.lock(); - if (!accessFile.canRead()) - { - throw new ConfigurationException("Cannot read '" + _accessFileName + "'."); + Properties accessRights = new Properties(); + accessRights.load(new FileInputStream(_accessFile)); + checkAccessRights(accessRights); + setAccessRights(accessRights); } - - if (!accessFile.canWrite()) + finally { - _logger.warn("Unable to write to access file '" + _accessFileName + "' changes will not be preserved."); + if (_accessRightsUpdate.isHeldByCurrentThread()) + { + _accessRightsUpdate.unlock(); + } } - - accessRights.load(new FileInputStream(accessFile)); - checkAccessRights(accessRights); - setAccessRights(accessRights); } - finally + else { - if (_accessRightsUpdate.isHeldByCurrentThread()) - { - _accessRightsUpdate.unlock(); - } + _logger.error("Specified jmxaccess rights file '" + _accessFile + "' does not exist."); } } @@ -385,33 +437,24 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana } } - private void saveAccessFile() + private void saveAccessFile() throws IOException { try { _accessRightsUpdate.lock(); - try - { - // Create temporary file - File tmp = File.createTempFile(_accessFileName, ".tmp"); - // Rename current file - File rights = new File(_accessFileName); + // Create temporary file + File tmp = File.createTempFile(_accessFile.getName(), ".tmp"); - FileOutputStream output = new FileOutputStream(tmp); - _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser()); - output.close(); + FileOutputStream output = new FileOutputStream(tmp); + _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser()); + output.close(); - // Rename new file to main file - tmp.renameTo(rights); + // Rename new file to main file + tmp.renameTo(_accessFile); - // delete tmp - tmp.delete(); - } - catch (IOException e) - { - _logger.warn("Problem occured saving '" + _accessFileName + "' changes may not be preserved. :" + e); - } + // delete tmp + tmp.delete(); } finally { @@ -420,6 +463,7 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana _accessRightsUpdate.unlock(); } } + } private String getCurrentJMXUser() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java index 658d7ebbd3..9fcdd4cd17 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java @@ -33,7 +33,9 @@ import java.io.IOException; public interface UserManagement { + String TYPE = "UserManagement"; + int VERSION = 2; //********** Operations *****************// /** @@ -115,4 +117,5 @@ public interface UserManagement impact = MBeanOperationInfo.INFO) TabularData viewUsers(); + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java new file mode 100644 index 0000000000..fc1bc048d4 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java @@ -0,0 +1,71 @@ +/* + * 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.access.plugins; + +import java.util.Collection; +import java.util.HashSet; + +import org.apache.commons.configuration.Configuration; +import org.apache.qpid.server.security.access.ACLPlugin; +import org.apache.qpid.server.security.access.ACLPluginFactory; + +/** + * + * Used to suppress warnings in legacy config files that have things in <security> which aren't handled by a plugin directly. + * + */ +public class LegacyAccessPlugin extends BasicACLPlugin +{ + public static final ACLPluginFactory FACTORY = new ACLPluginFactory() + { + private Collection maskedTags = new HashSet<String>(); + { + maskedTags.add("principal-databases"); + maskedTags.add("access"); + maskedTags.add("msg-auth"); + maskedTags.add("false"); + maskedTags.add("jmx"); + } + + public boolean supportsTag(String name) + { + return maskedTags .contains(name); + } + + public ACLPlugin newInstance(Configuration config) + { + return new LegacyAccessPlugin(); + } + }; + + public String getPluginName() + { + return getClass().getSimpleName(); + } + + @Override + protected AuthzResult getResult() + { + // Always abstain + return AuthzResult.ABSTAIN; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java index 7fcf4a0494..a1a399e5bf 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.security.access.plugins.network; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.server.security.access.ACLPlugin; import org.apache.qpid.server.security.access.ACLPluginFactory; @@ -28,7 +29,7 @@ public class FirewallFactory implements ACLPluginFactory { @Override - public ACLPlugin newInstance(Configuration config) + public ACLPlugin newInstance(Configuration config) throws ConfigurationException { FirewallPlugin plugin = new FirewallPlugin(); plugin.setConfiguration(config); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java index cb8b6f6fed..85026121ab 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java @@ -23,12 +23,19 @@ package org.apache.qpid.server.security.access.plugins.network; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Iterator; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; +import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.XMLConfiguration; import org.apache.qpid.server.protocol.AMQMinaProtocolSession; import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.security.access.ACLPlugin; +import org.apache.qpid.server.security.access.ACLPluginFactory; import org.apache.qpid.server.security.access.plugins.AbstractACLPlugin; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.util.NetMatcher; @@ -36,9 +43,27 @@ import org.apache.qpid.util.NetMatcher; public class FirewallPlugin extends AbstractACLPlugin { + public class FirewallPluginException extends Exception {} + + public static final ACLPluginFactory FACTORY = new ACLPluginFactory() + { + public boolean supportsTag(String name) + { + return name.startsWith("firewall"); + } + + public ACLPlugin newInstance(Configuration config) throws ConfigurationException + { + FirewallPlugin plugin = new FirewallPlugin(); + plugin.setConfiguration(config); + return plugin; + } + }; + public class FirewallRule { + private static final long DNS_TIMEOUT = 30000; private AuthzResult _access; private NetMatcher _network; private Pattern[] _hostnamePatterns; @@ -76,11 +101,15 @@ public class FirewallPlugin extends AbstractACLPlugin return networkStrings; } - public boolean match(InetAddress remote) + public boolean match(InetAddress remote) throws FirewallPluginException { if (_hostnamePatterns != null) { - String hostname = remote.getCanonicalHostName(); + String hostname = getHostname(remote); + if (hostname == null) + { + throw new FirewallPluginException(); + } for (Pattern pattern : _hostnamePatterns) { if (pattern.matcher(hostname).matches()) @@ -96,6 +125,48 @@ public class FirewallPlugin extends AbstractACLPlugin } } + /** + * @param remote the InetAddress to look up + * @return the hostname, null if not found or takes longer than 30s to find + */ + private String getHostname(final InetAddress remote) + { + final String[] hostname = new String[]{null}; + final AtomicBoolean done = new AtomicBoolean(false); + // Spawn thread + Thread thread = new Thread(new Runnable() + { + public void run() + { + hostname[0] = remote.getCanonicalHostName(); + done.getAndSet(true); + synchronized (done) + { + done.notifyAll(); + } + } + }); + + thread.run(); + long endTime = System.currentTimeMillis() + DNS_TIMEOUT; + + while (System.currentTimeMillis() < endTime && !done.get()) + { + try + { + synchronized (done) + { + done.wait(endTime - System.currentTimeMillis()); + } + } + catch (InterruptedException e) + { + // Check the time and if necessary sleep for a bit longer + } + } + return hostname[0]; + } + public AuthzResult getAccess() { return _access; @@ -125,7 +196,14 @@ public class FirewallPlugin extends AbstractACLPlugin boolean match = false; for (FirewallRule rule : _rules) { - match = rule.match(addr); + try + { + match = rule.match(addr); + } + catch (FirewallPluginException e) + { + return AuthzResult.DENIED; + } if (match) { return rule.getAccess(); @@ -149,7 +227,7 @@ public class FirewallPlugin extends AbstractACLPlugin } @Override - public void setConfiguration(Configuration config) + public void setConfiguration(Configuration config) throws ConfigurationException { // Get default action String defaultAction = config.getString("[@default-action]"); @@ -165,15 +243,21 @@ public class FirewallPlugin extends AbstractACLPlugin { _default = AuthzResult.DENIED; } + CompositeConfiguration finalConfig = new CompositeConfiguration(config); + + List subFiles = config.getList("firewall.xml[@fileName]"); + for (Object subFile : subFiles) + { + finalConfig.addConfiguration(new XMLConfiguration((String) subFile)); + } - int numRules = config.getList("rule[@access]").size(); // all rules must - // have an access - // attribute + // all rules must have an access attribute + int numRules = finalConfig.getList("rule[@access]").size(); _rules = new FirewallRule[numRules]; for (int i = 0; i < numRules; i++) { - FirewallRule rule = new FirewallRule(config.getString("rule(" + i + ")[@access]"), config.getList("rule(" - + i + ")[@network]"), config.getList("rule(" + i + ")[@hostname]")); + FirewallRule rule = new FirewallRule(finalConfig.getString("rule(" + i + ")[@access]"), finalConfig.getList("rule(" + + i + ")[@network]"), finalConfig.getList("rule(" + i + ")[@hostname]")); _rules[i] = rule; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java index 69ad9014db..3c211746e3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java @@ -152,8 +152,39 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException { char[] pwd = lookupPassword(principal); + + if (pwd == null) + { + throw new AccountNotFoundException("Unable to lookup the specfied users password"); + } + + byte[] byteArray = new byte[password.length]; + int index = 0; + for (char c : password) + { + byteArray[index++] = (byte) c; + } + + byte[] MD5byteArray; + try + { + MD5byteArray = HashedUser.getMD5(byteArray); + } + catch (Exception e1) + { + _logger.warn("Unable to hash password for user '" + principal + "' for comparison"); + return false; + } + + char[] hashedPassword = new char[MD5byteArray.length]; - return compareCharArray(pwd, password); + index = 0; + for (byte c : MD5byteArray) + { + hashedPassword[index++] = (char) c; + } + + return compareCharArray(pwd, hashedPassword); } private boolean compareCharArray(char[] a, char[] b) @@ -193,7 +224,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase { _userUpdate.lock(); char[] orig = user.getPassword(); - user.setPassword(password); + user.setPassword(password,false); try { @@ -204,7 +235,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase _logger.error("Unable to save password file, password change for user'" + principal + "' will revert at restart"); //revert the password change - user.setPassword(orig); + user.setPassword(orig,true); return false; } return true; @@ -230,7 +261,17 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase return false; } - HashedUser user = new HashedUser(principal.getName(), password); + HashedUser user; + try + { + user = new HashedUser(principal.getName(), password); + } + catch (Exception e1) + { + _logger.warn("Unable to create new user '" + principal.getName() + "'"); + return false; + } + try { 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 fc96776a3a..e0d4c49af1 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 @@ -34,6 +34,7 @@ import org.apache.log4j.Logger; import org.apache.qpid.configuration.PropertyUtils; import org.apache.qpid.configuration.PropertyException; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager; @@ -46,20 +47,18 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab { private static final Logger _logger = Logger.getLogger(ConfigurationFilePrincipalDatabaseManager.class); - private static final String _base = "security.principal-databases.principal-database"; - Map<String, PrincipalDatabase> _databases; - public ConfigurationFilePrincipalDatabaseManager(Configuration configuration) throws Exception + public ConfigurationFilePrincipalDatabaseManager(ServerConfiguration _configuration) throws Exception { _logger.info("Initialising PrincipleDatabase authentication manager"); - _databases = initialisePrincipalDatabases(configuration); + _databases = initialisePrincipalDatabases(_configuration); } - private Map<String, PrincipalDatabase> initialisePrincipalDatabases(Configuration configuration) throws Exception + private Map<String, PrincipalDatabase> initialisePrincipalDatabases(ServerConfiguration _configuration) throws Exception { - List<String> databaseNames = configuration.getList(_base + ".name"); - List<String> databaseClasses = configuration.getList(_base + ".class"); + List<String> databaseNames = _configuration.getPrincipalDatabaseNames(); + List<String> databaseClasses = _configuration.getPrincipalDatabaseClass(); Map<String, PrincipalDatabase> databases = new HashMap<String, PrincipalDatabase>(); if (databaseNames.size() == 0) @@ -84,7 +83,7 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab throw new Exception("Principal databases must implement the PrincipalDatabase interface"); } - initialisePrincipalDatabase((PrincipalDatabase) o, configuration, i); + initialisePrincipalDatabase((PrincipalDatabase) o, _configuration, i); String name = databaseNames.get(i); if ((name == null) || (name.length() == 0)) @@ -105,12 +104,11 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab return databases; } - private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, Configuration config, int index) + private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, ServerConfiguration _configuration, int index) throws FileNotFoundException, ConfigurationException { - String baseName = _base + "(" + index + ").attributes.attribute."; - List<String> argumentNames = config.getList(baseName + "name"); - List<String> argumentValues = config.getList(baseName + "value"); + List<String> argumentNames = _configuration.getPrincipalDatabaseAttributeNames(index); + List<String> argumentValues = _configuration.getPrincipalDatabaseAttributeValues(index); for (int i = 0; i < argumentNames.size(); i++) { String argName = argumentNames.get(i); @@ -166,18 +164,17 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab return _databases; } - public void initialiseManagement(Configuration config) throws ConfigurationException + public void initialiseManagement(ServerConfiguration config) throws ConfigurationException { try { AMQUserManagementMBean _mbean = new AMQUserManagementMBean(); - String baseSecurity = "security.jmx"; - List<String> principalDBs = config.getList(baseSecurity + ".principal-database"); + List<String> principalDBs = config.getManagementPrincipalDBs(); if (principalDBs.size() == 0) { - throw new ConfigurationException("No principal-database specified for jmx security(" + baseSecurity + ".principal-database)"); + throw new ConfigurationException("No principal-database specified for jmx security"); } String databaseName = principalDBs.get(0); @@ -191,11 +188,11 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab _mbean.setPrincipalDatabase(database); - List<String> jmxaccesslist = config.getList(baseSecurity + ".access"); + List<String> jmxaccesslist = config.getManagementAccessList(); if (jmxaccesslist.size() == 0) { - throw new ConfigurationException("No access control files specified for jmx security(" + baseSecurity + ".access)"); + throw new ConfigurationException("No access control files specified for jmx security"); } String jmxaccesssFile = null; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java index 4d92e3fb4c..3690e7f92a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java @@ -25,6 +25,7 @@ import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; @@ -63,10 +64,22 @@ public class HashedUser implements Principal } } - public HashedUser(String name, char[] password) + public HashedUser(String name, char[] password) throws UnsupportedEncodingException, NoSuchAlgorithmException { _name = name; - setPassword(password); + setPassword(password,false); + } + + public static byte[] getMD5(byte[] data) throws NoSuchAlgorithmException, UnsupportedEncodingException + { + MessageDigest md = MessageDigest.getInstance("MD5"); + + for (byte b : data) + { + md.update(b); + } + + return md.digest(); } public String getName() @@ -84,9 +97,31 @@ public class HashedUser implements Principal return _password; } - void setPassword(char[] password) + void setPassword(char[] password, boolean alreadyHashed) throws UnsupportedEncodingException, NoSuchAlgorithmException { - _password = password; + if(alreadyHashed){ + _password = password; + } + else + { + byte[] byteArray = new byte[password.length]; + int index = 0; + for (char c : password) + { + byteArray[index++] = (byte) c; + } + + byte[] MD5byteArray = getMD5(byteArray); + + _password = new char[MD5byteArray.length]; + + index = 0; + for (byte c : MD5byteArray) + { + _password[index++] = (char) c; + } + } + _modified = true; _encodedPassword = null; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java index 9da954d74f..5e4678a63b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java @@ -34,11 +34,13 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.io.PrintStream; import java.security.Principal; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; /** @@ -50,13 +52,18 @@ import java.util.regex.Pattern; */ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase { + public static final String DEFAULT_ENCODING = "utf-8"; + private static final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class); - protected File _passwordFile; + private File _passwordFile; - protected Pattern _regexp = Pattern.compile(":"); + private Pattern _regexp = Pattern.compile(":"); - protected Map<String, AuthenticationProviderInitialiser> _saslServers; + private Map<String, AuthenticationProviderInitialiser> _saslServers; + + private Map<String, PlainUser> _users = new HashMap<String, PlainUser>(); + private ReentrantLock _userUpdate = new ReentrantLock(); public PlainPasswordFilePrincipalDatabase() { @@ -83,7 +90,7 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase _saslServers.put(cram.getMechanismName(), cram); } - public void setPasswordFile(String passwordFile) throws FileNotFoundException + public void setPasswordFile(String passwordFile) throws IOException { File f = new File(passwordFile); _logger.info("PlainPasswordFile using file " + f.getAbsolutePath()); @@ -97,10 +104,20 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase throw new FileNotFoundException("Cannot read password file " + f + ". Check permissions."); } + + loadPasswordFile(); } - public void setPassword(Principal principal, PasswordCallback callback) throws IOException, - AccountNotFoundException + /** + * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile + * If you want to change the password for a user, use updatePassword instead. + * + * @param principal The Principal to set the password for + * @param callback The PasswordCallback to call setPassword on + * + * @throws AccountNotFoundException If the Principal cannot be found in this Database + */ + public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException { if (_passwordFile == null) { @@ -111,6 +128,7 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase throw new IllegalArgumentException("principal must not be null"); } char[] pwd = lookupPassword(principal.getName()); + if (pwd != null) { callback.setPassword(pwd); @@ -121,33 +139,151 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase } } + /** + * Used to verify that the presented Password is correct. Currently only used by Management Console + * + * @param principal The principal to authenticate + * @param password The plaintext password to check + * + * @return true if password is correct + * + * @throws AccountNotFoundException if the principal cannot be found + */ public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException { - try - { - char[] pwd = lookupPassword(principal); - return compareCharArray(pwd, password); - } - catch (IOException e) + char[] pwd = lookupPassword(principal); + + if (pwd == null) { - return false; + throw new AccountNotFoundException("Unable to lookup the specfied users password"); } + + return compareCharArray(pwd, password); + } + /** + * Changes the password for the specified user + * + * @param principal to change the password for + * @param password plaintext password to set the password too + */ public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException { - return false; // updates denied + PlainUser user = _users.get(principal.getName()); + + if (user == null) + { + throw new AccountNotFoundException(principal.getName()); + } + + try + { + try + { + _userUpdate.lock(); + char[] orig = user.getPassword(); + user.setPassword(password); + + try + { + savePasswordFile(); + } + catch (IOException e) + { + _logger.error("Unable to save password file, password change for user '" + principal + "' discarded"); + //revert the password change + user.setPassword(orig); + return false; + } + return true; + } + finally + { + if (_userUpdate.isHeldByCurrentThread()) + { + _userUpdate.unlock(); + } + } + } + catch (Exception e) + { + return false; + } } public boolean createPrincipal(Principal principal, char[] password) { - return false; // updates denied + if (_users.get(principal.getName()) != null) + { + return false; + } + + PlainUser user = new PlainUser(principal.getName(), password); + + try + { + _userUpdate.lock(); + _users.put(user.getName(), user); + + try + { + savePasswordFile(); + return true; + } + catch (IOException e) + { + //remove the use on failure. + _users.remove(user.getName()); + _logger.warn("Unable to create user '" + user.getName()); + return false; + } + } + finally + { + if (_userUpdate.isHeldByCurrentThread()) + { + _userUpdate.unlock(); + } + } } public boolean deletePrincipal(Principal principal) throws AccountNotFoundException { - return false; // updates denied + PlainUser user = _users.get(principal.getName()); + + if (user == null) + { + throw new AccountNotFoundException(principal.getName()); + } + + try + { + _userUpdate.lock(); + user.delete(); + + try + { + savePasswordFile(); + } + catch (IOException e) + { + _logger.error("Unable to remove user '" + user.getName() + "' from password file."); + return false; + } + + _users.remove(user.getName()); + } + finally + { + if (_userUpdate.isHeldByCurrentThread()) + { + _userUpdate.unlock(); + } + } + + return true; } public Map<String, AuthenticationProviderInitialiser> getMechanisms() @@ -157,21 +293,14 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase public List<Principal> getUsers() { - return new LinkedList<Principal>(); //todo + return new LinkedList<Principal>(_users.values()); } public Principal getUser(String username) { - try - { - if (lookupPassword(username) != null) - { - return new UsernamePrincipal(username); - } - } - catch (IOException e) + if (_users.containsKey(username)) { - //fall through to null return + return new UsernamePrincipal(username); } return null; } @@ -197,49 +326,166 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it * creates strings of passwords. It should be modified to create only char arrays which get nulled out. * - * @param name the name of the principal to lookup - * - * @return char[] of the password + * @param name The principal name to lookup * - * @throws java.io.IOException whilst accessing the file + * @return a char[] for use in SASL. */ - private char[] lookupPassword(String name) throws IOException + private char[] lookupPassword(String name) + { + PlainUser user = _users.get(name); + if (user == null) + { + return null; + } + else + { + return user.getPassword(); + } + } + + private void loadPasswordFile() throws IOException + { + try + { + _userUpdate.lock(); + _users.clear(); + + BufferedReader reader = null; + try + { + reader = new BufferedReader(new FileReader(_passwordFile)); + String line; + + while ((line = reader.readLine()) != null) + { + String[] result = _regexp.split(line); + if (result == null || result.length < 2 || result[0].startsWith("#")) + { + continue; + } + + PlainUser user = new PlainUser(result); + _logger.info("Created user:" + user); + _users.put(user.getName(), user); + } + } + finally + { + if (reader != null) + { + reader.close(); + } + } + } + finally + { + if (_userUpdate.isHeldByCurrentThread()) + { + _userUpdate.unlock(); + } + } + } + + private void savePasswordFile() throws IOException { - BufferedReader reader = null; try { - reader = new BufferedReader(new FileReader(_passwordFile)); - String line; + _userUpdate.lock(); + + BufferedReader reader = null; + PrintStream writer = null; + File tmp = File.createTempFile(_passwordFile.getName(), ".tmp"); - while ((line = reader.readLine()) != null) + try { - if (!line.startsWith("#")) + writer = new PrintStream(tmp); + reader = new BufferedReader(new FileReader(_passwordFile)); + String line; + + while ((line = reader.readLine()) != null) { String[] result = _regexp.split(line); - if (result == null || result.length < 2) + if (result == null || result.length < 2 || result[0].startsWith("#")) { + writer.write(line.getBytes(DEFAULT_ENCODING)); + writer.println(); continue; } - if (name.equals(result[0])) + PlainUser user = _users.get(result[0]); + + if (user == null) { - return result[1].toCharArray(); + writer.write(line.getBytes(DEFAULT_ENCODING)); + writer.println(); + } + else if (!user.isDeleted()) + { + if (!user.isModified()) + { + writer.write(line.getBytes(DEFAULT_ENCODING)); + writer.println(); + } + else + { + byte[] password = user.getPasswordBytes(); + + writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); + writer.write(password); + writer.println(); + + user.saved(); + } + } + } + + for (PlainUser user : _users.values()) + { + if (user.isModified()) + { + byte[] password; + password = user.getPasswordBytes(); + writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); + writer.write(password); + writer.println(); + user.saved(); } } } - return null; + finally + { + if (reader != null) + { + reader.close(); + } + + if (writer != null) + { + writer.close(); + } + + // Swap temp file to main password file. + File old = new File(_passwordFile.getAbsoluteFile() + ".old"); + if (old.exists()) + { + old.delete(); + } + _passwordFile.renameTo(old); + tmp.renameTo(_passwordFile); + tmp.delete(); + } } finally { - if (reader != null) + if (_userUpdate.isHeldByCurrentThread()) { - reader.close(); + _userUpdate.unlock(); } } } - + public void reload() throws IOException { - //This PD is not cached, so do nothing. + loadPasswordFile(); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java new file mode 100644 index 0000000000..46a78a55aa --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java @@ -0,0 +1,106 @@ +/* +* + * 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.database; + +import org.apache.log4j.Logger; + +import java.security.Principal; + +public class PlainUser implements Principal +{ + private String _name; + private char[] _password; + private boolean _modified = false; + private boolean _deleted = false; + + PlainUser(String[] data) + { + if (data.length != 2) + { + throw new IllegalArgumentException("User Data should be length 2, username, password"); + } + + _name = data[0]; + + _password = data[1].toCharArray(); + + } + + public PlainUser(String name, char[] password) + { + _name = name; + _password = password; + _modified = true; + } + + public String getName() + { + return _name; + } + + public String toString() + { + return _name; + } + + char[] getPassword() + { + return _password; + } + + byte[] getPasswordBytes() + { + byte[] byteArray = new byte[_password.length]; + int index = 0; + for (char c : _password) + { + byteArray[index++] = (byte) c; + } + return byteArray; + } + + void setPassword(char[] password) + { + _password = password; + _modified = true; + } + + public boolean isModified() + { + return _modified; + } + + public boolean isDeleted() + { + return _deleted; + } + + public void delete() + { + _deleted = true; + } + + public void saved() + { + _modified = false; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java index 2c553ae76a..f9882f8810 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.security.auth.database; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; @@ -30,5 +31,5 @@ public interface PrincipalDatabaseManager { public Map<String, PrincipalDatabase> getDatabases(); - public void initialiseManagement(Configuration config) throws ConfigurationException; + public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java index 6b86a46bd2..4efe381a8b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java @@ -20,7 +20,8 @@ */ package org.apache.qpid.server.security.auth.database; -import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.configuration.ServerConfiguration; import java.util.Map; import java.util.Properties; @@ -41,7 +42,8 @@ public class PropertiesPrincipalDatabaseManager implements PrincipalDatabaseMana return _databases; } - public void initialiseManagement(Configuration config) + @Override + public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException { //todo } 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 2cbbdc85ff..98c060599a 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,6 +23,7 @@ package org.apache.qpid.server.security.auth.manager; import org.apache.log4j.Logger; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; @@ -60,7 +61,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan /** The name for the required SASL Server mechanisms */ public static final String PROVIDER_NAME= "AMQSASLProvider-Server"; - public PrincipalDatabaseAuthenticationManager(String name, Configuration hostConfig) throws Exception + public PrincipalDatabaseAuthenticationManager(String name, VirtualHostConfiguration hostConfig) throws Exception { _logger.info("Initialising " + (name == null ? "Default" : "'" + name + "'") + " PrincipleDatabase authentication manager."); @@ -77,7 +78,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan } else { - String databaseName = hostConfig.getString("security.authentication.name"); + String databaseName = hostConfig.getAuthenticationDatabase(); if (databaseName == null) { @@ -121,14 +122,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, Map<String, PrincipalDatabase> databases) throws Exception { -// Configuration config = ApplicationRegistry.getInstance().getConfiguration(); -// List<String> mechanisms = config.getList("security.sasl.mechanisms.mechanism.initialiser.class"); -// -// // Maps from the mechanism to the properties used to initialise the server. See the method -// // Sasl.createSaslServer for details of the use of these properties. This map is populated during initialisation -// // of each provider. - - if (databases.size() > 1) { _logger.warn("More than one principle database provided currently authentication mechanism will override each other."); @@ -136,13 +129,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan for (Map.Entry<String, PrincipalDatabase> entry : databases.entrySet()) { - // fixme As the database now provide the mechanisms they support, they will ... // overwrite each other in the map. There should only be one database per vhost. // But currently we must have authentication before vhost definition. initialiseAuthenticationMechanisms(providerMap, entry.getValue()); } - } private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database) throws Exception 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 378b17e733..77040e896c 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,23 +20,14 @@ */ package org.apache.qpid.server.security.auth.rmi; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; import java.util.Collections; import javax.management.remote.JMXAuthenticator; import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; -import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; -import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; -import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; public class RMIPasswordAuthenticator implements JMXAuthenticator { @@ -48,7 +39,6 @@ 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."; - public static final String DEFAULT_ENCODING = "utf-8"; private PrincipalDatabase _db = null; public RMIPasswordAuthenticator() @@ -91,56 +81,26 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator throw new SecurityException(SHOULD_BE_NON_NULL); } + // Verify that a PD has been set. + if (_db == null) + { + throw new SecurityException(UNABLE_TO_LOOKUP); + } + boolean authenticated = false; // Perform authentication try { - PasswordCallback pwCallback = new PasswordCallback("prompt",false); - UsernamePrincipal uname = new UsernamePrincipal(username); - - if (_db instanceof Base64MD5PasswordFilePrincipalDatabase) - { - //retrieve the stored password for the given user - _db.setPassword(uname, pwCallback); - - //compare the MD5Hash of the given password with the stored value - if (Arrays.equals(getMD5Hash(password), pwCallback.getPassword())) - { - authenticated = true; - } - } - else if (_db instanceof PlainPasswordFilePrincipalDatabase) - { - //retrieve the users stored password and compare with given value - _db.setPassword(uname, pwCallback); - - if (password.equals(new String(pwCallback.getPassword()))) - { - authenticated = true; - } - } - else - { - throw new SecurityException(UNABLE_TO_LOOKUP); + if (_db.verifyPassword(username, password.toCharArray())) + { + authenticated = true; } } catch (AccountNotFoundException e) { throw new SecurityException(INVALID_CREDENTIALS); } - catch (UnsupportedEncodingException e) - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } - catch (NoSuchAlgorithmException e) - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } - catch (IOException e) - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } if (authenticated) { @@ -155,28 +115,5 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator throw new SecurityException(INVALID_CREDENTIALS); } } - - public static char[] getMD5Hash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException - { - byte[] data = text.getBytes(DEFAULT_ENCODING); - MessageDigest md = MessageDigest.getInstance("MD5"); - - for (byte b : data) - { - md.update(b); - } - - byte[] digest = md.digest(); - - char[] hash = new char[digest.length ]; - - int index = 0; - for (byte b : digest) - { - hash[index++] = (char) b; - } - - return hash; - } }
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java index 500fd4c7bf..33b3d8608e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.store; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; @@ -142,7 +143,7 @@ public class DerbyMessageStore implements TransactionLog, RoutingTable private State _state = State.INITIAL; - public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception + public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception { //Only initialise when loaded with the old 'store' confing ignore the new 'RoutingTable' config if (base.equals("store")) @@ -156,7 +157,7 @@ public class DerbyMessageStore implements TransactionLog, RoutingTable _logger.info("Configuring Derby message store for virtual host " + virtualHost.getName()); QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); - final String databasePath = config.getString(base + "." + ENVIRONMENT_PATH_PROPERTY, "derbyDB"); + final String databasePath = config.getStoreConfiguration().getString(base + "." + ENVIRONMENT_PATH_PROPERTY, "derbyDB"); File environmentPath = new File(databasePath); if (!environmentPath.exists()) @@ -1356,7 +1357,8 @@ public class DerbyMessageStore implements TransactionLog, RoutingTable if(message != null) { - message.incrementReference(); + //todo must enqueue message to build reference table +// message.incrementReference(1); } else { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java index eee7be7ef6..3754b41a3e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java @@ -27,26 +27,31 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.server.queue.MessageMetaData; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.transactionlog.TransactionLog; +import org.apache.qpid.server.queue.MessageMetaData; import org.apache.qpid.server.routing.RoutingTable; +import org.apache.qpid.server.transactionlog.TransactionLog; +import org.apache.qpid.server.virtualhost.VirtualHost; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -/** A simple message store that stores the messages in a threadsafe structure in memory. +/** + * A simple message store that stores the messages in a threadsafe structure in memory. * * NOTE: Now that we have removed the MessageStore interface and are using a TransactionLog * * This class really should have no storage unless we want to do inMemory Recovery. - * */ public class MemoryMessageStore implements TransactionLog, RoutingTable { @@ -62,6 +67,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable private final AtomicLong _messageId = new AtomicLong(1); private AtomicBoolean _closed = new AtomicBoolean(false); + protected final Map<Long, List<AMQQueue>> _messageEnqueueMap = new HashMap<Long, List<AMQQueue>>(); public void configure() { @@ -70,19 +76,19 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable _contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>(DEFAULT_HASHTABLE_CAPACITY); } - public void configure(String base, Configuration config) + public void configure(String base, VirtualHostConfiguration config) { //Only initialise when called with current 'store' configs i.e. don't reinit when used as a 'RoutingTable' if (base.equals("store")) { - int hashtableCapacity = config.getInt(base + "." + HASHTABLE_CAPACITY_CONFIG, DEFAULT_HASHTABLE_CAPACITY); + int hashtableCapacity = config.getStoreConfiguration().getInt(base + "." + HASHTABLE_CAPACITY_CONFIG, DEFAULT_HASHTABLE_CAPACITY); _log.info("Using capacity " + hashtableCapacity + " for hash tables"); _metaDataMap = new ConcurrentHashMap<Long, MessageMetaData>(hashtableCapacity); _contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>(hashtableCapacity); } } - public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception + public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception { configure(base, config); } @@ -102,7 +108,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable } } - public void removeMessage(StoreContext context, Long messageId) throws AMQException + private void removeMessage(StoreContext context, Long messageId) throws AMQException { checkNotClosed(); if (_log.isDebugEnabled()) @@ -111,6 +117,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable } _metaDataMap.remove(messageId); _contentBodyMap.remove(messageId); + _messageEnqueueMap.remove(messageId); } public void createExchange(Exchange exchange) throws AMQException @@ -133,7 +140,6 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable } - public void createQueue(AMQQueue queue) throws AMQException { // Not requred to do anything @@ -151,12 +157,39 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable public void enqueueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException { - // Not required to do anything + synchronized (_messageEnqueueMap) + { + List<AMQQueue> queues = _messageEnqueueMap.get(messageId); + if (queues == null) + { + queues = new LinkedList<AMQQueue>(); + _messageEnqueueMap.put(messageId, queues); + } + + queues.add(queue); + } } public void dequeueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException { - // Not required to do anything + synchronized (_messageEnqueueMap) + { + List<AMQQueue> queues = _messageEnqueueMap.get(messageId); + if (queues == null || !queues.contains(queue)) + { + throw new RuntimeException("Attempt to dequeue messageID:" + messageId + " from queue:" + queue.getName() + + " but it is not enqueued on that queue."); + } + else + { + queues.remove(queue); + if (queues.isEmpty()) + { + removeMessage(context,messageId); + } + } + } + } public void beginTran(StoreContext context) throws AMQException @@ -237,7 +270,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable } private void checkNotClosed() throws MessageStoreClosedException - { + { if (_closed.get()) { throw new MessageStoreClosedException(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java index be11eb7b84..bc1f56fee1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java @@ -144,7 +144,8 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage StoreContext storeContext = getChannel().getStoreContext(); try - { // if we do not need to wait for client acknowledgements + { + // if we do not need to wait for client acknowledgements // we can decrement the reference count immediately. // By doing this _before_ the send we ensure that it @@ -153,7 +154,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage // The send may of course still fail, in which case, as // the message is unacked, it will be lost. - entry.dequeue(storeContext); + entry.dequeueAndDelete(storeContext); synchronized (getChannel()) @@ -163,7 +164,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage sendToClient(entry, deliveryTag); } - entry.dispose(storeContext); } finally { @@ -316,7 +316,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage _autoClose = false; } - + _logger.info(debugIdentity()+" Created subscription:"); } @@ -387,6 +387,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage //todo - client id should be recoreded and this test removed but handled below if (_noLocal) { + //todo getPublisherClientInstance should be moved to QueueEntryImpl final Object publisherId = entry.getMessage().getPublisherClientInstance(); // We don't want local messages so check to see if message is one we sent @@ -407,6 +408,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage //todo - client id should be recoreded and this test removed but handled here + //todo getPublisherIdentifier should be moved to QueueEntryImpl if (localInstance != null && localInstance.equals(entry.getMessage().getPublisherIdentifier())) { return false; @@ -498,9 +500,9 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage } - public boolean wouldSuspend(QueueEntry msg) + public boolean wouldSuspend(QueueEntry queueEntry) { - return !_creditManager.useCreditForMessage(msg.getMessage());//_channel.wouldSuspend(msg.getMessage()); + return !_creditManager.useCreditForMessage(queueEntry); } public void getSendLock() @@ -594,6 +596,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage protected void sendToClient(final QueueEntry entry, final long deliveryTag) throws AMQException { + _logger.info("Sending Message(" + entry + ") DTag:" + deliveryTag + " to subscription:" + debugIdentity()); _deliveryMethod.deliverToClient(this,entry,deliveryTag); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java index c927bb3272..97a1ecb38c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java @@ -26,6 +26,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.MessageMetaData; import org.apache.qpid.server.queue.AMQQueue; @@ -67,7 +68,7 @@ public interface TransactionLog * * @throws Exception If any error occurs that means the store is unable to configure itself. */ - void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception; + void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception; /** * Called to close and cleanup any resources used by the message store. @@ -77,18 +78,6 @@ public interface TransactionLog void close() throws Exception; /** - * Removes the specified message from the store in the given transactional store context. - * - * @param storeContext The transactional context to remove the message in. - * @param messageId Identifies the message to remove. - * - * @throws AMQException If the operation fails for any reason. - */ - void removeMessage(StoreContext storeContext, Long messageId) throws AMQException; - - - - /** * Places a message onto a specified queue, in a given transactional context. * * @param context The transactional context for the operation. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java deleted file mode 100644 index b67bb98e28..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.transport; - -import org.apache.mina.common.IoAcceptor; -import org.apache.mina.util.NewThreadExecutor; -import org.apache.qpid.configuration.Configured; -import org.apache.log4j.Logger; - -public class ConnectorConfiguration -{ - private static final Logger _logger = Logger.getLogger(ConnectorConfiguration.class); - - public static final String DEFAULT_PORT = "5672"; - - public static final String SSL_PORT = "8672"; - - @Configured(path = "connector.processors", - defaultValue = "4") - public int processors; - - @Configured(path = "connector.port", - defaultValue = DEFAULT_PORT) - public int port; - - @Configured(path = "connector.bind", - defaultValue = "wildcard") - public String bindAddress; - - @Configured(path = "connector.socketReceiveBuffer", - defaultValue = "32767") - public int socketReceiveBufferSize; - - @Configured(path = "connector.socketWriteBuffer", - defaultValue = "32767") - public int socketWriteBuferSize; - - @Configured(path = "connector.tcpNoDelay", - defaultValue = "true") - public boolean tcpNoDelay; - - @Configured(path = "advanced.filterchain[@enableExecutorPool]", - defaultValue = "false") - public boolean enableExecutorPool; - - @Configured(path = "advanced.enablePooledAllocator", - defaultValue = "false") - public boolean enablePooledAllocator; - - @Configured(path = "advanced.enableDirectBuffers", - defaultValue = "false") - public boolean enableDirectBuffers; - - @Configured(path = "connector.ssl.enabled", - defaultValue = "false") - public boolean enableSSL; - - @Configured(path = "connector.ssl.sslOnly", - defaultValue = "true") - public boolean sslOnly; - - @Configured(path = "connector.ssl.port", - defaultValue = SSL_PORT) - public int sslPort; - - @Configured(path = "connector.ssl.keystorePath", - defaultValue = "none") - public String keystorePath; - - @Configured(path = "connector.ssl.keystorePassword", - defaultValue = "none") - public String keystorePassword; - - @Configured(path = "connector.ssl.certType", - defaultValue = "SunX509") - public String certType; - - @Configured(path = "connector.qpidnio", - defaultValue = "false") - public boolean _multiThreadNIO; - - @Configured(path = "advanced.useWriteBiasedPool", - defaultValue = "false") - public boolean useBiasedWrites; - - - public IoAcceptor createAcceptor() - { - if (_multiThreadNIO) - { - _logger.warn("Using Qpid Multithreaded IO Processing"); - return new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor(processors, new NewThreadExecutor()); - } - else - { - _logger.warn("Using Mina IO Processing"); - return new org.apache.mina.transport.socket.nio.SocketAcceptor(processors, new NewThreadExecutor()); - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java index 9bc2e98fe9..abfb60c5bf 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java @@ -92,20 +92,12 @@ public class LocalTransactionalContext implements TransactionalContext public void process() throws AMQException { - _message.incrementReference(); - try - { QueueEntry entry = _queue.enqueue(getStoreContext(),_message); if(entry.immediateAndNotDelivered()) { getReturnMessages().add(new NoConsumersException(_message)); } - } - finally - { - _message.decrementReference(getStoreContext()); - } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java index 145d7f8b13..2f27e1405a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java @@ -123,18 +123,18 @@ public class NonTransactionalContext implements TransactionalContext unacknowledgedMessageMap.size()); unacknowledgedMessageMap.visit(new UnacknowledgedMessageMap.Visitor() { - public boolean callback(final long deliveryTag, QueueEntry message) throws AMQException + public boolean callback(final long deliveryTag, QueueEntry queueEntry) throws AMQException { if (debug) { - _log.debug("Discarding message: " + message.getMessage().getMessageId()); + _log.debug("Discarding message: " + queueEntry.getMessageId()); } - if(message.getMessage().isPersistent()) + if(queueEntry.isPersistent()) { beginTranIfNecessary(); } - //Message has been ack so discard it. This will dequeue and decrement the reference. - message.discard(_storeContext); + //Message has been ack so dequeueAndDelete it. + queueEntry.dequeueAndDelete(_storeContext); return false; } @@ -157,10 +157,15 @@ public class NonTransactionalContext implements TransactionalContext } else { - QueueEntry msg; - msg = unacknowledgedMessageMap.get(deliveryTag); + QueueEntry queueEntry; + queueEntry = unacknowledgedMessageMap.get(deliveryTag); - if (msg == null) + if (debug) + { + _log.debug("Received non-multiple ack for messaging with delivery tag " + deliveryTag); + } + + if (queueEntry == null) { _log.info("Single ack on delivery tag " + deliveryTag + " not known for channel:" + _channel.getChannelId()); @@ -170,24 +175,21 @@ public class NonTransactionalContext implements TransactionalContext if (debug) { - _log.debug("Discarding message: " + msg.getMessage().getMessageId()); + _log.debug("Discarding message: " + queueEntry.getMessageId()); } - if(msg.getMessage().isPersistent()) + if(queueEntry.isPersistent()) { beginTranIfNecessary(); } - //Message has been ack so discard it. This will dequeue and decrement the reference. - msg.discard(_storeContext); + //Message has been ack so dequeueAndDelete it. + // If the message is persistent and this is the last QueueEntry that uses it then the data will be removed + // from the transaciton log + queueEntry.dequeueAndDelete(_storeContext); unacknowledgedMessageMap.remove(deliveryTag); - if (debug) - { - _log.debug("Received non-multiple ack for messaging with delivery tag " + deliveryTag + " msg id " + - msg.getMessage().getMessageId()); - } } if(_inTran) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java index 88ad87b9c1..eda2d3a94e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java @@ -26,7 +26,11 @@ import java.util.HashMap; import java.util.Properties; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.MapConfiguration; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.management.NoopManagedObjectRegistry; import org.apache.qpid.server.plugins.PluginManager; import org.apache.qpid.server.registry.ApplicationRegistry; @@ -39,17 +43,16 @@ import org.apache.qpid.server.virtualhost.VirtualHostRegistry; public class NullApplicationRegistry extends ApplicationRegistry { - public NullApplicationRegistry() + public NullApplicationRegistry() throws ConfigurationException { - super(new MapConfiguration(new HashMap())); + super(new ServerConfiguration(new PropertiesConfiguration())); } public void initialise() throws Exception { _logger.info("Initialising NullApplicationRegistry"); - _configuration.addProperty("store.class", "org.apache.qpid.server.store.MemoryMessageStore"); - _configuration.addProperty("housekeeping.expiredMessageCheckPeriod", "200"); + _configuration.setHousekeepingExpiredMessageCheckPeriod(200); Properties users = new Properties(); @@ -57,17 +60,18 @@ public class NullApplicationRegistry extends ApplicationRegistry _databaseManager = new PropertiesPrincipalDatabaseManager("default", users); - _accessManager = new ACLManager(_configuration, _pluginManager, AllowAll.FACTORY); + _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager, AllowAll.FACTORY); _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null); _managedObjectRegistry = new NoopManagedObjectRegistry(); _virtualHostRegistry = new VirtualHostRegistry(); - VirtualHost dummyHost = new VirtualHost("test", _configuration); + PropertiesConfiguration vhostProps = new PropertiesConfiguration(); + VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps); + VirtualHost dummyHost = new VirtualHost(hostConfig); _virtualHostRegistry.registerVirtualHost(dummyHost); _virtualHostRegistry.setDefaultVirtualHostName("test"); _pluginManager = new PluginManager(""); - _configuration.addProperty("heartbeat.delay", 10 * 60); // 10 minutes } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java index 85d804457e..f4c81fbbb8 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java @@ -31,6 +31,7 @@ import org.apache.qpid.server.management.MBeanAttribute; public interface ManagedVirtualHost
{
static final String TYPE = "VirtualHost";
+ static final int VERSION = 1;
/**
* Returns the name of the managed virtualHost.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index 1497b4adb8..8a8cbd23cf 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -20,41 +20,49 @@ */ package org.apache.qpid.server.virtualhost; -import java.util.Timer; -import java.util.TimerTask; - -import javax.management.NotCompliantMBeanException; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.AMQBrokerManagerMBean; -import org.apache.qpid.server.routing.RoutingTable; -import org.apache.qpid.server.transactionlog.TransactionLog; -import org.apache.qpid.server.configuration.Configurator; +import org.apache.qpid.server.configuration.ExchangeConfiguration; +import org.apache.qpid.server.configuration.QueueConfiguration; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.connection.ConnectionRegistry; import org.apache.qpid.server.connection.IConnectionRegistry; import org.apache.qpid.server.exchange.DefaultExchangeFactory; import org.apache.qpid.server.exchange.DefaultExchangeRegistry; +import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.DefaultQueueRegistry; +import org.apache.qpid.server.queue.FileQueueBackingStoreFactory; +import org.apache.qpid.server.queue.QueueBackingStoreFactory; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.routing.RoutingTable; import org.apache.qpid.server.security.access.ACLManager; import org.apache.qpid.server.security.access.Accessable; import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; +import org.apache.qpid.server.transactionlog.TransactionLog; + +import javax.management.NotCompliantMBeanException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; public class VirtualHost implements Accessable { private static final Logger _logger = Logger.getLogger(VirtualHost.class); - private final String _name; private ConnectionRegistry _connectionRegistry; @@ -78,9 +86,9 @@ public class VirtualHost implements Accessable private ACLManager _accessManager; private final Timer _houseKeepingTimer; - - private static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L; + private VirtualHostConfiguration _configuration; + private QueueBackingStoreFactory _queueBackingStoreFactory; public void setAccessableName(String name) { @@ -103,6 +111,16 @@ public class VirtualHost implements Accessable return _routingTable; } + public VirtualHostConfiguration getConfiguration() + { + return _configuration; + } + + public QueueBackingStoreFactory getQueueBackingStoreFactory() + { + return _queueBackingStoreFactory; + } + /** * Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any * implementaion of an Exchange MBean should extend this class. @@ -111,7 +129,7 @@ public class VirtualHost implements Accessable { public VirtualHostMBean() throws NotCompliantMBeanException { - super(ManagedVirtualHost.class, "VirtualHost"); + super(ManagedVirtualHost.class, ManagedVirtualHost.TYPE, ManagedVirtualHost.VERSION); } public String getObjectInstanceName() @@ -129,50 +147,58 @@ public class VirtualHost implements Accessable return VirtualHost.this; } - } // End of MBean class /** - * Used for testing only - * @param name - * @param transactionLog - * @throws Exception - */ - public VirtualHost(String name, TransactionLog transactionLog) throws Exception - { - this(name, new PropertiesConfiguration(), transactionLog); - } - - /** * Normal Constructor - * @param name + * * @param hostConfig + * * @throws Exception */ - public VirtualHost(String name, Configuration hostConfig) throws Exception + public VirtualHost(VirtualHostConfiguration hostConfig) throws Exception { - this(name, hostConfig, null); + this(hostConfig, null); } - public VirtualHost(String name, Configuration hostConfig, TransactionLog transactionLog) throws Exception + public VirtualHost(VirtualHostConfiguration hostConfig, TransactionLog transactionLog) throws Exception { - if (name == null || name.length() == 0) + _configuration = hostConfig; + _name = hostConfig.getName(); + + if (_name == null || _name.length() == 0) { - throw new IllegalArgumentException("Illegal name (" + name + ") for virtualhost."); + throw new IllegalArgumentException("Illegal name (" + _name + ") for virtualhost."); } - _name = name; - _virtualHostMBean = new VirtualHostMBean(); _connectionRegistry = new ConnectionRegistry(this); - _houseKeepingTimer = new Timer("Queue-housekeeping-"+name, true); + _houseKeepingTimer = new Timer("Queue-housekeeping-" + _name, true); + _queueRegistry = new DefaultQueueRegistry(this); + _exchangeFactory = new DefaultExchangeFactory(this); _exchangeFactory.initialise(hostConfig); + _exchangeRegistry = new DefaultExchangeRegistry(this); + _queueBackingStoreFactory = new FileQueueBackingStoreFactory(); + _queueBackingStoreFactory.configure(this, hostConfig); + + //Create a temporary RT to store the durable entries from the config file + // so we can replay them in to the real _RT after it has been loaded. + /// This should be removed after the _RT has been fully split from the the TL + + StartupRoutingTable configFileRT = new StartupRoutingTable(); + + _routingTable = configFileRT; + + // This needs to be after the RT has been defined as it creates the default durable exchanges. + _exchangeRegistry.initialise(); + initialiseModel(hostConfig); + if (transactionLog != null) { _transactionLog = transactionLog; @@ -183,41 +209,47 @@ public class VirtualHost implements Accessable } else { - if (hostConfig == null) - { - throw new IllegalAccessException("HostConfig and TransactionLog cannot be null"); - } initialiseTransactionLog(hostConfig); initialiseRoutingTable(hostConfig); } + //Now that the RT has been initialised loop through the persistent queues/exchanges created from the config + // file and write them in to the new routing Table. + for (StartupRoutingTable.CreateQueueTuple cqt : configFileRT.queue) + { + _routingTable.createQueue(cqt.queue, cqt.arguments); + } + for (Exchange exchange : configFileRT.exchange) + { + _routingTable.createExchange(exchange); + } - _exchangeRegistry.initialise(); + for (StartupRoutingTable.CreateBindingTuple cbt : configFileRT.bindings) + { + _routingTable.bindQueue(cbt.exchange, cbt.routingKey, cbt.queue, cbt.arguments); + } - _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig); + _authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, hostConfig); _accessManager = ApplicationRegistry.getInstance().getAccessManager(); - _accessManager.configureHostPlugins(hostConfig); - + _accessManager.configureHostPlugins(hostConfig.getSecurityConfiguration()); + _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean); _brokerMBean.register(); - initialiseHouseKeeping(hostConfig); + initialiseHouseKeeping(hostConfig.getHousekeepingExpiredMessageCheckPeriod()); } - private void initialiseHouseKeeping(final Configuration hostConfig) + private void initialiseHouseKeeping(long period) { - - long period = hostConfig.getLong("housekeeping.expiredMessageCheckPeriod", DEFAULT_HOUSEKEEPING_PERIOD); - /* add a timer task to iterate over queues, cleaning expired messages from queues with no consumers */ - if(period != 0L) + if (period != 0L) { class RemoveExpiredMessagesTask extends TimerTask { public void run() { - for(AMQQueue q : _queueRegistry.getQueues()) + for (AMQQueue q : _queueRegistry.getQueues()) { try @@ -226,7 +258,7 @@ public class VirtualHost implements Accessable } catch (AMQException e) { - _logger.error("Exception in housekeeping for queue: " + q.getName().toString(),e); + _logger.error("Exception in housekeeping for queue: " + q.getName().toString(), e); throw new RuntimeException(e); } } @@ -234,15 +266,15 @@ public class VirtualHost implements Accessable } _houseKeepingTimer.scheduleAtFixedRate(new RemoveExpiredMessagesTask(), - period/2, - period); + period / 2, + period); } } //todo we need to move from store.class to transactionlog.class - private void initialiseTransactionLog(Configuration config) throws Exception + private void initialiseTransactionLog(VirtualHostConfiguration config) throws Exception { - String transactionLogClass = config.getString("store.class"); + String transactionLogClass = config.getTransactionLogClass(); Class clazz = Class.forName(transactionLogClass); Object o = clazz.newInstance(); @@ -253,13 +285,20 @@ public class VirtualHost implements Accessable " does not."); } _transactionLog = (TransactionLog) o; + + //Assign RoutingTable as old MessageStores converted to TransactionLog will require the _routingTable. + if (_transactionLog instanceof RoutingTable) + { + _routingTable = (RoutingTable) _transactionLog; + } + _transactionLog.configure(this, "store", config); } //todo we need to move from store.class to transactionlog.class - private void initialiseRoutingTable(Configuration config) throws Exception + private void initialiseRoutingTable(VirtualHostConfiguration hostConfig) throws Exception { - String transactionLogClass = config.getString("routingtable.class"); + String transactionLogClass = hostConfig.getRoutingTableClass(); if (transactionLogClass != null) { @@ -272,34 +311,99 @@ public class VirtualHost implements Accessable " does not."); } _routingTable = (RoutingTable) o; - _routingTable.configure(this, "routingtable", config); + _routingTable.configure(this, "routingtable", hostConfig); } else { - if (_transactionLog instanceof RoutingTable) + if (_routingTable == null) { - _routingTable = (RoutingTable)_transactionLog; + throw new RuntimeException("No Routing Table configured unable to startup."); } } } + private void initialiseModel(VirtualHostConfiguration config) throws ConfigurationException, AMQException + { + _logger.debug("Loading configuration for virtualhost: " + config.getName()); + + List exchangeNames = config.getExchanges(); + for (Object exchangeNameObj : exchangeNames) + { + String exchangeName = String.valueOf(exchangeNameObj); + configureExchange(config.getExchangeConfiguration(exchangeName)); + } - public <T> T getConfiguredObject(Class<T> instanceType, Configuration config) + String[] queueNames = config.getQueueNames(); + + for (Object queueNameObj : queueNames) + { + String queueName = String.valueOf(queueNameObj); + configureQueue(config.getQueueConfiguration(queueName)); + } + } + + private void configureExchange(ExchangeConfiguration exchangeConfiguration) throws AMQException + { + AMQShortString exchangeName = new AMQShortString(exchangeConfiguration.getName()); + + Exchange exchange; + exchange = _exchangeRegistry.getExchange(exchangeName); + if (exchange == null) + { + + AMQShortString type = new AMQShortString(exchangeConfiguration.getType()); + boolean durable = exchangeConfiguration.getDurable(); + boolean autodelete = exchangeConfiguration.getAutoDelete(); + + Exchange newExchange = _exchangeFactory.createExchange(exchangeName, type, durable, autodelete, 0); + _exchangeRegistry.registerExchange(newExchange); + } + } + + private void configureQueue(QueueConfiguration queueConfiguration) throws AMQException, ConfigurationException { - T instance; - try + AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueConfiguration, this); + + if (queue.isDurable()) + { + _routingTable.createQueue(queue); + } + + String exchangeName = queueConfiguration.getExchange(); + + Exchange exchange = _exchangeRegistry.getExchange(exchangeName == null ? null : new AMQShortString(exchangeName)); + + if (exchange == null) + { + exchange = _exchangeRegistry.getDefaultExchange(); + } + + if (exchange == null) + { + throw new ConfigurationException("Attempt to bind queue to unknown exchange:" + exchangeName); + } + + List routingKeys = queueConfiguration.getRoutingKeys(); + if (routingKeys == null || routingKeys.isEmpty()) { - instance = instanceType.newInstance(); + routingKeys = Collections.singletonList(queue.getName()); } - catch (Exception e) + + for (Object routingKeyNameObj : routingKeys) { - _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor"); - throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e); + AMQShortString routingKey = new AMQShortString(String.valueOf(routingKeyNameObj)); + if (_logger.isInfoEnabled()) + { + _logger.info("Binding queue:" + queue + " with routing key '" + routingKey + "' to exchange:" + this); + } + queue.bind(exchange, routingKey, null); } - Configurator.configure(instance); - return instance; + if (exchange != _exchangeRegistry.getDefaultExchange()) + { + queue.bind(_exchangeRegistry.getDefaultExchange(), queue.getName(), null); + } } public String getName() @@ -340,7 +444,7 @@ public class VirtualHost implements Accessable public ACLManager getAccessManager() { return _accessManager; - } + } public void close() throws Exception { @@ -348,6 +452,12 @@ public class VirtualHost implements Accessable //Stop Connections _connectionRegistry.close(); + //Stop Housekeeping + if (_houseKeepingTimer != null) + { + _houseKeepingTimer.cancel(); + } + //Stop the Queues processing if (_queueRegistry != null) { @@ -355,13 +465,7 @@ public class VirtualHost implements Accessable { queue.stop(); } - } - - //Stop Housekeeping - if (_houseKeepingTimer != null) - { - _houseKeepingTimer.cancel(); - } + } //Close TransactionLog if (_transactionLog != null) @@ -379,4 +483,95 @@ public class VirtualHost implements Accessable { return _virtualHostMBean; } + + /** + * Temporary Startup RT class to record the creation of persistent queues / exchanges. + * + * + * This is so we can replay the creation of queues/exchanges in to the real _RT after it has been loaded. + * This should be removed after the _RT has been fully split from the the TL + */ + private class StartupRoutingTable implements RoutingTable + { + public List<Exchange> exchange = new LinkedList<Exchange>(); + public List<CreateQueueTuple> queue = new LinkedList<CreateQueueTuple>(); + public List<CreateBindingTuple> bindings = new LinkedList<CreateBindingTuple>(); + + public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception + { + } + + public void close() throws Exception + { + } + + public void createExchange(Exchange exchange) throws AMQException + { + if (exchange.isDurable()) + { + this.exchange.add(exchange); + } + } + + public void removeExchange(Exchange exchange) throws AMQException + { + } + + public void bindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException + { + if (exchange.isDurable() && queue.isDurable()) + { + bindings.add(new CreateBindingTuple(exchange, routingKey, queue, args)); + } + } + + public void unbindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException + { + } + + public void createQueue(AMQQueue queue) throws AMQException + { + createQueue(queue, null); + } + + public void createQueue(AMQQueue queue, FieldTable arguments) throws AMQException + { + if (queue.isDurable()) + { + this.queue.add(new CreateQueueTuple(queue, arguments)); + } + } + + public void removeQueue(AMQQueue queue) throws AMQException + { + } + + private class CreateQueueTuple + { + public AMQQueue queue; + public FieldTable arguments; + + public CreateQueueTuple(AMQQueue queue, FieldTable arguments) + { + this.queue = queue; + this.arguments = arguments; + } + } + + private class CreateBindingTuple + { + public AMQQueue queue; + public FieldTable arguments; + public Exchange exchange; + public AMQShortString routingKey; + + public CreateBindingTuple(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) + { + this.exchange = exchange; + this.routingKey = routingKey; + this.queue = queue; + arguments = args; + } + } + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java index a8dd58ca83..7fe16062fc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java @@ -172,7 +172,7 @@ public class Move extends AbstractCommand { for (QueueEntry msg : messages) { - ids.add(msg.getMessage().getMessageId()); + ids.add(msg.getMessageId()); } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java index d46ba85069..49afcb1340 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java @@ -352,7 +352,7 @@ public class Show extends AbstractCommand isredelivered.add(entry.isRedelivered() ? "true" : "false"); - isdelivered.add(msg.getDeliveredToConsumer() ? "true" : "false"); + isdelivered.add(entry.getDeliveredToConsumer() ? "true" : "false"); BasicContentHeaderProperties headers = null; diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java index 2a97db6066..c370fd9867 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java @@ -32,6 +32,7 @@ import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.MockSubscription; +import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.AMQException; import java.util.Map; @@ -87,7 +88,7 @@ public class ExtractResendAndRequeueTest extends TestCase while(queueEntries.advance()) { QueueEntry entry = queueEntries.getNode(); - _unacknowledgedMessageMap.add(entry.getMessage().getMessageId(), entry); + _unacknowledgedMessageMap.add(entry.getMessageId(), entry); // Store the entry for future inspection _referenceList.add(entry); @@ -96,6 +97,12 @@ public class ExtractResendAndRequeueTest extends TestCase assertEquals("Map does not contain correct setup data", INITIAL_MSG_COUNT, _unacknowledgedMessageMap.size()); } + public void tearDown() throws Exception + { + //Ensure we close the registry that the MockAMQQueue will create + ApplicationRegistry.getInstance().close(); + } + /** * Helper method to create a new subscription and aquire the given messages. * diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java index 01533d6509..52b8b0ad19 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java @@ -21,12 +21,16 @@ package org.apache.qpid.server.ack; import junit.framework.TestCase; + +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.RequiredDeliveryException; +import org.apache.qpid.server.transactionlog.TransactionLog; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.MessageFactory; import org.apache.qpid.server.queue.QueueEntry; @@ -34,9 +38,10 @@ import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.TransientAMQMessage; import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; -import org.apache.qpid.server.store.TestMemoryMessageStore; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.server.store.TestTransactionLog; +import org.apache.qpid.server.store.TestableMemoryMessageStore; import org.apache.qpid.server.txn.NonTransactionalContext; import org.apache.qpid.server.txn.TransactionalContext; @@ -78,20 +83,6 @@ public class TxAckTest extends TestCase combined.stop(); } - public void testPrepare() throws AMQException - { - individual.prepare(); - multiple.prepare(); - combined.prepare(); - } - - public void testUndoPrepare() throws AMQException - { - individual.undoPrepare(); - multiple.undoPrepare(); - combined.undoPrepare(); - } - public void testCommit() throws AMQException { individual.commit(); @@ -112,17 +103,23 @@ public class TxAckTest extends TestCase private final List<Long> _unacked; private StoreContext _storeContext = new StoreContext(); private AMQQueue _queue; + private TransactionLog _transactionLog = new TestableMemoryMessageStore(); private static final int MESSAGE_SIZE=100; Scenario(int messageCount, List<Long> acked, List<Long> unacked) throws Exception { - TransactionalContext txnContext = new NonTransactionalContext(new TestMemoryMessageStore(), + TransactionalContext txnContext = new NonTransactionalContext(_transactionLog, _storeContext, null, new LinkedList<RequiredDeliveryException>() ); - _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, null, false, new VirtualHost("test", new MemoryMessageStore()), - null); + + PropertiesConfiguration env = new PropertiesConfiguration(); + env.setProperty("name", "test"); + VirtualHost virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env)); + + _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, null, false, + virtualHost, null); for (int i = 0; i < messageCount; i++) { @@ -130,12 +127,15 @@ public class TxAckTest extends TestCase MessagePublishInfo info = new MessagePublishInfoImpl(); - AMQMessage message = new TestMessage(deliveryTag, info); + AMQMessage message = new TestMessage(deliveryTag, info, (TestTransactionLog) _transactionLog); ContentHeaderBody header = new ContentHeaderBody(); header.bodySize = MESSAGE_SIZE; message.setPublishAndContentHeaderBody(_storeContext, info, header); + + + _map.add(deliveryTag, _queue.enqueue(new StoreContext(), message)); } _acked = acked; @@ -157,25 +157,6 @@ public class TxAckTest extends TestCase } } - void prepare() throws AMQException - { - _op.consolidate(); - _op.prepare(_storeContext); - - assertCount(_acked, -1); - assertCount(_unacked, 0); - - } - - void undoPrepare() - { - _op.consolidate(); - _op.undoPrepare(); - - assertCount(_acked, 1); - assertCount(_unacked, 0); - } - void commit() { _op.consolidate(); @@ -224,30 +205,22 @@ public class TxAckTest extends TestCase private class TestMessage extends TransientAMQMessage { private final long _tag; - private int _count; + private TestTransactionLog _transactionLog; - TestMessage(long tag, MessagePublishInfo publishBody) + public TestMessage(long tag, MessagePublishInfo publishBody, TestTransactionLog transactionLog) throws AMQException { super(createMessage( publishBody)); _tag = tag; + _transactionLog = transactionLog; } - public boolean incrementReference() - { - _count++; - return true; - } - - public void decrementReference(StoreContext context) - { - _count--; - } - void assertCountEquals(int expected) { - assertEquals("Wrong count for message with tag " + _tag, expected, _count); + List<AMQQueue> list = _transactionLog.getMessageReferenceMap(_messageId); + int actual = (list == null ? 0 : list.size()); + assertEquals("Wrong count for message with tag " + _tag, expected, actual); } } } 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 new file mode 100644 index 0000000000..ad1df1c777 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java @@ -0,0 +1,849 @@ +/* + * + * 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.configuration; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.List; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.qpid.AMQException; +import org.apache.qpid.codec.AMQCodecFactory; +import org.apache.qpid.server.protocol.AMQMinaProtocolSession; +import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.protocol.TestIoSession; +import org.apache.qpid.server.queue.MockProtocolSession; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; +import org.apache.qpid.server.security.access.ACLManager; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +import junit.framework.TestCase; + +public class ServerConfigurationTest extends TestCase +{ + + private XMLConfiguration _config; + + @Override + public void setUp() + { + _config = new XMLConfiguration(); + } + + @Override + public void tearDown() + { + ApplicationRegistry.removeAll(); + } + + public void testSetJMXManagementPort() throws ConfigurationException + { + ServerConfiguration serverConfig = new ServerConfiguration(_config); + serverConfig.setJMXManagementPort(23); + assertEquals(23, serverConfig.getJMXManagementPort()); + } + + public void testGetJMXManagementPort() throws ConfigurationException + { + _config.setProperty("management.jmxport", 42); + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(42, serverConfig.getJMXManagementPort()); + } + + public void testGetPlatformMbeanserver() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getPlatformMbeanserver()); + + // Check value we set + _config.setProperty("management.platform-mbeanserver", false); + serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getPlatformMbeanserver()); + } + + public void testGetPluginDirectory() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(null, serverConfig.getPluginDirectory()); + + // Check value we set + _config.setProperty("plugin-directory", "/path/to/plugins"); + serverConfig = new ServerConfiguration(_config); + assertEquals("/path/to/plugins", serverConfig.getPluginDirectory()); + } + + public void testGetPrincipalDatabaseNames() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getPrincipalDatabaseNames().size()); + + // Check value we set + _config.setProperty("security.principal-databases.principal-database(0).name", "a"); + _config.setProperty("security.principal-databases.principal-database(1).name", "b"); + serverConfig = new ServerConfiguration(_config); + List<String> dbs = serverConfig.getPrincipalDatabaseNames(); + assertEquals(2, dbs.size()); + assertEquals("a", dbs.get(0)); + assertEquals("b", dbs.get(1)); + } + + public void testGetPrincipalDatabaseClass() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getPrincipalDatabaseClass().size()); + + // Check value we set + _config.setProperty("security.principal-databases.principal-database(0).class", "a"); + _config.setProperty("security.principal-databases.principal-database(1).class", "b"); + serverConfig = new ServerConfiguration(_config); + List<String> dbs = serverConfig.getPrincipalDatabaseClass(); + assertEquals(2, dbs.size()); + assertEquals("a", dbs.get(0)); + assertEquals("b", dbs.get(1)); + } + + public void testGetPrincipalDatabaseAttributeNames() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getPrincipalDatabaseAttributeNames(1).size()); + + // Check value we set + _config.setProperty("security.principal-databases.principal-database(0).attributes(0).attribute.name", "a"); + _config.setProperty("security.principal-databases.principal-database(0).attributes(1).attribute.name", "b"); + serverConfig = new ServerConfiguration(_config); + List<String> dbs = serverConfig.getPrincipalDatabaseAttributeNames(0); + assertEquals(2, dbs.size()); + assertEquals("a", dbs.get(0)); + assertEquals("b", dbs.get(1)); + } + + public void testGetPrincipalDatabaseAttributeValues() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getPrincipalDatabaseAttributeValues(1).size()); + + // Check value we set + _config.setProperty("security.principal-databases.principal-database(0).attributes(0).attribute.value", "a"); + _config.setProperty("security.principal-databases.principal-database(0).attributes(1).attribute.value", "b"); + serverConfig = new ServerConfiguration(_config); + List<String> dbs = serverConfig.getPrincipalDatabaseAttributeValues(0); + assertEquals(2, dbs.size()); + assertEquals("a", dbs.get(0)); + assertEquals("b", dbs.get(1)); + } + + public void testGetManagementAccessList() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getManagementAccessList().size()); + + // Check value we set + _config.setProperty("security.jmx.access(0)", "a"); + _config.setProperty("security.jmx.access(1)", "b"); + serverConfig = new ServerConfiguration(_config); + List<String> dbs = serverConfig.getManagementAccessList(); + assertEquals(2, dbs.size()); + assertEquals("a", dbs.get(0)); + assertEquals("b", dbs.get(1)); + } + + public void testGetFrameSize() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(65536, serverConfig.getFrameSize()); + + // Check value we set + _config.setProperty("advanced.framesize", "23"); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getFrameSize()); + } + + public void testGetProtectIOEnabled() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getProtectIOEnabled()); + + // Check value we set + _config.setProperty("broker.connector.protectio.enabled", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getProtectIOEnabled()); + } + + public void testGetBufferReadLimit() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(262144, serverConfig.getBufferReadLimit()); + + // Check value we set + _config.setProperty("broker.connector.protectio.readBufferLimitSize", 23); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getBufferReadLimit()); + } + + public void testGetBufferWriteLimit() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(262144, serverConfig.getBufferWriteLimit()); + + // Check value we set + _config.setProperty("broker.connector.protectio.writeBufferLimitSize", 23); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getBufferWriteLimit()); + } + + public void testGetSynchedClocks() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getSynchedClocks()); + + // Check value we set + _config.setProperty("advanced.synced-clocks", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getSynchedClocks()); + } + + public void testGetMsgAuth() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getMsgAuth()); + + // Check value we set + _config.setProperty("security.msg-auth", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getMsgAuth()); + } + + public void testGetJMXPrincipalDatabase() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(null, serverConfig.getJMXPrincipalDatabase()); + + // Check value we set + _config.setProperty("security.jmx.principal-database", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getJMXPrincipalDatabase()); + } + + public void testGetManagementKeyStorePath() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(null, serverConfig.getManagementKeyStorePath()); + + // Check value we set + _config.setProperty("management.ssl.keyStorePath", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getManagementKeyStorePath()); + } + + public void testGetManagementSSLEnabled() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getManagementSSLEnabled()); + + // Check value we set + _config.setProperty("management.ssl.enabled", false); + serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getManagementSSLEnabled()); + } + + public void testGetManagementKeyStorePassword() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(null, serverConfig.getManagementKeyStorePassword()); + + // Check value we set + _config.setProperty("management.ssl.keyStorePassword", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getManagementKeyStorePassword()); + } + + public void testGetQueueAutoRegister() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getQueueAutoRegister()); + + // Check value we set + _config.setProperty("queue.auto_register", false); + serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getQueueAutoRegister()); + } + + public void testGetManagementEnabled() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getManagementEnabled()); + + // Check value we set + _config.setProperty("management.enabled", false); + serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getManagementEnabled()); + } + + public void testSetManagementEnabled() throws ConfigurationException + { + // Check value we set + ServerConfiguration serverConfig = new ServerConfiguration(_config); + serverConfig.setManagementEnabled(false); + assertEquals(false, serverConfig.getManagementEnabled()); + } + + public void testGetHeartBeatDelay() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(5, serverConfig.getHeartBeatDelay()); + + // Check value we set + _config.setProperty("heartbeat.delay", 23); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getHeartBeatDelay()); + } + + public void testGetHeartBeatTimeout() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(2.0, serverConfig.getHeartBeatTimeout()); + + // Check value we set + _config.setProperty("heartbeat.timeoutFactor", 2.3); + serverConfig = new ServerConfiguration(_config); + assertEquals(2.3, serverConfig.getHeartBeatTimeout()); + } + + public void testGetMaximumMessageAge() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getMaximumMessageAge()); + + // Check value we set + _config.setProperty("maximumMessageAge", 10L); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getMaximumMessageAge()); + } + + public void testGetMaximumMessageCount() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getMaximumMessageCount()); + + // Check value we set + _config.setProperty("maximumMessageCount", 10L); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getMaximumMessageCount()); + } + + public void testGetMaximumQueueDepth() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getMaximumQueueDepth()); + + // Check value we set + _config.setProperty("maximumQueueDepth", 10L); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getMaximumQueueDepth()); + } + + public void testGetMaximumMessageSize() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getMaximumMessageSize()); + + // Check value we set + _config.setProperty("maximumMessageSize", 10L); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getMaximumMessageSize()); + } + + public void testGetMinimumAlertRepeatGap() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(0, serverConfig.getMinimumAlertRepeatGap()); + + // Check value we set + _config.setProperty("minimumAlertRepeatGap", 10L); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getMinimumAlertRepeatGap()); + } + + public void testGetProcessors() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(4, serverConfig.getProcessors()); + + // Check value we set + _config.setProperty("connector.processors", 10); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getProcessors()); + } + + public void testGetPort() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(5672, serverConfig.getPort()); + + // Check value we set + _config.setProperty("connector.port", 10); + serverConfig = new ServerConfiguration(_config); + assertEquals(10, serverConfig.getPort()); + } + + public void testGetBind() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals("wildcard", serverConfig.getBind()); + + // Check value we set + _config.setProperty("connector.bind", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getBind()); + } + + public void testGetReceiveBufferSize() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(32767, serverConfig.getReceiveBufferSize()); + + // Check value we set + _config.setProperty("connector.socketReceiveBuffer", "23"); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getReceiveBufferSize()); + } + + public void testGetWriteBufferSize() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(32767, serverConfig.getWriteBufferSize()); + + // Check value we set + _config.setProperty("connector.socketWriteBuffer", "23"); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getWriteBufferSize()); + } + + public void testGetTcpNoDelay() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getTcpNoDelay()); + + // Check value we set + _config.setProperty("connector.tcpNoDelay", false); + serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getTcpNoDelay()); + } + + public void testGetEnableExecutorPool() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getEnableExecutorPool()); + + // Check value we set + _config.setProperty("advanced.filterchain[@enableExecutorPool]", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getEnableExecutorPool()); + } + + public void testGetEnablePooledAllocator() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getEnablePooledAllocator()); + + // Check value we set + _config.setProperty("advanced.enablePooledAllocator", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getEnablePooledAllocator()); + } + + public void testGetEnableDirectBuffers() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getEnableDirectBuffers()); + + // Check value we set + _config.setProperty("advanced.enableDirectBuffers", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getEnableDirectBuffers()); + } + + public void testGetEnableSSL() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getEnableSSL()); + + // Check value we set + _config.setProperty("connector.ssl.enabled", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getEnableSSL()); + } + + public void testGetSSLOnly() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getSSLOnly()); + + // Check value we set + _config.setProperty("connector.ssl.sslOnly", false); + serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getSSLOnly()); + } + + public void testGetSSLPort() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(8672, serverConfig.getSSLPort()); + + // Check value we set + _config.setProperty("connector.ssl.port", 23); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getSSLPort()); + } + + public void testGetKeystorePath() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals("none", serverConfig.getKeystorePath()); + + // Check value we set + _config.setProperty("connector.ssl.keystorePath", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getKeystorePath()); + } + + public void testGetKeystorePassword() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals("none", serverConfig.getKeystorePassword()); + + // Check value we set + _config.setProperty("connector.ssl.keystorePassword", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getKeystorePassword()); + } + + public void testGetCertType() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals("SunX509", serverConfig.getCertType()); + + // Check value we set + _config.setProperty("connector.ssl.certType", "a"); + serverConfig = new ServerConfiguration(_config); + assertEquals("a", serverConfig.getCertType()); + } + + public void testGetQpidNIO() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getQpidNIO()); + + // Check value we set + _config.setProperty("connector.qpidnio", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getQpidNIO()); + } + + public void testGetUseBiasedWrites() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(false, serverConfig.getUseBiasedWrites()); + + // Check value we set + _config.setProperty("advanced.useWriteBiasedPool", true); + serverConfig = new ServerConfiguration(_config); + assertEquals(true, serverConfig.getUseBiasedWrites()); + } + + public void testGetHousekeepingExpiredMessageCheckPeriod() throws ConfigurationException + { + // Check default + ServerConfiguration serverConfig = new ServerConfiguration(_config); + assertEquals(30000, serverConfig.getHousekeepingCheckPeriod()); + + // Check value we set + _config.setProperty("housekeeping.expiredMessageCheckPeriod", 23L); + serverConfig = new ServerConfiguration(_config); + assertEquals(23, serverConfig.getHousekeepingCheckPeriod()); + serverConfig.setHousekeepingExpiredMessageCheckPeriod(42L); + assertEquals(42, serverConfig.getHousekeepingCheckPeriod()); + } + + public void testSingleConfiguration() throws IOException, ConfigurationException + { + File fileA = File.createTempFile(getClass().getName(), null); + fileA.deleteOnExit(); + FileWriter out = new FileWriter(fileA); + out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>"); + out.close(); + ServerConfiguration conf = new ServerConfiguration(fileA); + assertEquals(4235, conf.getSSLPort()); + } + + public void testCombinedConfiguration() throws IOException, ConfigurationException + { + File mainFile = File.createTempFile(getClass().getName(), null); + File fileA = File.createTempFile(getClass().getName(), null); + File fileB = File.createTempFile(getClass().getName(), null); + + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + + FileWriter out = new FileWriter(mainFile); + out.write("<configuration><system/>"); + out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>"); + out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>"); + out.write("</configuration>"); + out.close(); + + out = new FileWriter(fileA); + out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>"); + out.close(); + + out = new FileWriter(fileB); + out.write("<broker><connector><ssl><port>2345</port></ssl><qpidnio>true</qpidnio></connector></broker>"); + out.close(); + + ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile()); + assertEquals(4235, config.getSSLPort()); // From first file, not + // overriden by second + assertEquals(2342, config.getPort()); // From the first file, not + // present in the second + assertEquals(true, config.getQpidNIO()); // From the second file, not + // present in the first + } + + public void testCombinedConfigurationFirewall() throws Exception + { + // Write out config + File mainFile = File.createTempFile(getClass().getName(), null); + File fileA = File.createTempFile(getClass().getName(), null); + File fileB = File.createTempFile(getClass().getName(), null); + + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + + FileWriter out = new FileWriter(mainFile); + out.write("<configuration><system/>"); + out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>"); + out.write("</configuration>"); + out.close(); + + out = new FileWriter(fileA); + out.write("<broker>\n"); + out.write("\t<management><enabled>false</enabled></management>\n"); + out.write("\t<security>\n"); + out.write("\t\t<principal-databases>\n"); + out.write("\t\t\t<principal-database>\n"); + out.write("\t\t\t\t<name>passwordfile</name>\n"); + out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); + out.write("\t\t\t\t<attributes>\n"); + out.write("\t\t\t\t\t<attribute>\n"); + out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); + out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); + out.write("\t\t\t\t\t</attribute>\n"); + 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<access>/dev/null</access>\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"); + out.write("\t</security>\n"); + out.write("\t<virtualhosts>\n"); + out.write("\t\t<virtualhost>\n"); + out.write("\t\t\t<name>test</name>\n"); + out.write("\t\t</virtualhost>\n"); + out.write("\t</virtualhosts>\n"); + out.write("</broker>\n"); + out.close(); + + out = new FileWriter(fileB); + out.write("<firewall>\n"); + out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>"); + out.write("</firewall>\n"); + out.close(); + + // Load config + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + ApplicationRegistry.initialise(reg, 1); + + // Test config + TestIoSession iosession = new TestIoSession(); + iosession.setAddress("127.0.0.1"); + VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); + VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); + AMQCodecFactory codecFactory = new AMQCodecFactory(true); + AMQProtocolSession session = new AMQMinaProtocolSession(iosession, virtualHostRegistry, codecFactory); + assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost)); + } + + public void testCombinedConfigurationFirewallReload() throws Exception + { + // Write out config + File mainFile = File.createTempFile(getClass().getName(), null); + File fileA = File.createTempFile(getClass().getName(), null); + File fileB = File.createTempFile(getClass().getName(), null); + + mainFile.deleteOnExit(); + fileA.deleteOnExit(); + fileB.deleteOnExit(); + + FileWriter out = new FileWriter(mainFile); + out.write("<configuration><system/>"); + out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>"); + out.write("</configuration>"); + out.close(); + + out = new FileWriter(fileA); + out.write("<broker>\n"); + out.write("\t<management><enabled>false</enabled></management>\n"); + out.write("\t<security>\n"); + out.write("\t\t<principal-databases>\n"); + out.write("\t\t\t<principal-database>\n"); + out.write("\t\t\t\t<name>passwordfile</name>\n"); + out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n"); + out.write("\t\t\t\t<attributes>\n"); + out.write("\t\t\t\t\t<attribute>\n"); + out.write("\t\t\t\t\t\t<name>passwordFile</name>\n"); + out.write("\t\t\t\t\t\t<value>/dev/null</value>\n"); + out.write("\t\t\t\t\t</attribute>\n"); + 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<access>/dev/null</access>\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"); + out.write("\t</security>\n"); + out.write("\t<virtualhosts>\n"); + out.write("\t\t<virtualhost>\n"); + out.write("\t\t\t<name>test</name>\n"); + out.write("\t\t</virtualhost>\n"); + out.write("\t</virtualhosts>\n"); + out.write("</broker>\n"); + out.close(); + + out = new FileWriter(fileB); + out.write("<firewall>\n"); + out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>"); + out.write("</firewall>\n"); + out.close(); + + // Load config + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile); + ApplicationRegistry.initialise(reg, 1); + + // Test config + TestIoSession iosession = new TestIoSession(); + iosession.setAddress("127.0.0.1"); + VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry(); + VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test"); + AMQCodecFactory codecFactory = new AMQCodecFactory(true); + AMQProtocolSession session = new AMQMinaProtocolSession(iosession, virtualHostRegistry, codecFactory); + assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost)); + + RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw"); + fileBRandom.setLength(0); + fileBRandom.seek(0); + fileBRandom.close(); + + out = new FileWriter(fileB); + out.write("<firewall>\n"); + out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>"); + out.write("</firewall>\n"); + out.close(); + + reg.getConfiguration().reparseConfigFile(); + + assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost)); + + fileBRandom = new RandomAccessFile(fileB, "rw"); + fileBRandom.setLength(0); + fileBRandom.seek(0); + fileBRandom.close(); + + out = new FileWriter(fileB); + out.write("<firewall>\n"); + out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>"); + out.write("</firewall>\n"); + out.close(); + + reg.getConfiguration().reparseConfigFile(); + + assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost)); + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java index 8f743d8856..7239ec9303 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java @@ -20,13 +20,10 @@ package org.apache.qpid.server.configuration; -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; +import junit.framework.TestCase; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; -import org.apache.commons.configuration.HierarchicalConfiguration.Node; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.queue.AMQPriorityQueue; @@ -34,29 +31,22 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; -import junit.framework.TestCase; - public class VirtualHostConfigurationTest extends TestCase { - private File configFile; private VirtualHostConfiguration vhostConfig; private XMLConfiguration configXml; @Override protected void setUp() throws Exception - { - // Create temporary configuration file - configFile = File.createTempFile(this.getName()+"config", ".xml"); - configFile.deleteOnExit(); - + { // Fill config file with stuff configXml = new XMLConfiguration(); configXml.setRootElementName("virtualhosts"); configXml.addProperty("virtualhost(-1).name", "test"); } - public void testQueuePriority() throws ConfigurationException, AMQException + public void testQueuePriority() throws Exception { // Set up queue with 5 priorities configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)", @@ -81,14 +71,8 @@ public class VirtualHostConfigurationTest extends TestCase "amq.direct"); configXml.addProperty("virtualhost.test.queues.queue.ntest.priority", "false"); - configXml.save(configFile); - - // Setup virtual host configuration - vhostConfig = new VirtualHostConfiguration(configFile.getAbsolutePath()); - // Do bindings and get resulting vhost - vhostConfig.performBindings(); - VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); + VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test"))); // Check that atest was a priority queue with 5 priorities AMQQueue atest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest")); @@ -105,4 +89,64 @@ public class VirtualHostConfigurationTest extends TestCase assertFalse(ntest instanceof AMQPriorityQueue); } + public void testQueueAlerts() throws Exception + { + // Set up queue with 5 priorities + configXml.addProperty("virtualhost.test.queues.exchange", "amq.topic"); + configXml.addProperty("virtualhost.test.queues.maximumQueueDepth", "1"); + configXml.addProperty("virtualhost.test.queues.maximumMessageSize", "2"); + configXml.addProperty("virtualhost.test.queues.maximumMessageAge", "3"); + + configXml.addProperty("virtualhost.test.queues(-1).queue(1).name(1)", "atest"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).exchange", "amq.direct"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumQueueDepth", "4"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMessageSize", "5"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMessageAge", "6"); + + configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)", "btest"); + + VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test"))); + + // Check specifically configured values + AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest")); + assertEquals(4, aTest.getMaximumQueueDepth()); + assertEquals(5, aTest.getMaximumMessageSize()); + assertEquals(6, aTest.getMaximumMessageAge()); + + // Check default values + AMQQueue bTest = vhost.getQueueRegistry().getQueue(new AMQShortString("btest")); + assertEquals(1, bTest.getMaximumQueueDepth()); + assertEquals(2, bTest.getMaximumMessageSize()); + assertEquals(3, bTest.getMaximumMessageAge()); + + } + + public void testQueueMemoryValues() throws Exception + { + // Set up queue with 5 priorities + configXml.addProperty("virtualhost.test.queues.exchange", "amq.topic"); + configXml.addProperty("virtualhost.test.queues.maximumMemoryUsage", "11"); + configXml.addProperty("virtualhost.test.queues.minimumMemoryUsage", "22"); + + configXml.addProperty("virtualhost.test.queues(-1).queue(1).name(1)", "atest"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).exchange", "amq.direct"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMemoryUsage", "44"); + configXml.addProperty("virtualhost.test.queues.queue.atest(-1).minimumMemoryUsage", "55"); + + configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)", "btest"); + + VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test"))); + + // Check specifically configured values + AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest")); + assertEquals(44, aTest.getMemoryUsageMaximum()); + assertEquals(55, aTest.getMemoryUsageMinimum()); + + // Check default values + AMQQueue bTest = vhost.getQueueRegistry().getQueue(new AMQShortString("btest")); + assertEquals(11, bTest.getMemoryUsageMaximum()); + assertEquals(22, bTest.getMemoryUsageMinimum()); + } + + } 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 40b08a2e39..ee1796ba2f 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 @@ -36,7 +36,6 @@ import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.FailedDequeueException; import org.apache.qpid.server.queue.IncomingMessage; -import org.apache.qpid.server.queue.MessageCleanupException; import org.apache.qpid.server.queue.MockProtocolSession; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.queue.SimpleAMQQueue; @@ -214,6 +213,11 @@ public class AbstractHeadersExchangeTestBase extends TestCase return null; //To change body of implemented methods use File | Settings | File Templates. } + public Long getMessageId() + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + public long getSize() { return 0; //To change body of implemented methods use File | Settings | File Templates. @@ -229,11 +233,21 @@ public class AbstractHeadersExchangeTestBase extends TestCase return false; //To change body of implemented methods use File | Settings | File Templates. } + public void setExpiration(long expiration) + { + //To change body of implemented methods use File | Settings | File Templates. + } + public boolean isAcquired() { return false; //To change body of implemented methods use File | Settings | File Templates. } + public boolean isAvailable() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + public boolean acquire() { return false; //To change body of implemented methods use File | Settings | File Templates. @@ -314,32 +328,38 @@ public class AbstractHeadersExchangeTestBase extends TestCase //To change body of implemented methods use File | Settings | File Templates. } - public void dispose(final StoreContext storeContext) throws MessageCleanupException + + public void dequeueAndDelete(StoreContext storeContext) throws FailedDequeueException { //To change body of implemented methods use File | Settings | File Templates. } - public void restoreCredit() + public boolean isQueueDeleted() { - //To change body of implemented methods use File | Settings | File Templates. + return false; //To change body of implemented methods use File | Settings | File Templates. } - public void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException + public void addStateChangeListener(StateChangeListener listener) { //To change body of implemented methods use File | Settings | File Templates. } - public boolean isQueueDeleted() + public boolean removeStateChangeListener(StateChangeListener listener) { return false; //To change body of implemented methods use File | Settings | File Templates. } - public void addStateChangeListener(StateChangeListener listener) + public void unload() { //To change body of implemented methods use File | Settings | File Templates. } - public boolean removeStateChangeListener(StateChangeListener listener) + public AMQMessage load() + { + return null; + } + + public boolean isFlowed() { return false; //To change body of implemented methods use File | Settings | File Templates. } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java index f8544a33bd..890b641540 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java @@ -100,7 +100,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -140,7 +140,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -159,7 +159,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -198,7 +198,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -217,7 +217,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -236,7 +236,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -254,7 +254,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -294,7 +294,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -312,7 +312,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -352,7 +352,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -384,7 +384,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -425,7 +425,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); @@ -464,7 +464,7 @@ public class DestWildExchangeTest extends TestCase Assert.assertEquals(1, queue.getMessageCount()); - Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId()); + Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId()); queue.deleteMessageFromTop(_context); Assert.assertEquals(0, queue.getMessageCount()); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java index 9344efd4a8..e7b3f40393 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java @@ -23,10 +23,18 @@ package org.apache.qpid.server.filter; import junit.framework.TestCase; import org.apache.qpid.AMQException; import org.apache.qpid.server.queue.MockQueueEntry; +import org.apache.qpid.server.registry.ApplicationRegistry; public class PropertyExpressionTest extends TestCase { + public void tearDown() throws Exception + { + //Ensure we close the registry that the MockQueueEntry will create + ApplicationRegistry.remove(1); + } + + public void testJMSRedelivered() { PropertyExpression<AMQException> pe = new PropertyExpression<AMQException>("JMSRedelivered"); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java new file mode 100644 index 0000000000..40153be331 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java @@ -0,0 +1,413 @@ +/* + * 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.logging.management; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.management.JMException; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularDataSupport; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; + +import junit.framework.TestCase; + +public class LoggingManagementMBeanTest extends TestCase +{ + private static final String TEST_LOGGER = "LoggingManagementMBeanTestLogger"; + private static final String TEST_LOGGER_CHILD1 = "LoggingManagementMBeanTestLogger.child1"; + private static final String TEST_LOGGER_CHILD2 = "LoggingManagementMBeanTestLogger.child2"; + + private static final String CATEGORY_PRIORITY = "LogManMBeanTest.category.priority"; + private static final String CATEGORY_LEVEL = "LogManMBeanTest.category.level"; + private static final String LOGGER_LEVEL = "LogManMBeanTest.logger.level"; + + private static final String NAME_INDEX = LoggingManagement.COMPOSITE_ITEM_NAMES[0]; + private static final String LEVEL_INDEX = LoggingManagement.COMPOSITE_ITEM_NAMES[1]; + + private static final String NEWLINE = System.getProperty("line.separator"); + + private File _testConfigFile; + + protected void setUp() throws Exception + { + _testConfigFile = createTempTestLog4JConfig(); + } + + private File createTempTestLog4JConfig() + { + File tmpFile = null; + try + { + tmpFile = File.createTempFile("LogManMBeanTestLog4jConfig", ".tmp"); + tmpFile.deleteOnExit(); + + FileWriter fstream = new FileWriter(tmpFile); + BufferedWriter writer = new BufferedWriter(fstream); + + writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+NEWLINE); + writer.write("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">"+NEWLINE); + + writer.write("<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\" debug=\"null\" " + + "threshold=\"null\">"+NEWLINE); + + writer.write(" <appender class=\"org.apache.log4j.ConsoleAppender\" name=\"STDOUT\">"+NEWLINE); + writer.write(" <layout class=\"org.apache.log4j.PatternLayout\">"+NEWLINE); + writer.write(" <param name=\"ConversionPattern\" value=\"%d %-5p [%t] %C{2} (%F:%L) - %m%n\"/>"+NEWLINE); + writer.write(" </layout>"+NEWLINE); + writer.write(" </appender>"+NEWLINE); + + //Example of a 'category' with a 'priority' + writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_PRIORITY +"\">"+NEWLINE); + writer.write(" <priority value=\"info\"/>"+NEWLINE); + writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); + writer.write(" </category>"+NEWLINE); + + //Example of a 'category' with a 'level' + writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_LEVEL +"\">"+NEWLINE); + writer.write(" <level value=\"warn\"/>"+NEWLINE); + writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); + writer.write(" </category>"+NEWLINE); + + //Example of a 'logger' with a 'level' + writer.write(" <logger additivity=\"true\" name=\"" + LOGGER_LEVEL + "\">"+NEWLINE); + writer.write(" <level value=\"error\"/>"+NEWLINE); + writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); + writer.write(" </logger>"+NEWLINE); + + //'root' logger + writer.write(" <root>"+NEWLINE); + writer.write(" <priority value=\"info\"/>"+NEWLINE); + writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE); + writer.write(" </root>"+NEWLINE); + + writer.write("</log4j:configuration>"+NEWLINE); + + writer.flush(); + writer.close(); + } + catch (IOException e) + { + fail("Unable to create temporary test log4j configuration"); + } + + return tmpFile; + } + + + + //******* Test Methods ******* // + + public void testSetRuntimeLoggerLevel() + { + LoggingManagementMBean lm = null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + //create a parent test logger, set its level explicitly + Logger log = Logger.getLogger(TEST_LOGGER); + log.setLevel(Level.toLevel("info")); + + //create child1 test logger, check its *effective* level is the same as the parent, "info" + Logger log1 = Logger.getLogger(TEST_LOGGER_CHILD1); + assertTrue("Test logger's level was not the expected value", + log1.getEffectiveLevel().toString().equalsIgnoreCase("info")); + + //now change its level to "warn" + assertTrue("Failed to set logger level", lm.setRuntimeLoggerLevel(TEST_LOGGER_CHILD1, "warn")); + + //check the change, see its actual level is "warn + assertTrue("Test logger's level was not the expected value", + log1.getLevel().toString().equalsIgnoreCase("warn")); + + //try an invalid level + assertFalse("Trying to set an invalid level succeded", lm.setRuntimeLoggerLevel(TEST_LOGGER_CHILD1, "made.up.level")); + } + + public void testSetRuntimeRootLoggerLevel() + { + LoggingManagementMBean lm = null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + Logger log = Logger.getRootLogger(); + + //get current root logger level + Level origLevel = log.getLevel(); + + //change level twice to ensure a new level is actually selected + + //set root loggers level to info + assertTrue("Failed to set root logger level", lm.setRuntimeRootLoggerLevel("debug")); + //check it is now actually info + Level currentLevel = log.getLevel(); + assertTrue("Logger level was not expected value", currentLevel.equals(Level.toLevel("debug"))); + + //try an invalid level + assertFalse("Trying to set an invalid level succeded", lm.setRuntimeRootLoggerLevel("made.up.level")); + + //set root loggers level to warn + assertTrue("Failed to set logger level", lm.setRuntimeRootLoggerLevel("info")); + //check it is now actually warn + currentLevel = log.getLevel(); + assertTrue("Logger level was not expected value", currentLevel.equals(Level.toLevel("info"))); + + //restore original level + log.setLevel(origLevel); + } + + public void testGetRuntimeRootLoggerLevel() + { + LoggingManagementMBean lm = null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + Logger log = Logger.getRootLogger(); + + //get current root logger level + Level origLevel = log.getLevel(); + + //change level twice to ensure a new level is actually selected + + //set root loggers level to debug + log.setLevel(Level.toLevel("debug")); + //check it is now actually debug + assertTrue("Logger level was not expected value", lm.getRuntimeRootLoggerLevel().equalsIgnoreCase("debug")); + + + //set root loggers level to warn + log.setLevel(Level.toLevel("info")); + //check it is now actually warn + assertTrue("Logger level was not expected value", lm.getRuntimeRootLoggerLevel().equalsIgnoreCase("info")); + + //restore original level + log.setLevel(origLevel); + } + + public void testViewEffectiveRuntimeLoggerLevels() + { + LoggingManagementMBean lm = null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + //(re)create a parent test logger, set its level explicitly + Logger log = Logger.getLogger(TEST_LOGGER); + log.setLevel(Level.toLevel("info")); + + //retrieve the current effective runtime logger level values + TabularDataSupport levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels(); + Collection<Object> records = levels.values(); + Map<String,String> list = new HashMap<String,String>(); + for (Object o : records) + { + CompositeData data = (CompositeData) o; + list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString()); + } + + //check child2 does not exist already + assertFalse("Did not expect this logger to exist already", list.containsKey(TEST_LOGGER_CHILD2)); + + //create child2 test logger + Logger log2 = Logger.getLogger(TEST_LOGGER_CHILD2); + + //retrieve the current effective runtime logger level values + levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels(); + records = levels.values(); + list = new HashMap<String,String>(); + for (Object o : records) + { + CompositeData data = (CompositeData) o; + list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString()); + } + + //verify the parent and child2 loggers are present in returned values + assertTrue(TEST_LOGGER + " logger was not in the returned list", list.containsKey(TEST_LOGGER)); + assertTrue(TEST_LOGGER_CHILD2 + " logger was not in the returned list", list.containsKey(TEST_LOGGER_CHILD2)); + + //check child2's effective level is the same as the parent, "info" + assertTrue("Test logger's level was not the expected value", + list.get(TEST_LOGGER_CHILD2).equalsIgnoreCase("info")); + + //now change its level explicitly to "warn" + log2.setLevel(Level.toLevel("warn")); + + //retrieve the current effective runtime logger level values + levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels(); + records = levels.values(); + list = new HashMap<String,String>(); + for (Object o : records) + { + CompositeData data = (CompositeData) o; + list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString()); + } + + //check child2's effective level is now "warn" + assertTrue("Test logger's level was not the expected value", + list.get(TEST_LOGGER_CHILD2).equalsIgnoreCase("warn")); + } + + public void testViewAndSetConfigFileLoggerLevel() throws Exception + { + LoggingManagementMBean lm =null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + //retrieve the current values + TabularDataSupport levels = (TabularDataSupport) lm.viewConfigFileLoggerLevels(); + Collection<Object> records = levels.values(); + Map<String,String> list = new HashMap<String,String>(); + for (Object o : records) + { + CompositeData data = (CompositeData) o; + list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString()); + } + + //check the 3 different types of logger definition are successfully retrieved before update + assertTrue("Wrong number of items in returned list", list.size() == 3); + assertTrue(CATEGORY_PRIORITY + " logger was not in the returned list", list.containsKey(CATEGORY_PRIORITY)); + assertTrue(CATEGORY_LEVEL + " logger was not in the returned list", list.containsKey(CATEGORY_LEVEL)); + assertTrue(LOGGER_LEVEL + " logger was not in the returned list", list.containsKey(LOGGER_LEVEL)); + + //check that their level is as expected + assertTrue(CATEGORY_PRIORITY + " logger's level was incorrect", list.get(CATEGORY_PRIORITY).equalsIgnoreCase("info")); + assertTrue(CATEGORY_LEVEL + " logger's level was incorrect", list.get(CATEGORY_LEVEL).equalsIgnoreCase("warn")); + assertTrue(LOGGER_LEVEL + " logger's level was incorrect", list.get(LOGGER_LEVEL).equalsIgnoreCase("error")); + + //increase their levels a notch to test the 3 different types of logger definition are successfully updated + //change the category+priority to warn + assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(CATEGORY_PRIORITY, "warn")); + //change the category+level to error + assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(CATEGORY_LEVEL, "error")); + //change the logger+level to trace + assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(LOGGER_LEVEL, "trace")); + + //try an invalid level + assertFalse("Use of an invalid logger level was successfull", lm.setConfigFileLoggerLevel(LOGGER_LEVEL, "made.up.level")); + + //try an invalid logger name + assertFalse("Use of an invalid logger name was successfull", lm.setConfigFileLoggerLevel("made.up.logger.name", "info")); + + //retrieve the new values from the file and check them + levels = (TabularDataSupport) lm.viewConfigFileLoggerLevels(); + records = levels.values(); + list = new HashMap<String,String>(); + for (Object o : records) + { + CompositeData data = (CompositeData) o; + list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString()); + } + + //check the 3 different types of logger definition are successfully retrieved after update + assertTrue("Wrong number of items in returned list", list.size() == 3); + assertTrue(CATEGORY_PRIORITY + " logger was not in the returned list", list.containsKey(CATEGORY_PRIORITY)); + assertTrue(CATEGORY_LEVEL + " logger was not in the returned list", list.containsKey(CATEGORY_LEVEL)); + assertTrue(LOGGER_LEVEL + " logger was not in the returned list", list.containsKey(LOGGER_LEVEL)); + + //check that their level is as expected after the changes + assertTrue(CATEGORY_PRIORITY + " logger's level was incorrect", list.get(CATEGORY_PRIORITY).equalsIgnoreCase("warn")); + assertTrue(CATEGORY_LEVEL + " logger's level was incorrect", list.get(CATEGORY_LEVEL).equalsIgnoreCase("error")); + assertTrue(LOGGER_LEVEL + " logger's level was incorrect", list.get(LOGGER_LEVEL).equalsIgnoreCase("trace")); + } + + public void testGetAndSetConfigFileRootLoggerLevel() throws Exception + { + LoggingManagementMBean lm =null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + //retrieve the current value + String level = lm.getConfigFileRootLoggerLevel(); + + //check the value was successfully retrieved before update + assertTrue("Retrieved RootLogger level was incorrect", level.equalsIgnoreCase("info")); + + //try an invalid level + assertFalse("Use of an invalid RootLogger level was successfull", lm.setConfigFileRootLoggerLevel("made.up.level")); + + //change the level to warn + assertTrue("Failed to set new RootLogger level", lm.setConfigFileRootLoggerLevel("warn")); + + //retrieve the current value + level = lm.getConfigFileRootLoggerLevel(); + + //check the value was successfully retrieved after update + assertTrue("Retrieved RootLogger level was incorrect", level.equalsIgnoreCase("warn")); + } + + public void testGetLog4jLogWatchInterval() + { + LoggingManagementMBean lm =null; + try + { + lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 5000); + } + catch (JMException e) + { + fail("Could not create test LoggingManagementMBean"); + } + + assertTrue("Wrong value returned for logWatch period", lm.getLog4jLogWatchInterval() == 5000); + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java index ba02e6f6bd..d7844730d1 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java @@ -23,20 +23,21 @@ package org.apache.qpid.server.queue; import junit.framework.AssertionFailedError; import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.txn.NonTransactionalContext; import java.util.ArrayList; public class AMQPriorityQueueTest extends SimpleAMQQueueTest { - private static final long MESSAGE_SIZE = 100L; + private static final int PRIORITIES = 3; @Override protected void setUp() throws Exception - { + { _arguments = new FieldTable(); - _arguments.put(AMQQueueFactory.X_QPID_PRIORITIES, 3); + _arguments.put(AMQQueueFactory.X_QPID_PRIORITIES, PRIORITIES); super.setUp(); } @@ -64,20 +65,20 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest _queue.registerSubscription(_subscription, false); Thread.sleep(150); - ArrayList<QueueEntry> msgs = _subscription.getMessages(); + ArrayList<QueueEntry> msgs = _subscription.getQueueEntries(); try { - assertEquals(new Long(1 + messagIDOffset), msgs.get(0).getMessage().getMessageId()); - assertEquals(new Long(6 + messagIDOffset), msgs.get(1).getMessage().getMessageId()); - assertEquals(new Long(8 + messagIDOffset), msgs.get(2).getMessage().getMessageId()); + assertEquals(new Long(1 + messagIDOffset), msgs.get(0).getMessageId()); + assertEquals(new Long(6 + messagIDOffset), msgs.get(1).getMessageId()); + assertEquals(new Long(8 + messagIDOffset), msgs.get(2).getMessageId()); - assertEquals(new Long(2 + messagIDOffset), msgs.get(3).getMessage().getMessageId()); - assertEquals(new Long(5 + messagIDOffset), msgs.get(4).getMessage().getMessageId()); - assertEquals(new Long(7 + messagIDOffset), msgs.get(5).getMessage().getMessageId()); + assertEquals(new Long(2 + messagIDOffset), msgs.get(3).getMessageId()); + assertEquals(new Long(5 + messagIDOffset), msgs.get(4).getMessageId()); + assertEquals(new Long(7 + messagIDOffset), msgs.get(5).getMessageId()); - assertEquals(new Long(3 + messagIDOffset), msgs.get(6).getMessage().getMessageId()); - assertEquals(new Long(4 + messagIDOffset), msgs.get(7).getMessage().getMessageId()); - assertEquals(new Long(9 + messagIDOffset), msgs.get(8).getMessage().getMessageId()); + assertEquals(new Long(3 + messagIDOffset), msgs.get(6).getMessageId()); + assertEquals(new Long(4 + messagIDOffset), msgs.get(7).getMessageId()); + assertEquals(new Long(9 + messagIDOffset), msgs.get(8).getMessageId()); } catch (AssertionFailedError afe) { @@ -85,7 +86,6 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest int index = 1; for (QueueEntry qe : msgs) { - System.err.println(index + ":" + qe.getMessage().getMessageId()); index++; } @@ -97,9 +97,96 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest protected AMQMessage createMessage(byte i) throws AMQException { AMQMessage message = super.createMessage(); - - ((BasicContentHeaderProperties)message.getContentHeaderBody().properties).setPriority(i); + + ((BasicContentHeaderProperties) message.getContentHeaderBody().properties).setPriority(i); return message; } + + + public void testMessagesFlowToDiskWithPriority() throws AMQException, InterruptedException + { + int PRIORITIES = 1; + FieldTable arguments = new FieldTable(); + arguments.put(AMQQueueFactory.X_QPID_PRIORITIES, PRIORITIES); + + // Create IncomingMessage and nondurable queue + NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null); + + //Create a priorityQueue + _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testMessagesFlowToDiskWithPriority"), false, _owner, false, _virtualHost, arguments); + + MESSAGE_SIZE = 1; + long MEMORY_MAX = PRIORITIES * 2; + int MESSAGE_COUNT = (int) MEMORY_MAX * 2; + //Set the Memory Usage to be very low + _queue.setMemoryUsageMaximum(MEMORY_MAX); + + for (int msgCount = 0; msgCount < MESSAGE_COUNT / 2; msgCount++) + { + sendMessage(txnContext, (msgCount % 10)); + } + + //Check that we can hold 10 messages without flowing + assertEquals(MESSAGE_COUNT / 2, _queue.getMessageCount()); + assertEquals(MEMORY_MAX, _queue.getMemoryUsageMaximum()); + assertEquals(_queue.getMemoryUsageMaximum(), _queue.getMemoryUsageCurrent()); + assertTrue("Queue is flowed.", !_queue.isFlowed()); + + // Send another and ensure we are flowed + sendMessage(txnContext, 9); + + //Give the Purging Thread a chance to run + Thread.yield(); + Thread.sleep(500); + + assertTrue("Queue is not flowed.", _queue.isFlowed()); + assertEquals("Queue contains more messages than expected.", MESSAGE_COUNT / 2 + 1, _queue.getMessageCount()); + assertEquals("Queue over memory quota.",MESSAGE_COUNT / 2, _queue.getMemoryUsageCurrent()); + + + //send another batch of messagse so the total in each queue is equal + for (int msgCount = 0; msgCount < (MESSAGE_COUNT / 2) ; msgCount++) + { + sendMessage(txnContext, (msgCount % 10)); + + long usage = _queue.getMemoryUsageCurrent(); + assertTrue("Queue has gone over quota:" + usage, + usage <= _queue.getMemoryUsageMaximum()); + + assertTrue("Queue has a negative quota:" + usage, usage > 0); + + } + assertEquals(MESSAGE_COUNT + 1, _queue.getMessageCount()); + assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is not flowed.", _queue.isFlowed()); + + _queue.registerSubscription(_subscription, false); + + int slept = 0; + while (_subscription.getQueueEntries().size() != MESSAGE_COUNT + 1 && slept < 10) + { + Thread.yield(); + Thread.sleep(500); + slept++; + } + + //Ensure the messages are retreived + assertEquals("Not all messages were received, slept:" + slept / 2 + "s", MESSAGE_COUNT + 1, _subscription.getQueueEntries().size()); + + //Check the queue is still within it's limits. + assertTrue("Queue has gone over quota:" + _queue.getMemoryUsageCurrent(), + _queue.getMemoryUsageCurrent() <= _queue.getMemoryUsageMaximum()); + + assertTrue("Queue has a negative quota:" + _queue.getMemoryUsageCurrent(), _queue.getMemoryUsageCurrent() >= 0); + + for (int index = 0; index < MESSAGE_COUNT; index++) + { + // Ensure that we have received the messages and it wasn't flushed to disk before we received it. + AMQMessage message = _subscription.getMessages().get(index); + assertNotNull("Message:" + message.debugIdentity() + " was null.", message); + } + + } + } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java index 1bc50db1d5..237fe20f7e 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java @@ -34,6 +34,7 @@ import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.transactionlog.TransactionLog; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; +import org.apache.qpid.server.configuration.QueueConfiguration; import org.apache.qpid.server.protocol.AMQMinaProtocolSession; import org.apache.qpid.server.protocol.InternalTestProtocolSession; import org.apache.qpid.framing.ContentHeaderBody; @@ -203,7 +204,7 @@ public class AMQQueueAlertTest extends TestCase // Send messages(no of message to be little more than what can cause a Queue_Depth alert) int messageCount = Math.round(MAX_QUEUE_DEPTH / MAX_MESSAGE_SIZE) + 10; - long totalSize = (messageCount * MAX_MESSAGE_SIZE) >> 10; + long totalSize = (messageCount * MAX_MESSAGE_SIZE); sendMessages(messageCount, MAX_MESSAGE_SIZE); // Check queueDepth. There should be no messages on the queue and as the subscriber is listening @@ -250,26 +251,6 @@ public class AMQQueueAlertTest extends TestCase _queueMBean.clearQueue(); assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth())); } - - public void testAlertConfiguration() throws AMQException - { - // Setup configuration - CompositeConfiguration config = new CompositeConfiguration(); - config.setProperty("maximumMessageSize", new Long(23)); - config.setProperty("maximumMessageCount", new Long(24)); - config.setProperty("maximumQueueDepth", new Long(25)); - config.setProperty("maximumMessageAge", new Long(26)); - - // Create queue and set config - _queue = getNewQueue(); - _queue.configure(config); - - // Check alerts and notifications - Set<NotificationCheck> checks = _queue.getNotificationChecks(); - assertNotNull("No checks found", checks); - assertFalse("Checks should not be empty", checks.isEmpty()); - assertEquals("Wrong number of checks", 4, checks.size()); - } protected IncomingMessage message(final boolean immediate, long size) throws AMQException { diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java new file mode 100644 index 0000000000..0d6c5948b4 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java @@ -0,0 +1,70 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.queue; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; + +public class AMQQueueFactoryPriorityTest extends AMQQueueFactoryTest +{ + private static final int PRIORITIES = 5; + + @Override + public void setUp() + { + super.setUp(); + _arguments.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), PRIORITIES); + } + + @Override + public void testQueueRegistration() + { + try + { + AMQQueue queue = createQueue(); + + assertEquals("Queue not a priorty queue", AMQPriorityQueue.class, queue.getClass()); + + assertEquals("Incorrect number of priorities set", PRIORITIES, ((AMQPriorityQueue) queue).getPriorities()); + } + catch (AMQException e) + { + fail(e.getMessage()); + } + } + + @Override + public void testQueueValuesAfterCreation() + { + try + { + AMQQueue queue = createQueue(); + + assertEquals("MemoryMaximumSize not set correctly:", MAX_SIZE, queue.getMemoryUsageMaximum()); + //NOTE: Priority queue will show 0 as minimum as the minimum value is actually spread between its sub QELs + assertEquals("MemoryMinimumSize not 0 as expected for a priority queue:", 0, queue.getMemoryUsageMinimum()); + } + catch (AMQException e) + { + fail(e.getMessage()); + } + } +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java index 520e49c56a..b8aa8272ba 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java @@ -29,8 +29,11 @@ import org.apache.qpid.AMQException; public class AMQQueueFactoryTest extends TestCase { + final int MAX_SIZE = 50; + QueueRegistry _queueRegistry; VirtualHost _virtualHost; + protected FieldTable _arguments; public void setUp() { @@ -41,6 +44,15 @@ public class AMQQueueFactoryTest extends TestCase _queueRegistry = _virtualHost.getQueueRegistry(); assertEquals("Queues registered on an empty virtualhost", 0, _queueRegistry.getQueues().size()); + + + _arguments = new FieldTable(); + + //Ensure we can call createQueue with a priority int value + _arguments.put(AMQQueueFactory.QPID_POLICY_TYPE, AMQQueueFactory.QPID_FLOW_TO_DISK); + // each message in the QBAAT is around 9-10 bytes each so only give space for half + + _arguments.put(AMQQueueFactory.QPID_MAX_SIZE, MAX_SIZE); } public void tearDown() @@ -50,17 +62,19 @@ public class AMQQueueFactoryTest extends TestCase } - public void testPriorityQueueRegistration() + protected AMQQueue createQueue() throws AMQException { - FieldTable fieldTable = new FieldTable(); - fieldTable.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 5); + return AMQQueueFactory.createAMQQueueImpl(new AMQShortString(this.getName()), false, new AMQShortString("owner"), false, + _virtualHost, _arguments); + } + + public void testQueueRegistration() + { try { - AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testPriorityQueue"), false, new AMQShortString("owner"), false, - _virtualHost, fieldTable); - - assertEquals("Queue not a priorty queue", AMQPriorityQueue.class, queue.getClass()); + AMQQueue queue = createQueue(); + assertEquals("Queue not a simple queue", SimpleAMQQueue.class, queue.getClass()); } catch (AMQException e) { @@ -68,18 +82,20 @@ public class AMQQueueFactoryTest extends TestCase } } - - public void testSimpleQueueRegistration() + public void testQueueValuesAfterCreation() { try { - AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue"), false, new AMQShortString("owner"), false, - _virtualHost, null); - assertEquals("Queue not a simple queue", SimpleAMQQueue.class, queue.getClass()); + AMQQueue queue = createQueue(); + + assertEquals("MemoryMaximumSize not set correctly:", MAX_SIZE, queue.getMemoryUsageMaximum()); + assertEquals("MemoryMinimumSize not defaulted to half maximum:", MAX_SIZE / 2, queue.getMemoryUsageMinimum()); + } catch (AMQException e) { fail(e.getMessage()); } } + } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java index daa8e4beb7..3d189ae6c5 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java @@ -73,7 +73,7 @@ public class AMQQueueMBeanTest extends TestCase sendMessages(messageCount, false); assertTrue(_queueMBean.getMessageCount() == messageCount); assertTrue(_queueMBean.getReceivedMessageCount() == messageCount); - long queueDepth = (messageCount * MESSAGE_SIZE) >> 10; + long queueDepth = (messageCount * MESSAGE_SIZE); assertTrue(_queueMBean.getQueueDepth() == queueDepth); _queueMBean.deleteMessageFromTop(); @@ -94,7 +94,7 @@ public class AMQQueueMBeanTest extends TestCase sendMessages(messageCount, true); assertEquals("", messageCount, _queueMBean.getMessageCount().intValue()); assertTrue(_queueMBean.getReceivedMessageCount() == messageCount); - long queueDepth = (messageCount * MESSAGE_SIZE) >> 10; + long queueDepth = (messageCount * MESSAGE_SIZE); assertTrue(_queueMBean.getQueueDepth() == queueDepth); _queueMBean.deleteMessageFromTop(); @@ -175,7 +175,7 @@ public class AMQQueueMBeanTest extends TestCase assertTrue(_queueMBean.getMaximumMessageCount() == 50000); assertTrue(_queueMBean.getMaximumMessageSize() == 2000); - assertTrue(_queueMBean.getMaximumQueueDepth() == (maxQueueDepth >> 10)); + assertTrue(_queueMBean.getMaximumQueueDepth() == (maxQueueDepth)); assertTrue(_queueMBean.getName().equals("testQueue")); assertTrue(_queueMBean.getOwner().equals("AMQueueMBeanTest")); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java new file mode 100644 index 0000000000..c7cf778d93 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java @@ -0,0 +1,98 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.queue; + +import junit.framework.TestCase; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.pool.ReferenceCountingExecutorService; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class AMQQueueThreadPoolTest extends TestCase +{ + + public void testSimpleAMQQueue() throws AMQException + { + int initialCount = ReferenceCountingExecutorService.getInstance().getReferenceCount(); + VirtualHost test = ApplicationRegistry.getInstance(1).getVirtualHostRegistry().getVirtualHost("test"); + + try + { + SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, + new AMQShortString("owner"), + false, test, null); + + assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown()); + + //This is +2 because: + // 1 - asyncDelivery Thread + // 2 - queue InhalerThread + // 3 - queue PurgerThread + assertEquals("References not increased", initialCount + 3, ReferenceCountingExecutorService.getInstance().getReferenceCount()); + + queue.stop(); + + assertEquals("References not decreased", initialCount, ReferenceCountingExecutorService.getInstance().getReferenceCount()); + } + finally + { + ApplicationRegistry.remove(1); + } + } + + public void testPriorityAMQQueue() throws AMQException + { + int initialCount = ReferenceCountingExecutorService.getInstance().getReferenceCount(); + VirtualHost test = ApplicationRegistry.getInstance(1).getVirtualHostRegistry().getVirtualHost("test"); + + try + { + + FieldTable arguements = new FieldTable(); + int priorities = 10; + arguements.put(AMQQueueFactory.X_QPID_PRIORITIES, priorities); + + SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, + new AMQShortString("owner"), + false, test, arguements); + + assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown()); + + //This is +2 because: + // 1 - asyncDelivery Thread + // 2 + 3 - queue InhalerThread, PurgerThread for the Priority Queue + // priorities * ( Inhaler , Purger) for each priority level + assertEquals("References not increased", (initialCount + 3) + priorities * 2, + ReferenceCountingExecutorService.getInstance().getReferenceCount()); + + queue.stop(); + + assertEquals("References not decreased", initialCount, ReferenceCountingExecutorService.getInstance().getReferenceCount()); + } + finally + { + ApplicationRegistry.remove(1); + } + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java index 98465eda20..9f8d5f9a99 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java @@ -30,14 +30,16 @@ import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.RequiredDeliveryException; +import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.flow.LimitlessCreditManager; import org.apache.qpid.server.flow.Pre0_10CreditManager; import org.apache.qpid.server.ack.UnacknowledgedMessageMap; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.store.TestMemoryMessageStore; import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.store.TestableMemoryMessageStore; +import org.apache.qpid.server.store.MemoryMessageStore; import org.apache.qpid.server.txn.NonTransactionalContext; import org.apache.qpid.server.txn.TransactionalContext; import org.apache.qpid.server.util.NullApplicationRegistry; @@ -57,7 +59,7 @@ public class AckTest extends TestCase private MockProtocolSession _protocolSession; - private TestMemoryMessageStore _messageStore; + private TestableMemoryMessageStore _messageStore; private StoreContext _storeContext = new StoreContext(); @@ -72,14 +74,15 @@ public class AckTest extends TestCase super.setUp(); ApplicationRegistry.initialise(new NullApplicationRegistry(), 1); - _messageStore = new TestMemoryMessageStore(); + VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); + _messageStore = new TestableMemoryMessageStore((MemoryMessageStore)vhost.getTransactionLog()); _protocolSession = new MockProtocolSession(_messageStore); _channel = new AMQChannel(_protocolSession,5, _messageStore /*dont need exchange registry*/); _protocolSession.addChannel(_channel); - _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("myQ"), false, new AMQShortString("guest"), true, ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"), - null); + _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("myQ"), false, new AMQShortString("guest"), + true, vhost, null); } protected void tearDown() @@ -185,7 +188,7 @@ public class AckTest extends TestCase /** * Tests that in no-ack mode no messages are retained */ - public void testPersistentNoAckMode() throws AMQException + public void testPersistentNoAckMode() throws AMQException, InterruptedException { // false arg means no acks expected _subscription = SubscriptionFactoryImpl.INSTANCE.createSubscription(5, _protocolSession, DEFAULT_CONSUMER_TAG, false,null,false, new LimitlessCreditManager()); @@ -194,7 +197,7 @@ public class AckTest extends TestCase UnacknowledgedMessageMap map = _channel.getUnacknowledgedMessageMap(); assertTrue(map.size() == 0); - assertTrue(_messageStore.getMessageMetaDataMap().size() == 0); + assertTrue("Size:" + _messageStore.getMessageMetaDataMap().size(), _messageStore.getMessageMetaDataMap().size() == 0); assertTrue(_messageStore.getContentBodyMap().size() == 0); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java new file mode 100644 index 0000000000..d2cbd46e28 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java @@ -0,0 +1,223 @@ +/* + * + * 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 junit.framework.TestCase; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; +import org.apache.qpid.framing.amqp_8_0.BasicPublishBodyImpl; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.server.transactionlog.TransactionLog; +import org.apache.qpid.server.virtualhost.VirtualHost; + +import java.io.File; + +public class FileQueueBackingStoreTest extends TestCase +{ + QueueBackingStore _backing; + private TransactionLog _transactionLog; + VirtualHost _vhost; + VirtualHostConfiguration _vhostConfig; + FileQueueBackingStoreFactory _factory; + AMQQueue _queue; + + public void setUp() throws Exception + { + _factory = new FileQueueBackingStoreFactory(); + PropertiesConfiguration config = new PropertiesConfiguration(); + config.addProperty("store.class", MemoryMessageStore.class.getName()); + _vhostConfig = new VirtualHostConfiguration(this.getName() + "-Vhost", config); + _vhost = new VirtualHost(_vhostConfig); + _transactionLog = _vhost.getTransactionLog(); + + _factory.configure(_vhost, _vhost.getConfiguration()); + + _queue = new SimpleAMQQueue(new AMQShortString(this.getName()), false, null, false, _vhost); + _backing = _factory.createBacking(_queue); + } + + private void resetBacking(Configuration configuration) throws Exception + { + configuration.addProperty("store.class", MemoryMessageStore.class.getName()); + _vhostConfig = new VirtualHostConfiguration(this.getName() + "-Vhost", configuration); + _vhost = new VirtualHost(_vhostConfig); + _transactionLog = _vhost.getTransactionLog(); + + _factory = new FileQueueBackingStoreFactory(); + + _factory.configure(_vhost, _vhost.getConfiguration()); + + _backing = _factory.createBacking(_queue); + } + + public void testInvalidSetupRootExistsIsFile() throws Exception + { + + File fileAsRoot = File.createTempFile("tmpRoot", ""); + fileAsRoot.deleteOnExit(); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.addProperty(VirtualHostConfiguration.FLOW_TO_DISK_PATH, fileAsRoot.getAbsolutePath()); + + try + { + resetBacking(configuration); + fail("Exception expected to be thrown"); + } + catch (ConfigurationException ce) + { + assertTrue("Expected Exception not thrown, expecting:" + + "Unable to create Temporary Flow to Disk store as specified root is a file:", + ce.getMessage(). + startsWith("Unable to create Temporary Flow to Disk store as specified root is a file:")); + } + + } + + public void testInvalidSetupRootExistsCantWrite() throws Exception + { + + File fileAsRoot = new File("/var/log"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + + configuration.addProperty(VirtualHostConfiguration.FLOW_TO_DISK_PATH, fileAsRoot.getAbsolutePath()); + + try + { + resetBacking(configuration); + fail("Exception expected to be thrown"); + } + catch (ConfigurationException ce) + { + assertEquals("Unable to create Temporary Flow to Disk store. Unable to write to specified root:/var/log", + ce.getMessage()); + } + + } + + public void testEmptyTransientFlowToDisk() throws UnableToFlowMessageException, AMQException + { + AMQMessage original = MessageFactory.getInstance().createMessage(null, false); + + ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID); + chb.bodySize = 0L; + + runTestWithMessage(original, chb); + } + + public void testEmptyPersistentFlowToDisk() throws UnableToFlowMessageException, AMQException + { + + AMQMessage original = MessageFactory.getInstance().createMessage(_transactionLog, true); + ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID); + chb.bodySize = 0L; + ((BasicContentHeaderProperties) chb.properties).setDeliveryMode((byte) 2); + + runTestWithMessage(original, chb); + + } + + public void testNonEmptyTransientFlowToDisk() throws UnableToFlowMessageException, AMQException + { + AMQMessage original = MessageFactory.getInstance().createMessage(null, false); + + ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID); + chb.bodySize = 100L; + + runTestWithMessage(original, chb); + } + + public void testNonEmptyPersistentFlowToDisk() throws UnableToFlowMessageException, AMQException + { + AMQMessage original = MessageFactory.getInstance().createMessage(_transactionLog, true); + ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID); + chb.bodySize = 100L; + ((BasicContentHeaderProperties) chb.properties).setDeliveryMode((byte) 2); + + runTestWithMessage(original, chb); + } + + void runTestWithMessage(AMQMessage original, ContentHeaderBody chb) throws UnableToFlowMessageException, AMQException + { + + // Create message + + original.setPublishAndContentHeaderBody(null, + new MessagePublishInfoImpl(ExchangeDefaults.DIRECT_EXCHANGE_NAME, + false, false, new AMQShortString("routing")), + chb); + if (chb.bodySize > 0) + { + ContentChunk chunk = new MockContentChunk((int) chb.bodySize / 2); + + original.addContentBodyFrame(null, chunk, false); + + chunk = new MockContentChunk((int) chb.bodySize / 2); + + original.addContentBodyFrame(null, chunk, true); + } + + _backing.unload(original); + + AMQMessage fromDisk = _backing.load(original.getMessageId()); + + assertEquals("Message IDs do not match", original.getMessageId(), fromDisk.getMessageId()); + assertEquals("Message arrival times do not match", original.getArrivalTime(), fromDisk.getArrivalTime()); + assertEquals(original.isPersistent(), fromDisk.isPersistent()); + + // Validate the MPI data was restored correctly + MessagePublishInfo originalMPI = original.getMessagePublishInfo(); + MessagePublishInfo fromDiskMPI = fromDisk.getMessagePublishInfo(); + assertEquals("Exchange", originalMPI.getExchange(), fromDiskMPI.getExchange()); + assertEquals(originalMPI.isImmediate(), fromDiskMPI.isImmediate()); + assertEquals(originalMPI.isMandatory(), fromDiskMPI.isMandatory()); + assertEquals(originalMPI.getRoutingKey(), fromDiskMPI.getRoutingKey()); + + // Validate BodyCounts. + int originalBodyCount = original.getBodyCount(); + assertEquals(originalBodyCount, fromDisk.getBodyCount()); + + if (originalBodyCount > 0) + { + for (int index = 0; index < originalBodyCount; index++) + { + ContentChunk originalChunk = original.getContentChunk(index); + ContentChunk fromDiskChunk = fromDisk.getContentChunk(index); + + assertEquals(originalChunk.getSize(), fromDiskChunk.getSize()); + assertEquals(originalChunk.getData(), fromDiskChunk.getData()); + } + } + + } + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java index db0fc56303..a272da88ac 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java @@ -29,16 +29,15 @@ public class MessageFactoryRecoveryTest extends TestCase public void setUp() { _factory = MessageFactory.getInstance(); - + _factory.reset(); } public void test() { - AMQMessage message = _factory.createMessage(null, false); - - _factory.enableRecover(); - Long messasgeID = message.getMessageId(); + Long messasgeID = 1L; + //Create initial message + _factory.createMessage(messasgeID, null); try { @@ -67,7 +66,7 @@ public class MessageFactoryRecoveryTest extends TestCase messasgeID += 100; try { - message = _factory.createMessage(messasgeID, null); + AMQMessage message = _factory.createMessage(messasgeID, null); assertEquals("Factory assigned incorrect id.", messasgeID, message.getMessageId()); } catch (Exception re) @@ -76,7 +75,7 @@ public class MessageFactoryRecoveryTest extends TestCase } // End the reovery process. - _factory.start(); + _factory.recoveryComplete(); //Check we cannot still create by id after ending recovery phase try @@ -96,7 +95,7 @@ public class MessageFactoryRecoveryTest extends TestCase try { - message = _factory.createMessage(null, false); + AMQMessage message = _factory.createMessage(null, false); assertEquals("Factory assigned incorrect id.", messasgeID, message.getMessageId()); } catch (Exception re) diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java index cc6c486e11..11049a7ae3 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java @@ -22,6 +22,15 @@ package org.apache.qpid.server.queue; import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.BasicPublishBody; +import org.apache.qpid.framing.amqp_8_0.BasicPublishBodyImpl; + +import java.util.LinkedList; +import java.util.ArrayList; public class MockAMQMessage extends TransientAMQMessage { @@ -29,6 +38,15 @@ public class MockAMQMessage extends TransientAMQMessage throws AMQException { super(messageId); + _messagePublishInfo = new MessagePublishInfoImpl(null,false,false,null); + BasicContentHeaderProperties properties = new BasicContentHeaderProperties(); + + properties.setMessageId(String.valueOf(messageId)); + properties.setTimestamp(System.currentTimeMillis()); + properties.setDeliveryMode((byte)1); + + _contentHeaderBody = new ContentHeaderBody(properties, BasicPublishBodyImpl.CLASS_ID); + _contentBodies = new ArrayList<ContentChunk>(); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java index 5f1cc81772..ff814840bc 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java @@ -20,15 +20,18 @@ */ package org.apache.qpid.server.queue; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.store.StoreContext; import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.AMQException; -import org.apache.commons.configuration.Configuration; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.registry.ApplicationRegistry; import java.util.List; import java.util.Set; @@ -38,10 +41,20 @@ public class MockAMQQueue implements AMQQueue private boolean _deleted = false; private int _queueCount; private AMQShortString _name; + private VirtualHost _virtualhost; public MockAMQQueue(String name) { - _name = new AMQShortString(name); + _name = new AMQShortString(name); + _virtualhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); + try + { + _virtualhost.getQueueRegistry().registerQueue(this); + } + catch (AMQException e) + { + e.printStackTrace(); + } } public AMQShortString getName() @@ -66,7 +79,7 @@ public class MockAMQQueue implements AMQQueue public VirtualHost getVirtualHost() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return _virtualhost; } public void bind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException @@ -114,6 +127,11 @@ public class MockAMQQueue implements AMQQueue return false; //To change body of implemented methods use File | Settings | File Templates. } + public boolean isFlowed() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + public int getMessageCount() { return 0; //To change body of implemented methods use File | Settings | File Templates. @@ -146,7 +164,7 @@ public class MockAMQQueue implements AMQQueue public int delete() throws AMQException { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; //To change body of implemented methods use File | Settings | File Templates. } public QueueEntry enqueue(StoreContext storeContext, AMQMessage message) throws AMQException @@ -215,6 +233,26 @@ public class MockAMQQueue implements AMQQueue //To change body of implemented methods use File | Settings | File Templates. } + public long getMemoryUsageMaximum() + { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } + + public void setMemoryUsageMaximum(long maximumMemoryUsage) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public long getMemoryUsageMinimum() + { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } + + public void setMemoryUsageMinimum(long minimumMemoryUsage) + { + //To change body of implemented methods use File | Settings | File Templates. + } + public long getMaximumMessageSize() { return 0; //To change body of implemented methods use File | Settings | File Templates. @@ -270,7 +308,6 @@ public class MockAMQQueue implements AMQQueue return 0; //To change body of implemented methods use File | Settings | File Templates. } - @Override public void checkMessageStatus() throws AMQException { //To change body of implemented methods use File | Settings | File Templates. @@ -301,9 +338,9 @@ public class MockAMQQueue implements AMQQueue //To change body of implemented methods use File | Settings | File Templates. } - public void configure(Configuration virtualHostDefaultQueueConfiguration) + public long getMemoryUsageCurrent() { - //To change body of implemented methods use File | Settings | File Templates. + return 0; } public ManagedObject getManagedObject() @@ -315,4 +352,10 @@ public class MockAMQQueue implements AMQQueue { return 0; //To change body of implemented methods use File | Settings | File Templates. } + + public void setMinimumAlertRepeatGap(long value) + { + + } + } 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 ed7b2923e7..92235648ec 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 @@ -20,193 +20,27 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.server.subscription.Subscription; - -public class MockQueueEntry implements QueueEntry +public class MockQueueEntry extends QueueEntryImpl { + static SimpleQueueEntryList _defaultList = new SimpleQueueEntryList(new MockAMQQueue("MockQueueEntry_DefaultQueue")); - private AMQMessage _message; - private boolean _redelivered; - - public boolean acquire() - { - return false; - } - - public boolean acquire(Subscription sub) - { - return false; - } - - public boolean acquiredBySubscription() - { - return false; - } - - public void addStateChangeListener(StateChangeListener listener) - { - - } - - public String debugIdentity() - { - return null; - } - - public boolean delete() - { - return false; - } - - public void dequeue(StoreContext storeContext) throws FailedDequeueException - { - - } - - public void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException - { - - } - - public void dispose(StoreContext storeContext) throws MessageCleanupException - { - - } - - public boolean expired() throws AMQException - { - return false; - } - - public Subscription getDeliveredSubscription() - { - return null; - } - - public boolean getDeliveredToConsumer() - { - return false; - } - - public AMQMessage getMessage() - { - return _message; - } - - public AMQQueue getQueue() - { - return null; - } - - public long getSize() - { - return 0; - } - - public boolean immediateAndNotDelivered() - { - return false; - } - - public boolean isAcquired() - { - return false; - } - - public boolean isDeleted() - { - return false; - } - - - public boolean isQueueDeleted() - { - - return false; - } - - - public boolean isRejectedBy(Subscription subscription) - { - - return false; - } - - - public void reject() - { - - - } - - - public void reject(Subscription subscription) - { - - - } - - - public void release() - { - - - } - - - public boolean removeStateChangeListener(StateChangeListener listener) - { - - return false; - } - - - public void requeue(StoreContext storeContext) throws AMQException - { - - - } - - - public void setDeliveredToSubscription() - { - - - } - - - public void setRedelivered(boolean redelivered) - { - _redelivered = redelivered; - } - - - public int compareTo(QueueEntry o) - { - - return 0; - } - - public void setMessage(AMQMessage msg) + public MockQueueEntry() { - _message = msg; + super(_defaultList); } - public ContentHeaderBody getContentHeaderBody() throws AMQException + public MockQueueEntry(SimpleQueueEntryList queueEntryList, AMQMessage message) { - return _message.getContentHeaderBody(); + super(queueEntryList, message); } - public boolean isPersistent() throws AMQException + public MockQueueEntry(AMQMessage message) { - return _message.isPersistent(); + super(_defaultList, message); } - public boolean isRedelivered() + public MockQueueEntry(AMQMessage message, SimpleAMQQueue queue) { - return _redelivered; + super(new SimpleQueueEntryList(queue) ,message); } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java index fdaf2c309f..7a944a5399 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java @@ -20,18 +20,50 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; +import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl; +import org.apache.qpid.server.RequiredDeliveryException; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.store.TestableMemoryMessageStore; +import org.apache.qpid.server.txn.NonTransactionalContext; +import org.apache.qpid.server.txn.TransactionalContext; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.commons.configuration.PropertiesConfiguration; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; public class PersistentMessageTest extends TransientMessageTest { - private MemoryMessageStore _messageStore; + private TestableMemoryMessageStore _messageStore; + + protected SimpleAMQQueue _queue; + protected AMQShortString _q1name = new AMQShortString("q1name"); + protected AMQShortString _owner = new AMQShortString("owner"); + protected AMQShortString _routingKey = new AMQShortString("routing key"); + private TransactionalContext _messageDeliveryContext; + private static final long MESSAGE_SIZE = 0L; + private List<RequiredDeliveryException> _returnMessages = new LinkedList<RequiredDeliveryException>(); - public void setUp() + public void setUp() throws Exception { - _messageStore = new MemoryMessageStore(); - _messageStore.configure(); + _messageStore = new TestableMemoryMessageStore(); + _storeContext = new StoreContext(); + VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration(PersistentMessageTest.class.getName(), + new PropertiesConfiguration()), + _messageStore); + _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(_q1name, false, _owner, false, vhost, null); + // Create IncomingMessage and nondurable queue + _messageDeliveryContext = new NonTransactionalContext(_messageStore, new StoreContext(), null, _returnMessages); + } @Override @@ -47,4 +79,86 @@ public class PersistentMessageTest extends TransientMessageTest assertTrue(_message.isPersistent()); } + /** + * Tests the returning of a single persistent message to a queue. An immediate message is sent to the queue and + * checked that it bounced. The transactionlog and returnMessasges are then checked to ensure they have the right + * contents. TransactionLog = Empty, returnMessages 1 item. + * + * @throws Exception + */ + public void testImmediateReturnNotInLog() throws Exception + { + MessagePublishInfo info = new MessagePublishInfoImpl(null, true, false, null); + IncomingMessage msg = createMessage(info); + + // Send persistent message + ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>(); + qs.add(_queue); + + // equivalent to amqChannel.routeMessage() + msg.enqueue(qs); + + msg.routingComplete(_messageStore); + + // equivalent to amqChannel.deliverCurrentMessageIfComplete + msg.deliverToQueues(); + + // Check that data has been stored to disk + long messageId = msg.getMessageId(); + checkMessageMetaDataExists(messageId); + + // Check that it was not enqueued + List<AMQQueue> queueList = _messageStore.getMessageReferenceMap(messageId); + assertNull("TransactionLog contains a queue reference for this messageID:" + messageId, queueList); + checkMessageMetaDataRemoved(messageId); + + assertEquals("Return message count not correct", 1, _returnMessages.size()); + } + + protected IncomingMessage createMessage(MessagePublishInfo info) throws AMQException + { + IncomingMessage msg = new IncomingMessage(info, _messageDeliveryContext, + new MockProtocolSession(_messageStore), _messageStore); + + // equivalent to amqChannel.publishContenHeader + ContentHeaderBody contentHeaderBody = new ContentHeaderBody(); + contentHeaderBody.classId = BasicConsumeBodyImpl.CLASS_ID; + // This message has no bodies + contentHeaderBody.bodySize = MESSAGE_SIZE; + contentHeaderBody.properties = new BasicContentHeaderProperties(); + ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2); + + msg.setContentHeaderBody(contentHeaderBody); + msg.setExpiration(); + + return msg; + } + + protected void checkMessageMetaDataExists(long messageId) + { + try + { + _messageStore.getMessageMetaData(_messageDeliveryContext.getStoreContext(), messageId); + } + catch (AMQException amqe) + { + fail("Message MetaData does not exist for message:" + messageId); + } + } + + protected void checkMessageMetaDataRemoved(long messageId) + { + try + { + assertNull("Message MetaData still exists for message:" + messageId, + _messageStore.getMessageMetaData(_messageDeliveryContext.getStoreContext(), messageId)); + assertNull("Message still has values in the reference map:" + messageId, + _messageStore.getMessageReferenceMap(messageId)); + + } + catch (AMQException e) + { + fail("AMQE thrown whilst trying to getMessageMetaData:" + e.getMessage()); + } + } } 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 index f7cd860c22..75b0d0ab60 100644 --- 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 @@ -21,16 +21,22 @@ package org.apache.qpid.server.queue; import junit.framework.TestCase; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; public class QueueEntryImplTest extends TestCase { - /** - * Test the Redelivered state of a QueueEntryImpl - */ + /** Test the Redelivered state of a QueueEntryImpl */ public void testRedelivered() { - QueueEntry entry = new QueueEntryImpl(null, null); + QueueEntry entry = new MockQueueEntry(null); assertFalse("New message should not be redelivered", entry.isRedelivered()); @@ -45,5 +51,186 @@ public class QueueEntryImplTest extends TestCase } + public void testImmediateAndNotDelivered() + { + AMQMessage message = MessageFactory.getInstance().createMessage(null, false); + + MessagePublishInfo mpi = new MessagePublishInfoImpl(null, true, false, null); + int bodySize = 0; + + BasicContentHeaderProperties props = new BasicContentHeaderProperties(); + + props.setAppId("HandleTest"); + + ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); + + try + { + message.setPublishAndContentHeaderBody(null, mpi, chb); + + QueueEntry queueEntry = new MockQueueEntry(message); + + assertTrue("Undelivered Immediate message should still be marked as so", queueEntry.immediateAndNotDelivered()); + + assertFalse("Undelivered Message should not say it is delivered.", queueEntry.getDeliveredToConsumer()); + + queueEntry.setDeliveredToSubscription(); + + assertTrue("Delivered Message should say it is delivered.", queueEntry.getDeliveredToConsumer()); + + assertFalse("Delivered Immediate message now be marked as so", queueEntry.immediateAndNotDelivered()); + } + catch (AMQException e) + { + fail(e.getMessage()); + } + } + + public void testNotImmediateAndNotDelivered() + { + AMQMessage message = MessageFactory.getInstance().createMessage(null, false); + + MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null); + int bodySize = 0; + + BasicContentHeaderProperties props = new BasicContentHeaderProperties(); + + props.setAppId("HandleTest"); + + ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); + + try + { + message.setPublishAndContentHeaderBody(null, mpi, chb); + + QueueEntry queueEntry = new MockQueueEntry(message); + + assertFalse("Undelivered Non-Immediate message should not result in true.", queueEntry.immediateAndNotDelivered()); + + assertFalse("Undelivered Message should not say it is delivered.", queueEntry.getDeliveredToConsumer()); + + queueEntry.setDeliveredToSubscription(); + + assertTrue("Delivered Message should say it is delivered.", queueEntry.getDeliveredToConsumer()); + + assertFalse("Delivered Non-Immediate message not change this return", queueEntry.immediateAndNotDelivered()); + } + catch (AMQException e) + { + fail(e.getMessage()); + } + } + + public void testExpiry() + { + AMQMessage message = MessageFactory.getInstance().createMessage(null, false); + + MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null); + int bodySize = 0; + + BasicContentHeaderProperties props = new BasicContentHeaderProperties(); + + props.setAppId("HandleTest"); + + ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); + + ReentrantLock waitLock = new ReentrantLock(); + Condition wait = waitLock.newCondition(); + try + { + message.setExpiration(System.currentTimeMillis() + 500L); + + message.setPublishAndContentHeaderBody(null, mpi, chb); + + QueueEntry queueEntry = new MockQueueEntry(message); + + assertFalse("New messages should not be expired.", queueEntry.expired()); + + final long MILLIS = 1000000L; + long waitTime = 500 * MILLIS; + + while (waitTime > 0) + { + try + { + waitLock.lock(); + + waitTime = wait.awaitNanos(waitTime); + } + catch (InterruptedException e) + { + //Stop if we are interrupted + fail(e.getMessage()); + } + finally + { + waitLock.unlock(); + } + + } + assertTrue("After a sleep messages should now be expired.", queueEntry.expired()); + + } + catch (AMQException e) + { + fail(e.getMessage()); + } + } + + public void testNoExpiry() + { + AMQMessage message = MessageFactory.getInstance().createMessage(null, false); + + MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null); + int bodySize = 0; + + BasicContentHeaderProperties props = new BasicContentHeaderProperties(); + + props.setAppId("HandleTest"); + + ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); + + ReentrantLock waitLock = new ReentrantLock(); + Condition wait = waitLock.newCondition(); + try + { + + message.setPublishAndContentHeaderBody(null, mpi, chb); + + QueueEntry queueEntry = new MockQueueEntry(message); + + assertFalse("New messages should not be expired.", queueEntry.expired()); + + final long MILLIS = 1000000L; + long waitTime = 10 * MILLIS; + + while (waitTime > 0) + { + try + { + waitLock.lock(); + + waitTime = wait.awaitNanos(waitTime); + } + catch (InterruptedException e) + { + //Stop if we are interrupted + fail(e.getMessage()); + } + finally + { + waitLock.unlock(); + } + + } + + assertFalse("After a sleep messages without an expiry should not expire.", queueEntry.expired()); + + } + catch (AMQException e) + { + fail(e.getMessage()); + } + } } 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 98772e7b61..f39dfe765e 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 @@ -21,6 +21,7 @@ package org.apache.qpid.server.queue; */ import junit.framework.TestCase; +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; @@ -28,13 +29,17 @@ import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; +import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.store.TestTransactionLog; 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.NonTransactionalContext; +import org.apache.qpid.server.txn.TransactionalContext; import org.apache.qpid.server.virtualhost.VirtualHost; import java.util.ArrayList; @@ -45,7 +50,7 @@ public class SimpleAMQQueueTest extends TestCase protected SimpleAMQQueue _queue; protected VirtualHost _virtualHost; - protected TestableMemoryMessageStore _store = new TestableMemoryMessageStore(); + protected TestableMemoryMessageStore _transactionLog = new TestableMemoryMessageStore(); protected AMQShortString _qname = new AMQShortString("qname"); protected AMQShortString _owner = new AMQShortString("owner"); protected AMQShortString _routingKey = new AMQShortString("routing key"); @@ -54,7 +59,7 @@ public class SimpleAMQQueueTest extends TestCase protected FieldTable _arguments = null; MessagePublishInfo info = new MessagePublishInfoImpl(); - private static final long MESSAGE_SIZE = 100; + protected static long MESSAGE_SIZE = 100; @Override protected void setUp() throws Exception @@ -63,7 +68,8 @@ public class SimpleAMQQueueTest extends TestCase //Create Application Registry for test ApplicationRegistry applicationRegistry = (ApplicationRegistry) ApplicationRegistry.getInstance(1); - _virtualHost = new VirtualHost("vhost", _store); + PropertiesConfiguration env = new PropertiesConfiguration(); + _virtualHost = new VirtualHost(new VirtualHostConfiguration(getClass().getSimpleName(), env), _transactionLog); applicationRegistry.getVirtualHostRegistry().registerVirtualHost(_virtualHost); _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(_qname, false, _owner, false, _virtualHost, _arguments); @@ -291,7 +297,7 @@ public class SimpleAMQQueueTest extends TestCase public void testGetLastFiveMessageIds() throws Exception { AMQMessage message = createMessage(); - Long messageIdOffset = message.getMessageId() -1 ; + Long messageIdOffset = message.getMessageId() - 1; for (int i = 0; i < 10; i++) { // Put message on queue @@ -313,8 +319,8 @@ public class SimpleAMQQueueTest extends TestCase public void testEnqueueDequeueOfPersistentMessageToNonDurableQueue() throws AMQException { // Create IncomingMessage and nondurable queue - NonTransactionalContext txnContext = new NonTransactionalContext(_store, null, null, null); - IncomingMessage msg = new IncomingMessage(info, txnContext, null, _store); + NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null); + IncomingMessage msg = new IncomingMessage(info, txnContext, new MockProtocolSession(_transactionLog), _transactionLog); ContentHeaderBody contentHeaderBody = new ContentHeaderBody(); contentHeaderBody.properties = new BasicContentHeaderProperties(); @@ -328,31 +334,184 @@ public class SimpleAMQQueueTest extends TestCase // Send persistent message qs.add(_queue); msg.enqueue(qs); - msg.routingComplete(_store); + msg.routingComplete(_transactionLog); - - _store.storeMessageMetaData(null, messageId, new MessageMetaData(info, contentHeaderBody, 1)); + _transactionLog.storeMessageMetaData(null, messageId, new MessageMetaData(info, contentHeaderBody, 1)); // Check that it is enqueued - AMQQueue data = _store.getMessages().get(messageId); + List<AMQQueue> data = _transactionLog.getMessageReferenceMap(messageId); assertNotNull(data); // Dequeue message - MockQueueEntry entry = new MockQueueEntry(); - ContentHeaderBody header = new ContentHeaderBody(); header.bodySize = MESSAGE_SIZE; - AMQMessage message = new MockPersistentAMQMessage(msg.getMessageId(), _store); + AMQMessage message = new MockPersistentAMQMessage(msg.getMessageId(), _transactionLog); message.setPublishAndContentHeaderBody(new StoreContext(), info, header); - entry.setMessage(message); - _queue.dequeue(null, entry); + MockQueueEntry entry = new MockQueueEntry(message, _queue); + entry.getQueueEntryList().add(message); + entry.acquire(); + entry.dequeue(null); // Check that it is dequeued - data = _store.getMessages().get(messageId); + data = _transactionLog.getMessageReferenceMap(messageId); assertNull(data); } + public void testMessagesFlowToDisk() throws AMQException, InterruptedException + { + // Create IncomingMessage and nondurable queue + NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null); + + MESSAGE_SIZE = 1; + long MEMORY_MAX = 500; + int MESSAGE_COUNT = (int) MEMORY_MAX * 2; + //Set the Memory Usage to be very low + _queue.setMemoryUsageMaximum(MEMORY_MAX); + + for (int msgCount = 0; msgCount < MESSAGE_COUNT / 2; msgCount++) + { + sendMessage(txnContext); + } + + //Check that we can hold 10 messages without flowing + assertEquals(MESSAGE_COUNT / 2, _queue.getMessageCount()); + assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is flowed.", !_queue.isFlowed()); + + // Send anothe and ensure we are flowed + sendMessage(txnContext); + assertEquals(MESSAGE_COUNT / 2 + 1, _queue.getMessageCount()); + assertEquals(MESSAGE_COUNT / 2, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is not flowed.", _queue.isFlowed()); + + //send another 99 so there are 200msgs in total on the queue + for (int msgCount = 0; msgCount < (MESSAGE_COUNT / 2) - 1; msgCount++) + { + sendMessage(txnContext); + + long usage = _queue.getMemoryUsageCurrent(); + assertTrue("Queue has gone over quota:" + usage, + usage <= _queue.getMemoryUsageMaximum()); + + assertTrue("Queue has a negative quota:" + usage, usage > 0); + + } + assertEquals(MESSAGE_COUNT, _queue.getMessageCount()); + assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is not flowed.", _queue.isFlowed()); + + _queue.registerSubscription(_subscription, false); + + int slept = 0; + while (_subscription.getQueueEntries().size() != MESSAGE_COUNT && slept < 10) + { + Thread.sleep(500); + slept++; + } + + //Ensure the messages are retreived + assertEquals("Not all messages were received, slept:" + slept / 2 + "s", MESSAGE_COUNT, _subscription.getQueueEntries().size()); + + //Check the queue is still within it's limits. + long current = _queue.getMemoryUsageCurrent(); + assertTrue("Queue has gone over quota:" + current + "/" + _queue.getMemoryUsageMaximum(), + current <= _queue.getMemoryUsageMaximum()); + + assertTrue("Queue has a negative quota:" + _queue.getMemoryUsageCurrent(), _queue.getMemoryUsageCurrent() >= 0); + + for (int index = 0; index < MESSAGE_COUNT; index++) + { + // Ensure that we have received the messages and it wasn't flushed to disk before we received it. + AMQMessage message = _subscription.getMessages().get(index); + assertNotNull("Message:" + message.debugIdentity() + " was null.", message); + } + } + + public void testMessagesFlowToDiskPurger() throws AMQException, InterruptedException + { + // Create IncomingMessage and nondurable queue + NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null); + + MESSAGE_SIZE = 1; + /** Set to larger than the purge batch size. Default 100. + * @see FlowableBaseQueueEntryList.BATCH_PROCESS_COUNT */ + long MEMORY_MAX = 500; + int MESSAGE_COUNT = (int) MEMORY_MAX; + //Set the Memory Usage to be very low + _queue.setMemoryUsageMaximum(MEMORY_MAX); + + for (int msgCount = 0; msgCount < MESSAGE_COUNT; msgCount++) + { + sendMessage(txnContext); + } + + //Check that we can hold all messages without flowing + assertEquals(MESSAGE_COUNT, _queue.getMessageCount()); + assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is flowed.", !_queue.isFlowed()); + + // Send anothe and ensure we are flowed + sendMessage(txnContext); + assertEquals(MESSAGE_COUNT + 1, _queue.getMessageCount()); + assertEquals(MESSAGE_COUNT, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is not flowed.", _queue.isFlowed()); + + _queue.setMemoryUsageMaximum(0L); + + //Give the purger time to work maximum of 1s + int slept = 0; + while (_queue.getMemoryUsageCurrent() > 0 && slept < 5) + { + Thread.yield(); + Thread.sleep(200); + slept++; + } + + assertEquals(MESSAGE_COUNT + 1, _queue.getMessageCount()); + assertEquals(0L, _queue.getMemoryUsageCurrent()); + assertTrue("Queue is not flowed.", _queue.isFlowed()); + + } + + protected void sendMessage(TransactionalContext txnContext) throws AMQException + { + sendMessage(txnContext, 5); + } + + protected void sendMessage(TransactionalContext txnContext, int priority) throws AMQException + { + IncomingMessage msg = new IncomingMessage(info, txnContext, new MockProtocolSession(_transactionLog), _transactionLog); + + ContentHeaderBody contentHeaderBody = new ContentHeaderBody(); + contentHeaderBody.classId = BasicConsumeBodyImpl.CLASS_ID; + contentHeaderBody.bodySize = MESSAGE_SIZE; + contentHeaderBody.properties = new BasicContentHeaderProperties(); + ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2); + ((BasicContentHeaderProperties) contentHeaderBody.properties).setPriority((byte) priority); + msg.setContentHeaderBody(contentHeaderBody); + + long messageId = msg.getMessageId(); + + ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>(); + + // Send persistent 10 messages + + qs.add(_queue); + msg.enqueue(qs); + + msg.routingComplete(_transactionLog); + + msg.addContentBodyFrame(new MockContentChunk(1)); + + msg.deliverToQueues(); + + //Check message was correctly enqueued + List<AMQQueue> data = _transactionLog.getMessageReferenceMap(messageId); + assertNotNull(data); + } + + // FIXME: move this to somewhere useful private static AMQMessage createMessage(final MessagePublishInfo publishBody) { @@ -378,7 +537,7 @@ public class SimpleAMQQueueTest extends TestCase public AMQMessage createMessage() throws AMQException { - AMQMessage message = new TestMessage(info); + AMQMessage message = new TestMessage(info, _transactionLog); ContentHeaderBody header = new ContentHeaderBody(); header.bodySize = MESSAGE_SIZE; @@ -394,29 +553,20 @@ public class SimpleAMQQueueTest extends TestCase public class TestMessage extends TransientAMQMessage { private final long _tag; - private int _count; + private TestTransactionLog _transactionLog; - TestMessage(MessagePublishInfo publishBody) + TestMessage(MessagePublishInfo publishBody, TestTransactionLog transactionLog) throws AMQException { super(SimpleAMQQueueTest.createMessage(publishBody)); _tag = getMessageId(); - } - - public boolean incrementReference() - { - _count++; - return true; - } - - public void decrementReference(StoreContext context) - { - _count--; + _transactionLog = transactionLog; } void assertCountEquals(int expected) { - assertEquals("Wrong count for message with tag " + _tag, expected, _count); + assertEquals("Wrong count for message with tag " + _tag, expected, + _transactionLog.getMessageReferenceMap(_messageId).size()); } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java deleted file mode 100644 index f45d887dec..0000000000 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.queue; - -import junit.framework.TestCase; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.pool.ReferenceCountingExecutorService; -import org.apache.qpid.server.virtualhost.VirtualHost; - -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.AMQException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SimpleAMQQueueThreadPoolTest extends TestCase -{ - - public void test() throws AMQException - { - assertEquals("References exist before start!", 0, ReferenceCountingExecutorService.getInstance().getReferenceCount()); - VirtualHost test = ApplicationRegistry.getInstance(1).getVirtualHostRegistry().getVirtualHost("test"); - - try - { - SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, - new AMQShortString("owner"), - false, test, null); - - assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown()); - - queue.stop(); - - assertEquals("References still exist", 0, ReferenceCountingExecutorService.getInstance().getReferenceCount()); - - assertTrue("Stop did not clean up.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown()); - } - finally - { - ApplicationRegistry.remove(1); - } - } -} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java index 16d1ab60f3..6fd153f398 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java @@ -287,180 +287,5 @@ public class TransientMessageTest extends TestCase assertFalse(_message.isPersistent()); } - public void testImmediateAndNotDelivered() - { - _message = newMessage(); - - MessagePublishInfo mpi = new MessagePublishInfoImpl(null, true, false, null); - int bodySize = 0; - - BasicContentHeaderProperties props = new BasicContentHeaderProperties(); - - props.setAppId("HandleTest"); - - ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); - - try - { - _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb); - - assertTrue("Undelivered Immediate message should still be marked as so", _message.immediateAndNotDelivered()); - - assertFalse("Undelivered Message should not say it is delivered.", _message.getDeliveredToConsumer()); - - _message.setDeliveredToConsumer(); - - assertTrue("Delivered Message should say it is delivered.", _message.getDeliveredToConsumer()); - - assertFalse("Delivered Immediate message now be marked as so", _message.immediateAndNotDelivered()); - } - catch (AMQException e) - { - fail(e.getMessage()); - } - } - - public void testNotImmediateAndNotDelivered() - { - _message = newMessage(); - - MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null); - int bodySize = 0; - - BasicContentHeaderProperties props = new BasicContentHeaderProperties(); - - props.setAppId("HandleTest"); - - ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); - - try - { - _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb); - - assertFalse("Undelivered Non-Immediate message should not result in true.", _message.immediateAndNotDelivered()); - - assertFalse("Undelivered Message should not say it is delivered.", _message.getDeliveredToConsumer()); - - _message.setDeliveredToConsumer(); - - assertTrue("Delivered Message should say it is delivered.", _message.getDeliveredToConsumer()); - - assertFalse("Delivered Non-Immediate message not change this return", _message.immediateAndNotDelivered()); - } - catch (AMQException e) - { - fail(e.getMessage()); - } - } - - public void testExpiry() - { - _message = newMessage(); - - MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null); - int bodySize = 0; - - BasicContentHeaderProperties props = new BasicContentHeaderProperties(); - - props.setAppId("HandleTest"); - - ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); - - ReentrantLock waitLock = new ReentrantLock(); - Condition wait = waitLock.newCondition(); - try - { - _message.setExpiration(System.currentTimeMillis() + 10L); - - _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb); - - assertFalse("New messages should not be expired.", _message.expired()); - - final long MILLIS =1000000L; - long waitTime = 20 * MILLIS; - - while (waitTime > 0) - { - try - { - waitLock.lock(); - - waitTime = wait.awaitNanos(waitTime); - } - catch (InterruptedException e) - { - //Stop if we are interrupted - fail(e.getMessage()); - } - finally - { - waitLock.unlock(); - } - - } - - assertTrue("After a sleep messages should now be expired.", _message.expired()); - - } - catch (AMQException e) - { - fail(e.getMessage()); - } - } - - - public void testNoExpiry() - { - _message = newMessage(); - - MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null); - int bodySize = 0; - - BasicContentHeaderProperties props = new BasicContentHeaderProperties(); - - props.setAppId("HandleTest"); - - ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize); - - ReentrantLock waitLock = new ReentrantLock(); - Condition wait = waitLock.newCondition(); - try - { - - _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb); - - assertFalse("New messages should not be expired.", _message.expired()); - - final long MILLIS =1000000L; - long waitTime = 10 * MILLIS; - - while (waitTime > 0) - { - try - { - waitLock.lock(); - - waitTime = wait.awaitNanos(waitTime); - } - catch (InterruptedException e) - { - //Stop if we are interrupted - fail(e.getMessage()); - } - finally - { - waitLock.unlock(); - } - - } - - assertFalse("After a sleep messages without an expiry should not expire.", _message.expired()); - - } - catch (AMQException e) - { - fail(e.getMessage()); - } - } - + } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java index 03fcfc31e9..939e3436a5 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java @@ -39,7 +39,7 @@ public class ApplicationRegistryShutdownTest extends TestCase ApplicationRegistry _registry; - public void setUp() + public void setUp() throws Exception { _registry = new TestApplicationRegistry(); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java index d12a0b1f1b..abcd9855d9 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java @@ -27,8 +27,11 @@ import java.io.FileWriter; import junit.framework.TestCase; import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.XMLConfiguration; +import org.apache.qpid.server.configuration.SecurityConfiguration; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.plugins.MockPluginManager; import org.apache.qpid.server.plugins.PluginManager; @@ -37,13 +40,14 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MockAMQQueue; import org.apache.qpid.server.queue.MockProtocolSession; import org.apache.qpid.server.store.TestableMemoryMessageStore; +import org.apache.qpid.server.registry.ApplicationRegistry; public class ACLManagerTest extends TestCase { private ACLManager _authzManager; private AMQProtocolSession _session; - private XMLConfiguration _conf; + private SecurityConfiguration _conf; private PluginManager _pluginManager; @Override @@ -52,10 +56,10 @@ public class ACLManagerTest extends TestCase File tmpFile = File.createTempFile(getClass().getName(), "testconfig"); tmpFile.deleteOnExit(); BufferedWriter out = new BufferedWriter(new FileWriter(tmpFile)); - out.write("<broker><security><queueDenier>notyet</queueDenier><exchangeDenier>yes</exchangeDenier></security></broker>"); + out.write("<security><queueDenier>notyet</queueDenier><exchangeDenier>yes</exchangeDenier></security>"); out.close(); - _conf = new XMLConfiguration(tmpFile); + _conf = new SecurityConfiguration(new XMLConfiguration(tmpFile)); // Create ACLManager @@ -64,6 +68,12 @@ public class ACLManagerTest extends TestCase _session = new MockProtocolSession(new TestableMemoryMessageStore()); } + + public void tearDown() throws Exception + { + //Ensure we close the registry that the MockAMQQueue will create + ApplicationRegistry.getInstance().close(); + } public void testACLManagerConfigurationPluginManager() throws Exception { @@ -77,7 +87,7 @@ public class ACLManagerTest extends TestCase assertTrue(_authzManager.authorisePurge(_session, queue)); } - public void testACLManagerConfigurationPluginManagerACLPlugin() + public void testACLManagerConfigurationPluginManagerACLPlugin() throws ConfigurationException { _authzManager = new ACLManager(_conf, _pluginManager, ExchangeDenier.FACTORY); @@ -85,13 +95,12 @@ public class ACLManagerTest extends TestCase assertFalse(_authzManager.authoriseDelete(_session, exchange)); } - public void testConfigurePlugins() + public void testConfigurePlugins() throws ConfigurationException { Configuration hostConfig = new PropertiesConfiguration(); - hostConfig.setProperty("security.queueDenier", "thisoneneither"); - _authzManager.configureHostPlugins(hostConfig); + hostConfig.setProperty("queueDenier", "thisoneneither"); + _authzManager.configureHostPlugins(new SecurityConfiguration(hostConfig)); AMQQueue queue = new MockAMQQueue("thisoneneither"); assertFalse(_authzManager.authoriseDelete(_session, queue)); } - } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java index bcbd83cde3..56a3783126 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java @@ -23,11 +23,13 @@ package org.apache.qpid.server.security.access; import junit.framework.TestCase; +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.amqp_0_9.ExchangeDeclareBodyImpl; import org.apache.qpid.framing.amqp_0_9.QueueDeclareBodyImpl; import org.apache.qpid.framing.amqp_8_0.QueueBindBodyImpl; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; @@ -50,7 +52,6 @@ public class PrincipalPermissionsTest extends TestCase private boolean _nowait = false; private boolean _passive = false; private boolean _durable = false; - private boolean _exclusive = false; private boolean _autoDelete = false; private AMQShortString _exchangeType = new AMQShortString("direct"); private boolean _internal = false; @@ -67,7 +68,8 @@ public class PrincipalPermissionsTest extends TestCase _perms = new PrincipalPermissions(_user); try { - _virtualHost = new VirtualHost("localhost", new SkeletonMessageStore()); + PropertiesConfiguration env = new PropertiesConfiguration(); + _virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env)); _exchange = DirectExchange.TYPE.newInstance(_virtualHost, _exchangeName, _durable, _ticket, _autoDelete); _queue = AMQQueueFactory.createAMQQueueImpl(_queueName, false, _owner , false, _virtualHost, _arguments); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java index f3c07d9eb2..958ee35476 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java @@ -21,103 +21,213 @@ package org.apache.qpid.server.security.access.management; +import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.management.MBeanInvocationHandlerImpl; +import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; import junit.framework.TestCase; +/* Note: The main purpose is to test the jmx access rights file manipulation + * within AMQUserManagementMBean. The Principal Databases are tested by their own tests, + * this test just exercises their usage in AMQUserManagementMBean. + */ public class AMQUserManagementMBeanTest extends TestCase { - private Base64MD5PasswordFilePrincipalDatabase _database; + private PlainPasswordFilePrincipalDatabase _database; private AMQUserManagementMBean _amqumMBean; + + private File _passwordFile; + private File _accessFile; - private static final String _QPID_HOME = System.getProperty("QPID_HOME"); - - private static final String USERNAME = "testuser"; - private static final String PASSWORD = "password"; - private static final String JMXRIGHTS = "admin"; - private static final String TEMP_PASSWORD_FILE_NAME = "tempPasswordFile.tmp"; - private static final String TEMP_JMXACCESS_FILE_NAME = "tempJMXAccessFile.tmp"; + private static final String TEST_USERNAME = "testuser"; + private static final String TEST_PASSWORD = "password"; @Override protected void setUp() throws Exception { - assertNotNull("QPID_HOME not set", _QPID_HOME); - - _database = new Base64MD5PasswordFilePrincipalDatabase(); + _database = new PlainPasswordFilePrincipalDatabase(); _amqumMBean = new AMQUserManagementMBean(); + loadFreshTestPasswordFile(); + loadFreshTestAccessFile(); } @Override protected void tearDown() throws Exception { - File testFile = new File(_QPID_HOME + File.separator + TEMP_JMXACCESS_FILE_NAME + ".tmp"); - if (testFile.exists()) + _passwordFile.delete(); + _accessFile.delete(); + } + + public void testDeleteUser() + { + loadFreshTestPasswordFile(); + loadFreshTestAccessFile(); + + //try deleting a non existant user + assertFalse(_amqumMBean.deleteUser("made.up.username")); + + assertTrue(_amqumMBean.deleteUser(TEST_USERNAME)); + } + + public void testDeleteUserIsSavedToAccessFile() + { + loadFreshTestPasswordFile(); + loadFreshTestAccessFile(); + + assertTrue(_amqumMBean.deleteUser(TEST_USERNAME)); + + //check the access rights were actually deleted from the file + try{ + BufferedReader reader = new BufferedReader(new FileReader(_accessFile)); + + //check the 'generated by' comment line is present + assertTrue("File has no content", reader.ready()); + assertTrue("'Generated by' comment line was missing",reader.readLine().contains("Generated by " + + "AMQUserManagementMBean Console : Last edited by user:")); + + //there should also be a modified date/time comment line + assertTrue("File has no modified date/time comment line", reader.ready()); + assertTrue("Modification date/time comment line was missing",reader.readLine().startsWith("#")); + + //the access file should not contain any further data now as we just deleted the only user + assertFalse("User access data was present when it should have been deleted", reader.ready()); + } + catch (IOException e) { - testFile.delete(); + fail("Unable to valdate file contents due to:" + e.getMessage()); } + + } + + public void testSetRights() + { + loadFreshTestPasswordFile(); + loadFreshTestAccessFile(); + + assertFalse(_amqumMBean.setRights("made.up.username", true, false, false)); + + assertTrue(_amqumMBean.setRights(TEST_USERNAME, true, false, false)); + assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, true, false)); + assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, false, true)); + } + + public void testSetRightsIsSavedToAccessFile() + { + loadFreshTestPasswordFile(); + loadFreshTestAccessFile(); + + assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, false, true)); + + //check the access rights were actually updated in the file + try{ + BufferedReader reader = new BufferedReader(new FileReader(_accessFile)); + + //check the 'generated by' comment line is present + assertTrue("File has no content", reader.ready()); + assertTrue("'Generated by' comment line was missing",reader.readLine().contains("Generated by " + + "AMQUserManagementMBean Console : Last edited by user:")); - testFile = new File(_QPID_HOME + File.separator + TEMP_JMXACCESS_FILE_NAME + ".old"); - if (testFile.exists()) + //there should also be a modified date/time comment line + assertTrue("File has no modified date/time comment line", reader.ready()); + assertTrue("Modification date/time comment line was missing",reader.readLine().startsWith("#")); + + //the access file should not contain any further data now as we just deleted the only user + assertTrue("User access data was not updated in the access file", + reader.readLine().equals(TEST_USERNAME + "=" + MBeanInvocationHandlerImpl.ADMIN)); + + //the access file should not contain any further data now as we just deleted the only user + assertFalse("Additional user access data was present when there should be no more", reader.ready()); + } + catch (IOException e) { - testFile.delete(); + fail("Unable to valdate file contents due to:" + e.getMessage()); } + } - testFile = new File(_QPID_HOME + File.separator + TEMP_PASSWORD_FILE_NAME + ".tmp"); - if (testFile.exists()) + public void testMBeanVersion() + { + try { - testFile.delete(); + ObjectName name = _amqumMBean.getObjectName(); + assertEquals(AMQUserManagementMBean.VERSION, Integer.parseInt(name.getKeyProperty("version"))); } - - testFile = new File(_QPID_HOME + File.separator + TEMP_PASSWORD_FILE_NAME + ".old"); - if (testFile.exists()) + catch (MalformedObjectNameException e) { - testFile.delete(); + fail(e.getMessage()); } } - public void testDeleteUser() + public void testSetAccessFileWithMissingFile() { - loadTestPasswordFile(); - loadTestAccessFile(); - - boolean deleted = false; + try + { + _amqumMBean.setAccessFile("made.up.filename"); + } + catch (IOException e) + { + fail("Should not have been an IOE." + e.getMessage()); + } + catch (ConfigurationException e) + { + assertTrue(e.getMessage(), e.getMessage().endsWith("does not exist")); + } + } + public void testSetAccessFileWithReadOnlyFile() + { + File testFile = null; try { - deleted = _amqumMBean.deleteUser(USERNAME); + testFile = File.createTempFile(this.getClass().getName(),".access.readonly"); + BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(testFile, false)); + passwordWriter.write(TEST_USERNAME + ":" + TEST_PASSWORD); + passwordWriter.newLine(); + passwordWriter.flush(); + passwordWriter.close(); + + testFile.setReadOnly(); + _amqumMBean.setAccessFile(testFile.getPath()); } - catch(Exception e){ - fail("Unable to delete user: " + e.getMessage()); + catch (IOException e) + { + fail("Access file was not created." + e.getMessage()); + } + catch (ConfigurationException e) + { + fail("There should not have been a configuration exception." + e.getMessage()); } - assertTrue(deleted); + testFile.delete(); } - - + // ============================ Utility methods ========================= - private void loadTestPasswordFile() + private void loadFreshTestPasswordFile() { try { - File tempPasswordFile = new File(_QPID_HOME + File.separator + TEMP_PASSWORD_FILE_NAME); - if (tempPasswordFile.exists()) + if(_passwordFile == null) { - tempPasswordFile.delete(); + _passwordFile = File.createTempFile(this.getClass().getName(),".password"); } - tempPasswordFile.deleteOnExit(); - BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(tempPasswordFile)); - passwordWriter.write(USERNAME + ":" + PASSWORD); + BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(_passwordFile, false)); + passwordWriter.write(TEST_USERNAME + ":" + TEST_PASSWORD); passwordWriter.newLine(); passwordWriter.flush(); - - _database.setPasswordFile(tempPasswordFile.toString()); + passwordWriter.close(); + _database.setPasswordFile(_passwordFile.toString()); _amqumMBean.setPrincipalDatabase(_database); } catch (IOException e) @@ -126,27 +236,36 @@ public class AMQUserManagementMBeanTest extends TestCase } } - private void loadTestAccessFile() + private void loadFreshTestAccessFile() { try { - File tempAccessFile = new File(_QPID_HOME + File.separator + TEMP_JMXACCESS_FILE_NAME); - if (tempAccessFile.exists()) + if(_accessFile == null) { - tempAccessFile.delete(); + _accessFile = File.createTempFile(this.getClass().getName(),".access"); } - tempAccessFile.deleteOnExit(); - - BufferedWriter accessWriter = new BufferedWriter(new FileWriter(tempAccessFile)); - accessWriter.write(USERNAME + "=" + JMXRIGHTS); + + BufferedWriter accessWriter = new BufferedWriter(new FileWriter(_accessFile,false)); + accessWriter.write("#Last Updated By comment"); + accessWriter.newLine(); + accessWriter.write("#Date/time comment"); + accessWriter.newLine(); + accessWriter.write(TEST_USERNAME + "=" + MBeanInvocationHandlerImpl.READONLY); accessWriter.newLine(); accessWriter.flush(); + accessWriter.close(); + } + catch (IOException e) + { + fail("Unable to create test access file: " + e.getMessage()); + } - _amqumMBean.setAccessFile(tempAccessFile.toString()); + try{ + _amqumMBean.setAccessFile(_accessFile.toString()); } catch (Exception e) { - fail("Unable to create test access file: " + e.getMessage()); + fail("Unable to set access file: " + e.getMessage()); } } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java index 8028362979..ff1fb8c97d 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java @@ -30,8 +30,10 @@ import java.net.InetSocketAddress; import junit.framework.TestCase; import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.XMLConfiguration; import org.apache.qpid.codec.AMQCodecFactory; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.protocol.AMQMinaProtocolSession; import org.apache.qpid.server.protocol.TestIoSession; import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult; @@ -87,7 +89,8 @@ public class FirewallPluginTest extends TestCase public void setUp() throws Exception { _store = new TestableMemoryMessageStore(); - _virtualHost = new VirtualHost("vhost", _store); + PropertiesConfiguration env = new PropertiesConfiguration(); + _virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env)); TestIoSession iosession = new TestIoSession(); iosession.setAddress("127.0.0.1"); VirtualHostRegistry virtualHostRegistry = null; diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java index b5034d9f5d..413b974986 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java @@ -22,8 +22,10 @@ package org.apache.qpid.server.security.auth.database; import junit.framework.TestCase; +import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; +import org.apache.commons.codec.binary.Base64; import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import java.io.BufferedReader; @@ -33,7 +35,9 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.security.Principal; +import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; @@ -41,12 +45,38 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase { private static final String TEST_COMMENT = "# Test Comment"; - private String USERNAME = "testUser"; - private String _username = this.getClass().getName()+"username"; - private char[] _password = "password".toCharArray(); - private Principal _principal = new UsernamePrincipal(_username); + + private static final String USERNAME = "testUser"; + private static final String PASSWORD = "guest"; + private static final String PASSWORD_B64MD5HASHED = "CE4DQ6BIb/BVMN9scFyLtA=="; + private static char[] PASSWORD_MD5_CHARS; + private static final String PRINCIPAL_USERNAME = "testUserPrincipal"; + private static final Principal PRINCIPAL = new UsernamePrincipal(PRINCIPAL_USERNAME); private Base64MD5PasswordFilePrincipalDatabase _database; private File _pwdFile; + + static + { + try + { + Base64 b64 = new Base64(); + byte[] md5passBytes = PASSWORD_B64MD5HASHED.getBytes(Base64MD5PasswordFilePrincipalDatabase.DEFAULT_ENCODING); + byte[] decoded = b64.decode(md5passBytes); + + PASSWORD_MD5_CHARS = new char[decoded.length]; + + int index = 0; + for (byte c : decoded) + { + PASSWORD_MD5_CHARS[index++] = (char) c; + } + } + catch (UnsupportedEncodingException e) + { + fail("Unable to perform B64 decode to get the md5 char[] password"); + } + } + public void setUp() throws Exception { @@ -111,7 +141,56 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase loadPasswordFile(testFile); - final String CREATED_PASSWORD = "createdPassword"; + + Principal principal = new Principal() + { + public String getName() + { + return USERNAME; + } + }; + + assertTrue("New user not created.", _database.createPrincipal(principal, PASSWORD.toCharArray())); + + PasswordCallback callback = new PasswordCallback("prompt",false); + try + { + _database.setPassword(principal, callback); + } + catch (AccountNotFoundException e) + { + fail("user account did not exist"); + } + assertTrue("Password returned was incorrect.", Arrays.equals(PASSWORD_MD5_CHARS, callback.getPassword())); + + loadPasswordFile(testFile); + + try + { + _database.setPassword(principal, callback); + } + catch (AccountNotFoundException e) + { + fail("user account did not exist"); + } + assertTrue("Password returned was incorrect.", Arrays.equals(PASSWORD_MD5_CHARS, callback.getPassword())); + + assertNotNull("Created User was not saved", _database.getUser(USERNAME)); + + assertFalse("Duplicate user created.", _database.createPrincipal(principal, PASSWORD.toCharArray())); + + testFile.delete(); + } + + public void testCreatePrincipalIsSavedToFile() + { + + File testFile = createPasswordFile(1, 0); + + loadPasswordFile(testFile); + + final String CREATED_PASSWORD = "guest"; + final String CREATED_B64MD5HASHED_PASSWORD = "CE4DQ6BIb/BVMN9scFyLtA=="; final String CREATED_USERNAME = "createdUser"; Principal principal = new Principal() @@ -122,16 +201,37 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase } }; - assertTrue("New user not created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray())); + _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray()); - loadPasswordFile(testFile); + try + { + BufferedReader reader = new BufferedReader(new FileReader(testFile)); + + assertTrue("File has no content", reader.ready()); + + assertEquals("Comment line has been corrupted.", TEST_COMMENT, reader.readLine()); - assertNotNull("Created User was not saved", _database.getUser(CREATED_USERNAME)); + assertTrue("File is missing user data.", reader.ready()); - assertFalse("Duplicate user created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray())); + String userLine = reader.readLine(); + + String[] result = Pattern.compile(":").split(userLine); + assertEquals("User line not complete '" + userLine + "'", 2, result.length); + + assertEquals("Username not correct,", CREATED_USERNAME, result[0]); + assertEquals("Password not correct,", CREATED_B64MD5HASHED_PASSWORD, result[1]); + + assertFalse("File has more content", reader.ready()); + + } + catch (IOException e) + { + fail("Unable to valdate file contents due to:" + e.getMessage()); + } testFile.delete(); } + public void testDeletePrincipal() { @@ -228,8 +328,8 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase assertNotNull(testUser); - String NEW_PASSWORD = "NewPassword"; - String NEW_PASSWORD_HASH = "TmV3UGFzc3dvcmQ="; + String NEW_PASSWORD = "guest"; + String NEW_PASSWORD_HASH = "CE4DQ6BIb/BVMN9scFyLtA=="; try { _database.updatePassword(testUser, NEW_PASSWORD.toCharArray()); @@ -268,7 +368,7 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase testFile.delete(); } - public void testSetPasswordWithMissingFile() + public void testSetPasswordFileWithMissingFile() { try { @@ -285,7 +385,7 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase } - public void testSetPasswordWithReadOnlyFile() + public void testSetPasswordFileWithReadOnlyFile() { File testFile = createPasswordFile(0, 0); @@ -310,28 +410,38 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase public void testCreateUserPrincipal() throws IOException { - _database.createPrincipal(_principal, _password); - Principal newPrincipal = _database.getUser(_username); + _database.createPrincipal(PRINCIPAL, PASSWORD.toCharArray()); + Principal newPrincipal = _database.getUser(PRINCIPAL_USERNAME); assertNotNull(newPrincipal); - assertEquals(_principal.getName(), newPrincipal.getName()); + assertEquals(PRINCIPAL.getName(), newPrincipal.getName()); } public void testVerifyPassword() throws IOException, AccountNotFoundException { testCreateUserPrincipal(); //assertFalse(_pwdDB.verifyPassword(_username, null)); - assertFalse(_database.verifyPassword(_username, new char[]{})); - assertFalse(_database.verifyPassword(_username, "massword".toCharArray())); - assertTrue(_database.verifyPassword(_username, _password)); + assertFalse(_database.verifyPassword(PRINCIPAL_USERNAME, new char[]{})); + assertFalse(_database.verifyPassword(PRINCIPAL_USERNAME, (PASSWORD+"z").toCharArray())); + assertTrue(_database.verifyPassword(PRINCIPAL_USERNAME, PASSWORD.toCharArray())); + + try + { + _database.verifyPassword("made.up.username", PASSWORD.toCharArray()); + fail("Should not have been able to verify this non-existant users password."); + } + catch (AccountNotFoundException e) + { + // pass + } } public void testUpdatePassword() throws IOException, AccountNotFoundException { testCreateUserPrincipal(); char[] newPwd = "newpassword".toCharArray(); - _database.updatePassword(_principal, newPwd); - assertFalse(_database.verifyPassword(_username, _password)); - assertTrue(_database.verifyPassword(_username, newPwd)); + _database.updatePassword(PRINCIPAL, newPwd); + assertFalse(_database.verifyPassword(PRINCIPAL_USERNAME, PASSWORD.toCharArray())); + assertTrue(_database.verifyPassword(PRINCIPAL_USERNAME, newPwd)); } - + } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java index a7d951cb5b..aa85cac758 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java @@ -34,7 +34,7 @@ public class HashedUserTest extends TestCase String USERNAME = "username"; String PASSWORD = "password"; - String HASHED_PASSWORD = "cGFzc3dvcmQ="; + String B64_ENCODED_PASSWORD = "cGFzc3dvcmQ="; public void testToLongArrayConstructor() { @@ -57,11 +57,11 @@ public class HashedUserTest extends TestCase { try { - HashedUser user = new HashedUser(new String[]{USERNAME, HASHED_PASSWORD}); + HashedUser user = new HashedUser(new String[]{USERNAME, B64_ENCODED_PASSWORD}); assertEquals("Username incorrect", USERNAME, user.getName()); int index = 0; - char[] hash = HASHED_PASSWORD.toCharArray(); + char[] hash = B64_ENCODED_PASSWORD.toCharArray(); try { diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java new file mode 100644 index 0000000000..20b8d0a7b4 --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java @@ -0,0 +1,396 @@ +/* + * + * 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.database; + +import junit.framework.TestCase; + +import javax.security.auth.login.AccountNotFoundException; + +import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.security.Principal; +import java.util.List; +import java.util.regex.Pattern; + +public class PlainPasswordFilePrincipalDatabaseTest extends TestCase +{ + + private static final String TEST_COMMENT = "# Test Comment"; + private static final String TEST_PASSWORD = "testPassword"; + private static final char[] TEST_PASSWORD_CHARS = TEST_PASSWORD.toCharArray(); + private static final String TEST_USERNAME = "testUser"; + + private Principal _principal = new UsernamePrincipal(TEST_USERNAME); + private PlainPasswordFilePrincipalDatabase _database; + + public void setUp() throws Exception + { + _database = new PlainPasswordFilePrincipalDatabase(); + } + + // ******* Test Methods ********** // + + public void testCreatePrincipal() + { + File testFile = createPasswordFile(1, 0); + + loadPasswordFile(testFile); + + final String CREATED_PASSWORD = "guest"; + final String CREATED_USERNAME = "createdUser"; + + Principal principal = new Principal() + { + public String getName() + { + return CREATED_USERNAME; + } + }; + + assertTrue("New user not created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray())); + + loadPasswordFile(testFile); + + assertNotNull("Created User was not saved", _database.getUser(CREATED_USERNAME)); + + assertFalse("Duplicate user created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray())); + + testFile.delete(); + } + + public void testCreatePrincipalIsSavedToFile() + { + + File testFile = createPasswordFile(1, 0); + + loadPasswordFile(testFile); + + Principal principal = new Principal() + { + public String getName() + { + return TEST_USERNAME; + } + }; + + _database.createPrincipal(principal, TEST_PASSWORD_CHARS); + + try + { + BufferedReader reader = new BufferedReader(new FileReader(testFile)); + + assertTrue("File has no content", reader.ready()); + + assertEquals("Comment line has been corrupted.", TEST_COMMENT, reader.readLine()); + + assertTrue("File is missing user data.", reader.ready()); + + String userLine = reader.readLine(); + + String[] result = Pattern.compile(":").split(userLine); + + assertEquals("User line not complete '" + userLine + "'", 2, result.length); + + assertEquals("Username not correct,", TEST_USERNAME, result[0]); + assertEquals("Password not correct,", TEST_PASSWORD, result[1]); + + assertFalse("File has more content", reader.ready()); + + } + catch (IOException e) + { + fail("Unable to valdate file contents due to:" + e.getMessage()); + } + testFile.delete(); + } + + public void testDeletePrincipal() + { + File testFile = createPasswordFile(1, 1); + + loadPasswordFile(testFile); + + Principal user = _database.getUser(TEST_USERNAME + "0"); + assertNotNull("Generated user not present.", user); + + try + { + _database.deletePrincipal(user); + } + catch (AccountNotFoundException e) + { + fail("User should be present" + e.getMessage()); + } + + try + { + _database.deletePrincipal(user); + fail("User should not be present"); + } + catch (AccountNotFoundException e) + { + //pass + } + + loadPasswordFile(testFile); + + try + { + _database.deletePrincipal(user); + fail("User should not be present"); + } + catch (AccountNotFoundException e) + { + //pass + } + + assertNull("Deleted user still present.", _database.getUser(TEST_USERNAME + "0")); + + testFile.delete(); + } + + public void testGetUsers() + { + int USER_COUNT = 10; + File testFile = createPasswordFile(1, USER_COUNT); + + loadPasswordFile(testFile); + + Principal user = _database.getUser("MISSING_USERNAME"); + assertNull("Missing user present.", user); + + List<Principal> users = _database.getUsers(); + + assertNotNull("Users list is null.", users); + + assertEquals(USER_COUNT, users.size()); + + boolean[] verify = new boolean[USER_COUNT]; + for (int i = 0; i < USER_COUNT; i++) + { + Principal principal = users.get(i); + + assertNotNull("Generated user not present.", principal); + + String name = principal.getName(); + + int id = Integer.parseInt(name.substring(TEST_USERNAME.length())); + + assertFalse("Duplicated username retrieve", verify[id]); + verify[id] = true; + } + + for (int i = 0; i < USER_COUNT; i++) + { + assertTrue("User " + i + " missing", verify[i]); + } + + testFile.delete(); + } + + public void testUpdatePasswordIsSavedToFile() + { + + File testFile = createPasswordFile(1, 1); + + loadPasswordFile(testFile); + + Principal testUser = _database.getUser(TEST_USERNAME + "0"); + + assertNotNull(testUser); + + String NEW_PASSWORD = "NewPassword"; + try + { + _database.updatePassword(testUser, NEW_PASSWORD.toCharArray()); + } + catch (AccountNotFoundException e) + { + fail(e.toString()); + } + + try + { + BufferedReader reader = new BufferedReader(new FileReader(testFile)); + + assertTrue("File has no content", reader.ready()); + + assertEquals("Comment line has been corrupted.", TEST_COMMENT, reader.readLine()); + + assertTrue("File is missing user data.", reader.ready()); + + String userLine = reader.readLine(); + + String[] result = Pattern.compile(":").split(userLine); + + assertEquals("User line not complete '" + userLine + "'", 2, result.length); + + assertEquals("Username not correct,", TEST_USERNAME + "0", result[0]); + assertEquals("New Password not correct,", NEW_PASSWORD, result[1]); + + assertFalse("File has more content", reader.ready()); + + } + catch (IOException e) + { + fail("Unable to valdate file contents due to:" + e.getMessage()); + } + testFile.delete(); + } + + public void testSetPasswordFileWithMissingFile() + { + try + { + _database.setPasswordFile("DoesntExist"); + } + catch (FileNotFoundException fnfe) + { + assertTrue(fnfe.getMessage(), fnfe.getMessage().startsWith("Cannot find password file")); + } + catch (IOException e) + { + fail("Password File was not created." + e.getMessage()); + } + + } + + public void testSetPasswordFileWithReadOnlyFile() + { + + File testFile = createPasswordFile(0, 0); + + testFile.setReadOnly(); + + try + { + _database.setPasswordFile(testFile.toString()); + } + catch (FileNotFoundException fnfe) + { + assertTrue(fnfe.getMessage().startsWith("Cannot read password file ")); + } + catch (IOException e) + { + fail("Password File was not created." + e.getMessage()); + } + + testFile.delete(); + } + + private void createUserPrincipal() throws IOException + { + File testFile = createPasswordFile(0, 0); + loadPasswordFile(testFile); + + _database.createPrincipal(_principal, TEST_PASSWORD_CHARS); + Principal newPrincipal = _database.getUser(TEST_USERNAME); + assertNotNull(newPrincipal); + assertEquals(_principal.getName(), newPrincipal.getName()); + } + + public void testVerifyPassword() throws IOException, AccountNotFoundException + { + createUserPrincipal(); + assertFalse(_database.verifyPassword(TEST_USERNAME, new char[]{})); + assertFalse(_database.verifyPassword(TEST_USERNAME, "massword".toCharArray())); + assertTrue(_database.verifyPassword(TEST_USERNAME, TEST_PASSWORD_CHARS)); + + try + { + _database.verifyPassword("made.up.username", TEST_PASSWORD_CHARS); + fail("Should not have been able to verify this non-existant users password."); + } + catch (AccountNotFoundException e) + { + // pass + } + } + + public void testUpdatePassword() throws IOException, AccountNotFoundException + { + createUserPrincipal(); + char[] newPwd = "newpassword".toCharArray(); + _database.updatePassword(_principal, newPwd); + assertFalse(_database.verifyPassword(TEST_USERNAME, TEST_PASSWORD_CHARS)); + assertTrue(_database.verifyPassword(TEST_USERNAME, newPwd)); + } + + + + // *********** Utility Methods ******** // + + private File createPasswordFile(int commentLines, int users) + { + try + { + File testFile = File.createTempFile(this.getClass().getName(),"tmp"); + testFile.deleteOnExit(); + + BufferedWriter writer = new BufferedWriter(new FileWriter(testFile)); + + for (int i = 0; i < commentLines; i++) + { + writer.write(TEST_COMMENT); + writer.newLine(); + } + + for (int i = 0; i < users; i++) + { + writer.write(TEST_USERNAME + i + ":" + TEST_PASSWORD); + writer.newLine(); + } + + writer.flush(); + writer.close(); + + return testFile; + + } + catch (IOException e) + { + fail("Unable to create test password file." + e.getMessage()); + } + + return null; + } + + private void loadPasswordFile(File file) + { + try + { + _database.setPasswordFile(file.toString()); + } + catch (IOException e) + { + fail("Password File was not created." + e.getMessage()); + } + } + + +} diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.java new file mode 100644 index 0000000000..7f0843d46e --- /dev/null +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.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.server.security.auth.database; + +import junit.framework.TestCase; + +/* + Note PlainUser is mainly tested by PlainPFPDTest, this is just to catch the extra methods + */ +public class PlainUserTest extends TestCase +{ + + String USERNAME = "username"; + String PASSWORD = "password"; + + public void testTooLongArrayConstructor() + { + try + { + PlainUser user = new PlainUser(new String[]{USERNAME, PASSWORD, USERNAME}); + fail("Error expected"); + } + catch (IllegalArgumentException e) + { + assertEquals("User Data should be length 2, username, password", e.getMessage()); + } + } + + public void testStringArrayConstructor() + { + PlainUser user = new PlainUser(new String[]{USERNAME, PASSWORD}); + assertEquals("Username incorrect", USERNAME, user.getName()); + int index = 0; + + char[] password = PASSWORD.toCharArray(); + + try + { + for (byte c : user.getPasswordBytes()) + { + assertEquals("Password incorrect", password[index], (char) c); + index++; + } + } + catch (Exception e) + { + fail(e.getMessage()); + } + + password = PASSWORD.toCharArray(); + + index=0; + for (char c : user.getPassword()) + { + assertEquals("Password incorrect", password[index], c); + index++; + } + } +} + diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java index 7722eae116..33d8ac0160 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java @@ -21,6 +21,8 @@ package org.apache.qpid.server.store; import junit.framework.TestCase; + +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeType; @@ -102,7 +104,7 @@ public class MessageStoreTest extends TestCase try { - _virtualHost = new VirtualHost(virtualHostName, configuration, null); + _virtualHost = new VirtualHost(new VirtualHostConfiguration(getClass().getName(), configuration)); ApplicationRegistry.getInstance().getVirtualHostRegistry().registerVirtualHost(_virtualHost); } catch (Exception e) diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java index a5b65b527c..0a30d855b3 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java @@ -28,6 +28,7 @@ import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.server.queue.MessageMetaData; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.transactionlog.TransactionLog; import org.apache.qpid.server.routing.RoutingTable; @@ -47,7 +48,7 @@ public class SkeletonMessageStore implements TransactionLog , RoutingTable { } - public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception + public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception { //To change body of implemented methods use File | Settings | File Templates. } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java index 48d69c5bad..5a4c435e59 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java @@ -34,7 +34,7 @@ import org.apache.qpid.server.queue.AMQMessage; */ public class TestReferenceCounting extends TestCase { - private TestMemoryMessageStore _store; + private TestableMemoryMessageStore _store; private StoreContext _storeContext = new StoreContext(); @@ -42,7 +42,7 @@ public class TestReferenceCounting extends TestCase protected void setUp() throws Exception { super.setUp(); - _store = new TestMemoryMessageStore(); + _store = new TestableMemoryMessageStore(); } /** @@ -54,19 +54,9 @@ public class TestReferenceCounting extends TestCase MessagePublishInfo info = new MessagePublishInfoImpl(); - final long messageId = _store.getNewMessageId(); - AMQMessage message = (MessageFactory.getInstance()).createMessage(_store, true); message.setPublishAndContentHeaderBody(_storeContext, info, chb); - message = message.takeReference(); - - // we call routing complete to set up the handle - // message.routingComplete(_store, _storeContext, new MessageHandleFactory()); - - - assertEquals(1, _store.getMessageMetaDataMap().size()); - message.decrementReference(_storeContext); assertEquals(1, _store.getMessageMetaDataMap().size()); } @@ -84,16 +74,10 @@ public class TestReferenceCounting extends TestCase MessagePublishInfo info = new MessagePublishInfoImpl(); - final Long messageId = _store.getNewMessageId(); final ContentHeaderBody chb = createPersistentContentHeader(); AMQMessage message = (MessageFactory.getInstance()).createMessage(_store, true); message.setPublishAndContentHeaderBody(_storeContext, info, chb); - message = message.takeReference(); - - assertEquals(1, _store.getMessageMetaDataMap().size()); - message = message.takeReference(); - message.decrementReference(_storeContext); assertEquals(1, _store.getMessageMetaDataMap().size()); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagementConfiguration.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestTransactionLog.java index 042f626e8b..bb051693c3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagementConfiguration.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestTransactionLog.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,13 +18,14 @@ * under the License. * */ -package org.apache.qpid.server.management; +package org.apache.qpid.server.store; + +import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.configuration.Configured; +import java.util.Map; +import java.util.List; -public class ManagementConfiguration +public interface TestTransactionLog { - @Configured(path = "management.enabled", - defaultValue = "true") - public boolean enabled; + public List<AMQQueue> getMessageReferenceMap(Long messageID); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java index 9146fe88ae..456e816a52 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java @@ -23,22 +23,29 @@ package org.apache.qpid.server.store; import org.apache.qpid.AMQException; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MessageMetaData; -import org.apache.qpid.framing.ContentBody; +import org.apache.qpid.server.routing.RoutingTable; +import org.apache.qpid.server.transactionlog.TransactionLog; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.commons.configuration.Configuration; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Adds some extra methods to the memory message store for testing purposes. */ -public class TestableMemoryMessageStore extends MemoryMessageStore +public class TestableMemoryMessageStore implements TestTransactionLog, TransactionLog, RoutingTable { MemoryMessageStore _mms = null; - private HashMap<Long, AMQQueue> _messages = new HashMap<Long, AMQQueue>(); public TestableMemoryMessageStore(MemoryMessageStore mms) { @@ -47,46 +54,122 @@ public class TestableMemoryMessageStore extends MemoryMessageStore public TestableMemoryMessageStore() { - _metaDataMap = new ConcurrentHashMap<Long, MessageMetaData>(); - _contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>(); + _mms = new MemoryMessageStore(); + _mms.configure(); } public ConcurrentMap<Long, MessageMetaData> getMessageMetaDataMap() { - if (_mms != null) - { - return _mms._metaDataMap; - } - else - { - return _metaDataMap; - } + return _mms._metaDataMap; } public ConcurrentMap<Long, List<ContentChunk>> getContentBodyMap() { - if (_mms != null) - { - return _mms._contentBodyMap; - } - else - { - return _contentBodyMap; - } + return _mms._contentBodyMap; } - - public void enqueueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException + + public List<AMQQueue> getMessageReferenceMap(Long messageId) + { + return _mms._messageEnqueueMap.get(messageId); + } + + public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception + { + _mms.configure(virtualHost,base,config); + } + + public void close() throws Exception + { + _mms.close(); + } + + public void createExchange(Exchange exchange) throws AMQException + { + _mms.createExchange(exchange); + } + + public void removeExchange(Exchange exchange) throws AMQException + { + _mms.removeExchange(exchange); + } + + public void bindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException + { + _mms.bindQueue(exchange,routingKey,queue,args); + } + + public void unbindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException + { + _mms.unbindQueue(exchange,routingKey,queue,args); + } + + public void createQueue(AMQQueue queue) throws AMQException + { + _mms.createQueue(queue); + } + + public void createQueue(AMQQueue queue, FieldTable arguments) throws AMQException + { + _mms.createQueue(queue,arguments); + } + + public void removeQueue(AMQQueue queue) throws AMQException + { + _mms.removeQueue(queue); + } + + public void enqueueMessage(StoreContext context, AMQQueue queue, Long messageId) throws AMQException + { + _mms.enqueueMessage(context,queue,messageId); + } + + public void dequeueMessage(StoreContext context, AMQQueue queue, Long messageId) throws AMQException + { + _mms.dequeueMessage(context,queue,messageId); + } + + public void beginTran(StoreContext context) throws AMQException + { + _mms.beginTran(context); + } + + public void commitTran(StoreContext context) throws AMQException + { + _mms.commitTran(context); + } + + public void abortTran(StoreContext context) throws AMQException + { + _mms.abortTran(context); + } + + public boolean inTran(StoreContext context) + { + return _mms.inTran(context); + } + + public void storeContentBodyChunk(StoreContext context, Long messageId, int index, ContentChunk contentBody, boolean lastContentBody) throws AMQException + { + _mms.storeContentBodyChunk(context,messageId,index,contentBody,lastContentBody); + } + + public void storeMessageMetaData(StoreContext context, Long messageId, MessageMetaData messageMetaData) throws AMQException + { + _mms.storeMessageMetaData(context,messageId,messageMetaData); + } + + public MessageMetaData getMessageMetaData(StoreContext context, Long messageId) throws AMQException { - getMessages().put(messageId, queue); + return _mms.getMessageMetaData(context,messageId); } - public void dequeueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException + public ContentChunk getContentBodyChunk(StoreContext context, Long messageId, int index) throws AMQException { - getMessages().remove(messageId); + return _mms.getContentBodyChunk(context,messageId,index); } - public HashMap<Long, AMQQueue> getMessages() + public boolean isPersistent() { - return _messages; + return _mms.isPersistent(); } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java index 33fd669d5c..ab0870144b 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java @@ -30,10 +30,13 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.QueueEntry.SubscriptionAcquiredState; +import org.apache.log4j.Logger; public class MockSubscription implements Subscription { + private static final Logger _logger = Logger.getLogger(MockSubscription.class); private boolean _closed = false; private AMQShortString tag = new AMQShortString("mocktag"); @@ -41,8 +44,12 @@ public class MockSubscription implements Subscription private StateListener _listener = null; private QueueEntry lastSeen = null; private State _state = State.ACTIVE; - private ArrayList<QueueEntry> messages = new ArrayList<QueueEntry>(); + private ArrayList<QueueEntry> _queueEntries = new ArrayList<QueueEntry>(); private final Lock _stateChangeLock = new ReentrantLock(); + private ArrayList<AMQMessage> _messages = new ArrayList<AMQMessage>(); + + + public void close() { @@ -136,10 +143,14 @@ public class MockSubscription implements Subscription { } - public void send(QueueEntry msg) throws AMQException + public void send(QueueEntry entry) throws AMQException { - lastSeen = msg; - messages.add(msg); + _logger.info("Sending Message(" + entry.debugIdentity() + ") to subscription:" + this); + + lastSeen = entry; + _queueEntries.add(entry); + _messages.add(entry.getMessage()); + entry.setDeliveredToSubscription(); } public boolean setLastSeenEntry(QueueEntry expected, QueueEntry newValue) @@ -173,8 +184,14 @@ public class MockSubscription implements Subscription return false; } - public ArrayList<QueueEntry> getMessages() + public ArrayList<QueueEntry> getQueueEntries() { - return messages; + return _queueEntries; } + + public ArrayList<AMQMessage> getMessages() + { + return _messages; + } + } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java index ca6644d141..26802b4210 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java @@ -22,8 +22,8 @@ package org.apache.qpid.server.txn; import junit.framework.TestCase; import org.apache.qpid.AMQException; -import org.apache.qpid.server.store.TestMemoryMessageStore; import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.store.TestableMemoryMessageStore; import org.apache.qpid.server.transactionlog.TransactionLog; import java.util.LinkedList; @@ -194,7 +194,7 @@ public class TxnBufferTest extends TestCase } } - class MockStore extends TestMemoryMessageStore + class MockStore extends TestableMemoryMessageStore { final Object BEGIN = "BEGIN"; final Object ABORT = "ABORT"; diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java index d150faf94a..cdc7eabf04 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java @@ -21,11 +21,14 @@ package org.apache.qpid.server.util; import junit.framework.TestCase; + +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl; +import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.protocol.InternalTestProtocolSession; import org.apache.qpid.server.AMQChannel; @@ -58,7 +61,9 @@ public class InternalBrokerBaseCase extends TestCase public void setUp() throws Exception { super.setUp(); - _registry = new TestApplicationRegistry(); + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty("virtualhosts.virtualhost.test.store.class", TestableMemoryMessageStore.class.getName()); + _registry = new TestApplicationRegistry(new ServerConfiguration(configuration)); ApplicationRegistry.initialise(_registry); _virtualHost = _registry.getVirtualHostRegistry().getVirtualHost("test"); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java index 2605ed0d11..22bd3b5aab 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java @@ -20,7 +20,11 @@ */ package org.apache.qpid.server.util; +import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.MapConfiguration; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.management.NoopManagedObjectRegistry; @@ -52,9 +56,17 @@ public class TestApplicationRegistry extends ApplicationRegistry private VirtualHost _vHost; - public TestApplicationRegistry() + private ServerConfiguration _config; + + public TestApplicationRegistry() throws ConfigurationException + { + super(new ServerConfiguration(new PropertiesConfiguration())); + } + + public TestApplicationRegistry(ServerConfiguration config) throws ConfigurationException { - super(new MapConfiguration(new HashMap())); + super(config); + _config = config; } public void initialise() throws Exception @@ -65,7 +77,7 @@ public class TestApplicationRegistry extends ApplicationRegistry _databaseManager = new PropertiesPrincipalDatabaseManager("default", users); - _accessManager = new ACLManager(_configuration, _pluginManager, AllowAll.FACTORY); + _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager, AllowAll.FACTORY); _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null); @@ -75,7 +87,9 @@ public class TestApplicationRegistry extends ApplicationRegistry _virtualHostRegistry = new VirtualHostRegistry(); - _vHost = new VirtualHost("test", _transactionLog); + PropertiesConfiguration vhostProps = new PropertiesConfiguration(); + VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps); + _vHost = new VirtualHost(hostConfig, _transactionLog); _virtualHostRegistry.registerVirtualHost(_vHost); @@ -83,7 +97,6 @@ public class TestApplicationRegistry extends ApplicationRegistry _exchangeFactory = _vHost.getExchangeFactory(); _exchangeRegistry = _vHost.getExchangeRegistry(); - _configuration.addProperty("heartbeat.delay", 10 * 60); // 10 minutes } public QueueRegistry getQueueRegistry() diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java index ba19fd5d5e..1274b99880 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.virtualhost; import junit.framework.TestCase; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; public class VirtualhostInitRoutingTableFromTransactionLogTest extends TestCase { @@ -35,7 +36,7 @@ public class VirtualhostInitRoutingTableFromTransactionLogTest extends TestCase VirtualHost _virtualHost = null; try { - _virtualHost = new VirtualHost("test", env); + _virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env)); assertNotNull(_virtualHost.getTransactionLog()); assertNotNull(_virtualHost.getRoutingTable()); diff --git a/qpid/java/build.deps b/qpid/java/build.deps index 7b06c379b3..d62e414639 100644 --- a/qpid/java/build.deps +++ b/qpid/java/build.deps @@ -1,9 +1,11 @@ backport-util-concurrent=lib/backport-util-concurrent-2.2.jar +commons-beanutils-core=lib/commons-beanutils-core-1.8.0.jar commons-cli=lib/commons-cli-1.0.jar commons-codec=lib/commons-codec-1.3.jar commons-collections=lib/commons-collections-3.2.jar -commons-configuration=lib/commons-configuration-1.2.jar +commons-configuration=lib/commons-configuration-1.6.jar +commons-digester=lib/commons-digester-1.8.1.jar commons-lang=lib/commons-lang-2.2.jar commons-logging=lib/commons-logging-1.0.4.jar commons-pool=lib/commons-pool-1.4.jar @@ -71,7 +73,7 @@ geronimo-servlet=lib/geronimo-servlet_2.5_spec-1.2.jar felix.libs=${osgi-core} ${felix-framework} common.libs=${slf4j-api} ${backport-util-concurrent} ${mina-core} \ - ${mina-filter-ssl} ${commons-codec} ${commons-lang} ${commons-collections} \ + ${mina-filter-ssl} ${commons-beanutils-core} ${commons-digester} ${commons-codec} ${commons-lang} ${commons-collections} \ ${commons-configuration} client.libs=${common.libs} ${geronimo-jms} tools.libs=${client.libs} @@ -90,7 +92,6 @@ integrationtests.libs=${systests.libs} client-example.libs=${client.libs} testkit.libs=${client.libs} - ibm-icu=lib/com.ibm.icu_3.8.1.v20080530.jar ecl-core-jface=lib/org.eclipse.jface_3.4.1.M20080827-2000.jar ecl-core-jface-databinding=lib/org.eclipse.jface.databinding_1.2.1.M20080827-0800a.jar @@ -112,30 +113,41 @@ ecl-swt=lib/org.eclipse.swt_3.4.1.v3449c.jar ecl-ui=lib/org.eclipse.ui_3.4.1.M20080910-0800.jar ecl-ui-forms=lib/org.eclipse.ui.forms_3.3.101.v20080708_34x.jar ecl-ui-workbench=lib/org.eclipse.ui.workbench_3.4.1.M20080827-0800a.jar +apache-commons-codec=lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar ecl-swt-win32-win32-x86=lib/org.eclipse.swt.win32.win32.x86_3.4.1.v3449c.jar ecl-equinox-launcher-win32-win32-x86=lib/org.eclipse.equinox.launcher.win32.win32.x86_1.0.101.R34x_v20080731/** ecl-swt-linux-gtk-x86=lib/org.eclipse.swt.gtk.linux.x86_3.4.1.v3449c.jar ecl-equinox-launcher-linux-gtk-x86=lib/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.101.R34x_v20080805/** +ecl-swt-linux-gtk-x86_64=lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar +ecl-equinox-launcher-linux-gtk-x86_64=lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/** ecl-swt-macosx-carbon=lib/org.eclipse.swt.carbon.macosx_3.4.1.v3449c.jar ecl-equinox-launcher-macosx-carbon=lib/org.eclipse.equinox.launcher.carbon.macosx_1.0.101.R34x_v20080731/** +ecl-swt-solaris-gtk-sparc=lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar +ecl-equinox-launcher-solaris-gtk-sparc=lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/** management-eclipse-plugin-win32-win32-x86.libs=${management-eclipse-plugin.core-libs} \ ${ecl-swt-win32-win32-x86} ${ecl-equinox-launcher-win32-win32-x86} management-eclipse-plugin-linux-gtk-x86.libs=${management-eclipse-plugin.core-libs} \ ${ecl-swt-linux-gtk-x86} ${ecl-equinox-launcher-linux-gtk-x86} +management-eclipse-plugin-linux-gtk-x86_64.libs=${management-eclipse-plugin.core-libs} \ + ${ecl-swt-linux-gtk-x86_64} ${ecl-equinox-launcher-linux-gtk-x86_64} management-eclipse-plugin-macosx.libs=${management-eclipse-plugin.core-libs} \ ${ecl-swt-macosx-carbon} ${ecl-equinox-launcher-macosx-carbon} +management-eclipse-plugin-solaris-gtk-sparc.libs=${management-eclipse-plugin.core-libs} \ + ${ecl-swt-solaris-gtk-sparc} ${ecl-equinox-launcher-solaris-gtk-sparc} management-eclipse-plugin.core-libs=${ibm-icu} ${ecl-core-jface} ${ecl-core-jface-databinding} \ ${ecl-core-commands} ${ecl-core-contenttype} ${ecl-core-databinding} ${ecl-core-expressions} \ ${ecl-core-jobs} ${ecl-core-runtime} ${ecl-core-runtime-compat-registry} ${ecl-equinox-app} \ ${ecl-equinox-common} ${ecl-equinox-launcher} ${ecl-equinox-prefs} ${ecl-equinox-registry} \ - ${ecl-help} ${ecl-osgi} ${ecl-swt} ${ecl-ui} ${ecl-ui-forms} ${ecl-ui-workbench} + ${ecl-help} ${ecl-osgi} ${ecl-swt} ${ecl-ui} ${ecl-ui-forms} ${ecl-ui-workbench} ${apache-commons-codec} management-eclipse-plugin.platform-libs=${ecl-equinox-launcher-win32-win32-x86} \ ${ecl-equinox-launcher-linux-gtk-x86} ${ecl-equinox-launcher-macosx-carbon} \ - ${ecl-swt-win32-win32-x86} ${ecl-swt-linux-gtk-x86} ${ecl-swt-macosx-carbon} + ${ecl-swt-win32-win32-x86} ${ecl-swt-linux-gtk-x86} ${ecl-swt-macosx-carbon} \ + ${ecl-swt-linux-gtk-x86_64} ${ecl-equinox-launcher-linux-gtk-x86_64} \ + ${ecl-swt-solaris-gtk-sparc} ${ecl-equinox-launcher-solaris-gtk-sparc} management-eclipse-plugin.libs=${management-eclipse-plugin.core-libs} ${management-eclipse-plugin.platform-libs} diff --git a/qpid/java/client/example/bin/verify_all b/qpid/java/client/example/bin/verify_all index 0212e7d819..3c8db42dcc 100644 --- a/qpid/java/client/example/bin/verify_all +++ b/qpid/java/client/example/bin/verify_all @@ -19,12 +19,13 @@ # export QPID_SRC_HOME=$(cd "$(dirname $0)/../../../.."; pwd) -export CPP=$QPID_SRC_HOME/cpp/examples/examples +export CPP=$QPID_SRC_HOME/cpp/examples export PYTHON=$QPID_SRC_HOME/python/examples export JAVA=$QPID_SRC_HOME/java/client/example/src/main/java/org/apache/qpid/example/jmsexample -export AMQP_SPEC=$QPID_SRC_HOME/specs/amqp.0-10.xml +export AMQP_SPEC=$QPID_SRC_HOME/specs/amqp.0-10-qpid-errata.xml export PYTHONPATH=$QPID_SRC_HOME/python/ +export LOG4J=file://$QPID_SRC_HOME/java/client/example/src/main/java/log4j.xml trap cleanup EXIT @@ -56,4 +57,3 @@ do $verify $script stop_broker done - diff --git a/qpid/java/client/example/src/main/java/README.txt b/qpid/java/client/example/src/main/java/README.txt index c8fe6a76ad..c9367b706d 100644 --- a/qpid/java/client/example/src/main/java/README.txt +++ b/qpid/java/client/example/src/main/java/README.txt @@ -13,5 +13,5 @@ QPID_SAMPLE This is the parent directory of the directory in which you find the runSample.sh (Ex:- $QPID_SRC_HOME/java/client/example/src/main) -default: /usr/share/doc/rhm-0.2 +default: $PWD diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java index 93bb097268..1ac3e85f7a 100755 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java @@ -42,6 +42,8 @@ public class Listener implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { System.out.println("Message: " + xfr); diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java index 4c72ce75a5..21f9c43cd2 100755 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java @@ -42,6 +42,8 @@ public class Listener implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { System.out.println("Message: " + xfr); diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java index aa1c9b0a41..dff49228a1 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java @@ -32,6 +32,8 @@ public class Listener implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { String body = xfr.getBodyString(); diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java index b930062813..e17d3eef9f 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java @@ -44,6 +44,8 @@ public class Listener implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { String body = xfr.getBodyString(); diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java index 5e6d3c6f69..dd9307ca84 100755 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java @@ -40,6 +40,8 @@ public class TopicListener implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { DeliveryProperties dp = xfr.getHeader().get(DeliveryProperties.class); diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify index 66b4b3c54e..7f81a3a57b 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify @@ -23,11 +23,11 @@ cpp=$CPP/direct direct_consumer_java() { -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer } direct_producer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer } clients $cpp/declare_queues direct_producer_java direct_consumer_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java index d581c4c1aa..a22162e075 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java @@ -2,7 +2,7 @@ cpp=$CPP/direct direct_consumer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer } clients $cpp/declare_queues $cpp/direct_producer direct_consumer_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp index 573cac6986..dc4b349808 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp @@ -2,7 +2,7 @@ cpp=$CPP/direct direct_producer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer } clients $cpp/declare_queues direct_producer_java $cpp/listener diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python index 61c033e969..befa34d650 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON_EXAMPLES/direct +py=$PYTHON/direct direct_producer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer } clients $py/declare_queues.py direct_producer_java $py/direct_consumer.py diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java index 4182331f3f..b22b44b9a6 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON_EXAMPLES/direct +py=$PYTHON/direct direct_consumer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer } clients $py/declare_queues.py $py/direct_producer.py direct_consumer_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify index 6617e37e85..98c866da99 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify @@ -22,11 +22,11 @@ cpp=$CPP/fanout fanout_listener_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 } fanout_producer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer } background "can receive messages" fanout_listener_java fanoutQueue1 diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java index de057ea3b1..ab8d37a0d8 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java @@ -3,7 +3,7 @@ cpp=$CPP/fanout fanout_listener_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 } background "can receive messages" fanout_listener_java fanoutQueue1 diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp index dab6114572..df923e6354 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp @@ -3,7 +3,7 @@ cpp=$CPP/fanout fanout_producer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer } background "Listening" $cpp/listener diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python index 1641d88354..5f8701882d 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python @@ -1,9 +1,9 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify # The JMS producer doesn't create qeueues so utilising the c++ declare_queues -py=$PYTHON_EXAMPLES/fanout +py=$PYTHON/fanout fanout_producer_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer } background "Subscribed" $py/fanout_consumer.py diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java index 0f05663985..72f263fd3d 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java @@ -1,9 +1,9 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify # The JMS producer doesn't create qeueues so utilising the c++ declare_queues -py=$PYTHON_EXAMPLES/fanout +py=$PYTHON/fanout fanout_listener_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1 } background "can receive messages" fanout_listener_java fanoutQueue1 diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify index 588a086752..363af252ad 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify @@ -21,11 +21,11 @@ cpp=$CPP/pub-sub topic_listener_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener } topic_publisher_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher } background "can receive messages" topic_listener_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java index 9276b3e21b..e73c164b77 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java @@ -2,7 +2,7 @@ cpp=$CPP/pub-sub topic_listener_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener } background "can receive messages" topic_listener_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp index af22b3b82c..0b877566d3 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp @@ -2,7 +2,7 @@ cpp=$CPP/pub-sub topic_publisher_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher } background "Listening" $cpp/topic_listener diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python index 3758e0f014..1340fe79eb 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON_EXAMPLES/pubsub +py=$PYTHON/pubsub topic_publisher_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher } background "Queues created" $py/topic_subscriber.py diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java index c2b516f376..b7fba2b3e0 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON_EXAMPLES/pubsub +py=$PYTHON/pubsub topic_listener_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener } background "can receive messages" topic_listener_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify index 79f22aa88a..c6caa7239e 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify @@ -21,11 +21,11 @@ cpp=$CPP/pub-sub client_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client } server_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server } background "can receive messages" server_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java index 6ef1b3b7e3..c0e788e373 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java @@ -3,7 +3,7 @@ cpp=$CPP/request-response client_java() { -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client } background "Waiting" $cpp/server diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp index a1c5aa325d..14a8c28000 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp @@ -2,7 +2,7 @@ cpp=$CPP/request-response server_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server } background "can receive messages" server_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python index 0760952527..2d2ec2fc04 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON_EXAMPLES/request-response +py=$PYTHON/request-response server_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server } background "can receive messages" server_java diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java index 6ea526e914..bcedf168e3 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java @@ -1,8 +1,8 @@ # See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify -py=$PYTHON_EXAMPLES/request-response +py=$PYTHON/request-response client_java(){ -java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client +java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client } background "Request server running" $py/server.py diff --git a/qpid/java/client/example/src/main/java/runSample.sh b/qpid/java/client/example/src/main/java/runSample.sh index e330fb0c36..66338556a5 100755 --- a/qpid/java/client/example/src/main/java/runSample.sh +++ b/qpid/java/client/example/src/main/java/runSample.sh @@ -43,7 +43,7 @@ if test "'x$QPID_SAMPLE'" != "'x'" then QPID_SAMPLE=$QPID_SAMPLE else - QPID_SAMPLE="/usr/share/doc/rhm-0.2" + QPID_SAMPLE=$PWD fi echo "Using QPID_SAMPLE: $QPID_SAMPLE" 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 6c9fcc0f4c..5c48d73e43 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 @@ -268,6 +268,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect //Indicates whether persistent messages are synchronized private boolean _syncPersistence; + //Indicates whether we need to sync on every message ack + private boolean _syncAck; + + //Indicates the sync publish options (persistent|all) + //By default it's async publish + private String _syncPublish = ""; + /** * @param broker brokerdetails * @param username username @@ -348,25 +355,53 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException { // set this connection maxPrefetch - if (connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH) != null) + if (connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH) != null) { - _maxPrefetch = Integer.parseInt(connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH)); + _maxPrefetch = Integer.parseInt(connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH)); } else { // use the defaul value set for all connections _maxPrefetch = Integer.parseInt(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, - ClientProperties.MAX_PREFETCH_DEFAULT)); + ClientProperties.MAX_PREFETCH_DEFAULT)); } - if (connectionURL.getOption(ConnectionURL.AMQ_SYNC_PERSISTENCE) != null) + if (connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PERSISTENCE) != null) { - _syncPersistence = Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.AMQ_SYNC_PERSISTENCE)); + _syncPersistence = + Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PERSISTENCE)); + _logger.warn("sync_persistence is a deprecated property, " + + "please use sync_publish={persistent|all} instead"); } else { // use the defaul value set for all connections _syncPersistence = Boolean.getBoolean(ClientProperties.SYNC_PERSISTENT_PROP_NAME); + if (_syncPersistence) + { + _logger.warn("sync_persistence is a deprecated property, " + + "please use sync_publish={persistent|all} instead"); + } + } + + if (connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_ACK) != null) + { + _syncAck = Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_ACK)); + } + else + { + // use the defaul value set for all connections + _syncAck = Boolean.getBoolean(ClientProperties.SYNC_ACK_PROP_NAME); + } + + if (connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PUBLISH) != null) + { + _syncPublish = connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PUBLISH); + } + else + { + // use the defaul value set for all connections + _syncPublish = System.getProperty((ClientProperties.SYNC_ACK_PROP_NAME),_syncPublish); } _failoverPolicy = new FailoverPolicy(connectionURL, this); @@ -1469,6 +1504,19 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect return _syncPersistence; } + /** + * Indicates whether we need to sync on every message ack + */ + public boolean getSyncAck() + { + return _syncAck; + } + + public String getSyncPublish() + { + return _syncPublish; + } + public void setIdleTimeout(long l) { _delegate.setIdleTimeout(l); diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java index 29f1aec2f5..c2fb05d94e 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java @@ -239,12 +239,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec { _conn.failoverPrep(); _qpidConnection.resume(); - - if (_conn.firePreResubscribe()) - { - _conn.resubscribeSessions(); - } - _conn.fireFailoverComplete(); return; } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java index 08fd49286b..d96544adf8 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java @@ -22,14 +22,12 @@ package org.apache.qpid.client; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpid.AMQException; import javax.jms.IllegalStateException; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Queue; import javax.jms.QueueBrowser; - import java.util.ArrayList; import java.util.Enumeration; import java.util.concurrent.atomic.AtomicBoolean; @@ -90,38 +88,11 @@ public class AMQQueueBrowser implements QueueBrowser { checkState(); final BasicMessageConsumer consumer = - (BasicMessageConsumer) _session.createBrowserConsumer(_queue, _messageSelector, false); + (BasicMessageConsumer) _session.createBrowserConsumer(_queue, _messageSelector, false); _consumers.add(consumer); - return new Enumeration() - { - - Message _nextMessage = consumer == null ? null : consumer.receive(1000); - - public boolean hasMoreElements() - { - _logger.info("QB:hasMoreElements:" + (_nextMessage != null)); - return (_nextMessage != null); - } - - public Object nextElement() - { - Message msg = _nextMessage; - try - { - _logger.info("QB:nextElement about to receive"); - _nextMessage = consumer.receive(1000); - _logger.info("QB:nextElement received:" + _nextMessage); - } - catch (JMSException e) - { - _logger.warn("Exception caught while queue browsing", e); - _nextMessage = null; - } - return msg; - } - }; + return new QueueBrowserEnumeration(consumer); } public void close() throws JMSException @@ -134,4 +105,39 @@ public class AMQQueueBrowser implements QueueBrowser _consumers.clear(); } + private class QueueBrowserEnumeration implements Enumeration + { + Message _nextMessage; + private BasicMessageConsumer _consumer; + + public QueueBrowserEnumeration(BasicMessageConsumer consumer) throws JMSException + { + _nextMessage = consumer == null ? null : consumer.receiveBrowse(); + _logger.info("QB:created with first element:" + _nextMessage); + _consumer = consumer; + } + + public boolean hasMoreElements() + { + _logger.info("QB:hasMoreElements:" + (_nextMessage != null)); + return (_nextMessage != null); + } + + public Object nextElement() + { + Message msg = _nextMessage; + try + { + _logger.info("QB:nextElement about to receive"); + _nextMessage = _consumer.receiveBrowse(); + _logger.info("QB:nextElement received:" + _nextMessage); + } + catch (JMSException e) + { + _logger.warn("Exception caught while queue browsing", e); + _nextMessage = null; + } + return msg; + } + } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 733bee2d81..b632c56708 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -196,13 +196,13 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic * The default value for immediate flag used by producers created by this session is false. That is, a consumer does * not need to be attached to a queue. */ - protected static final boolean DEFAULT_IMMEDIATE = false; + protected static final boolean DEFAULT_IMMEDIATE = Boolean.parseBoolean(System.getProperty("qpid.default_immediate", "false")); /** * The default value for mandatory flag used by producers created by this session is true. That is, server will not * silently drop messages where no queue is connected to the exchange for the message. */ - protected static final boolean DEFAULT_MANDATORY = true; + protected static final boolean DEFAULT_MANDATORY = Boolean.parseBoolean(System.getProperty("qpid.default_mandatory", "true")); /** System property to enable strict AMQP compliance. */ public static final String STRICT_AMQP = "STRICT_AMQP"; @@ -575,12 +575,19 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic public void bindQueue(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments, final AMQShortString exchangeName, final AMQDestination destination) throws AMQException { + bindQueue(queueName, routingKey, arguments, exchangeName, destination, false); + } + + public void bindQueue(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments, + final AMQShortString exchangeName, final AMQDestination destination, + final boolean nowait) throws AMQException + { /*new FailoverRetrySupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>()*/ new FailoverNoopSupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>() { public Object execute() throws AMQException, FailoverException { - sendQueueBind(queueName, routingKey, arguments, exchangeName, destination); + sendQueueBind(queueName, routingKey, arguments, exchangeName, destination, nowait); return null; } }, _connection).execute(); @@ -595,7 +602,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic } public abstract void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments, - final AMQShortString exchangeName, AMQDestination destination) throws AMQException, FailoverException; + final AMQShortString exchangeName, AMQDestination destination, + final boolean nowait) throws AMQException, FailoverException; /** * Closes the session. @@ -1007,6 +1015,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic } catch (URISyntaxException urlse) { + _logger.error("", urlse); JMSException jmse = new JMSException(urlse.getReason()); jmse.setLinkedException(urlse); @@ -1815,6 +1824,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic void failoverPrep() { startDispatcherIfNecessary(); + syncDispatchQueue(); + } + + void syncDispatchQueue() + { final CountDownLatch signal = new CountDownLatch(1); _queue.add(new Dispatchable() { public void dispatch(AMQSession ssn) @@ -1828,7 +1842,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic } catch (InterruptedException e) { - // pass + throw new RuntimeException(e); } } @@ -1859,6 +1873,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic _inRecovery = inRecovery; } + boolean isStarted() + { + return _startedAtLeastOnce.get(); + } + /** * Starts the session, which ensures that it is not suspended and that its event dispatcher is running. * @@ -2281,7 +2300,13 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic * @todo Be aware of possible changes to parameter order as versions change. */ protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, - final boolean noLocal) + final boolean noLocal) throws AMQException + { + return declareQueue(amqd, protocolHandler, noLocal, false); + } + + protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, + final boolean noLocal, final boolean nowait) throws AMQException { /*return new FailoverRetrySupport<AMQShortString, AMQException>(*/ @@ -2296,14 +2321,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic amqd.setQueueName(protocolHandler.generateQueueName()); } - sendQueueDeclare(amqd, protocolHandler); + sendQueueDeclare(amqd, protocolHandler, nowait); return amqd.getAMQQueueName(); } }, _connection).execute(); } - public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler) throws AMQException, FailoverException; + public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, + final boolean nowait) throws AMQException, FailoverException; /** * Undeclares the specified queue. @@ -2416,14 +2442,14 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic AMQProtocolHandler protocolHandler = getProtocolHandler(); - declareExchange(amqd, protocolHandler, false); + declareExchange(amqd, protocolHandler, nowait); - AMQShortString queueName = declareQueue(amqd, protocolHandler, consumer.isNoLocal()); + AMQShortString queueName = declareQueue(amqd, protocolHandler, consumer.isNoLocal(), nowait); // store the consumer queue name consumer.setQueuename(queueName); - bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd); + bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait); // If IMMEDIATE_PREFETCH is not required then suspsend the channel to delay prefetch if (!_immediatePrefetch) @@ -2455,11 +2481,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic try { - consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer.getMessageSelector()); - } - catch (JMSException e) // thrown by getMessageSelector - { - throw new AMQException(null, e.getMessage(), e); + consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer._messageSelector); } catch (FailoverException e) { @@ -2531,8 +2553,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic for (C consumer : consumers) { - consumer.failedOver(); + consumer.failedOverPre(); registerConsumer(consumer, true); + consumer.failedOverPost(); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java index 45b74f317e..34457d745f 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java @@ -52,9 +52,12 @@ import static org.apache.qpid.transport.Option.*; import javax.jms.*; import javax.jms.IllegalStateException; +import java.util.Date; import java.util.HashMap; import java.util.UUID; import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; /** * This is a 0.10 Session @@ -68,6 +71,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic */ private static final Logger _logger = LoggerFactory.getLogger(AMQSession_0_10.class); + private static Timer timer = new Timer("ack-flusher", true); + /** * The underlying QpidSession @@ -83,6 +88,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic // a ref on the qpid connection protected org.apache.qpid.transport.Connection _qpidConnection; + private long maxAckDelay = Long.getLong("qpid.session.max_ack_delay", 1000); + private TimerTask flushTask = null; private RangeSet unacked = new RangeSet(); private int unackedCount = 0; @@ -119,6 +126,25 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic { _qpidSession.txSelect(); } + + if (maxAckDelay > 0) + { + flushTask = new TimerTask() + { + public void run() + { + try + { + flushAcknowledgments(true); + } + catch (Throwable t) + { + _logger.error("error flushing acks", t); + } + } + }; + timer.schedule(flushTask, new Date(), maxAckDelay); + } } /** @@ -142,14 +168,20 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic private void addUnacked(int id) { - unacked.add(id); - unackedCount++; + synchronized (unacked) + { + unacked.add(id); + unackedCount++; + } } private void clearUnacked() { - unacked.clear(); - unackedCount = 0; + synchronized (unacked) + { + unacked.clear(); + unackedCount = 0; + } } //------- overwritten methods of class AMQSession @@ -196,24 +228,37 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic long prefetch = getAMQConnection().getMaxPrefetch(); - if (unackedCount >= prefetch/2 || _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE) + if (unackedCount >= prefetch/2 || maxAckDelay <= 0) { flushAcknowledgments(); - } + } } void flushAcknowledgments() { - if (unackedCount > 0) + flushAcknowledgments(false); + } + + void flushAcknowledgments(boolean setSyncBit) + { + synchronized (unacked) { - messageAcknowledge - (unacked, _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE); - clearUnacked(); + if (unackedCount > 0) + { + messageAcknowledge + (unacked, _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE,setSyncBit); + clearUnacked(); + } } } void messageAcknowledge(RangeSet ranges, boolean accept) { + messageAcknowledge(ranges,accept,false); + } + + void messageAcknowledge(RangeSet ranges, boolean accept,boolean setSyncBit) + { Session ssn = getQpidSession(); for (Range range : ranges) { @@ -222,7 +267,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic ssn.flushProcessed(accept ? BATCH : NONE); if (accept) { - ssn.messageAccept(ranges); + ssn.messageAccept(ranges, UNRELIABLE,setSyncBit? SYNC : NONE); } } @@ -237,7 +282,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic * @param arguments 0_8 specific */ public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey, - final FieldTable arguments, final AMQShortString exchangeName, final AMQDestination destination) + final FieldTable arguments, final AMQShortString exchangeName, + final AMQDestination destination, final boolean nowait) throws AMQException, FailoverException { Map args = FiledTableSupport.convertToMap(arguments); @@ -252,9 +298,12 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic _logger.debug("Binding queue : " + queueName.toString() + " exchange: " + exchangeName.toString() + " using binding key " + rk.asString()); getQpidSession().exchangeBind(queueName.toString(), exchangeName.toString(), rk.toString(), args); } - // We need to sync so that we get notify of an error. - getQpidSession().sync(); - getCurrentException(); + if (!nowait) + { + // We need to sync so that we get notify of an error. + getQpidSession().sync(); + getCurrentException(); + } } @@ -267,6 +316,10 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic */ public void sendClose(long timeout) throws AMQException, FailoverException { + if (flushTask != null) + { + flushTask.cancel(); + } flushAcknowledgments(); getQpidSession().sync(); getQpidSession().close(); @@ -462,18 +515,24 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic { getQpidSession().messageSetFlowMode(consumerTag, MessageFlowMode.WINDOW); } - getQpidSession().messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF); + getQpidSession().messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF, + Option.UNRELIABLE); // We need to sync so that we get notify of an error. // only if not immediat prefetch - if(prefetch() && (consumer.isStrated() || _immediatePrefetch)) + if(prefetch() && (isStarted() || _immediatePrefetch)) { // set the flow getQpidSession().messageFlow(consumerTag, MessageCreditUnit.MESSAGE, - getAMQConnection().getMaxPrefetch()); + getAMQConnection().getMaxPrefetch(), + Option.UNRELIABLE); + } + + if (!nowait) + { + getQpidSession().sync(); + getCurrentException(); } - getQpidSession().sync(); - getCurrentException(); } /** @@ -501,14 +560,18 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic null, name.toString().startsWith("amq.")? Option.PASSIVE:Option.NONE); // We need to sync so that we get notify of an error. - getQpidSession().sync(); - getCurrentException(); + if (!nowait) + { + getQpidSession().sync(); + getCurrentException(); + } } /** * Declare a queue with the given queueName */ - public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler) + public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, + final boolean nowait) throws AMQException, FailoverException { // do nothing this is only used by 0_8 @@ -518,7 +581,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic * Declare a queue with the given queueName */ public AMQShortString send0_10QueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, - final boolean noLocal) + final boolean noLocal, final boolean nowait) throws AMQException, FailoverException { AMQShortString res; @@ -542,9 +605,12 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic amqd.isDurable() ? Option.DURABLE : Option.NONE, !amqd.isDurable() && amqd.isExclusive() ? Option.EXCLUSIVE : Option.NONE); // passive --> false - // We need to sync so that we get notify of an error. - getQpidSession().sync(); - getCurrentException(); + if (!nowait) + { + // We need to sync so that we get notify of an error. + getQpidSession().sync(); + getCurrentException(); + } return res; } @@ -570,7 +636,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic { for (BasicMessageConsumer consumer : _consumers.values()) { - getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag())); + getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag()), + Option.UNRELIABLE); } } else @@ -586,17 +653,20 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic if (consumer.getMessageListener() != null) { getQpidSession().messageFlow(consumerTag, - MessageCreditUnit.MESSAGE, 1); + MessageCreditUnit.MESSAGE, 1, + Option.UNRELIABLE); } } else { getQpidSession() .messageFlow(consumerTag, MessageCreditUnit.MESSAGE, - getAMQConnection().getMaxPrefetch()); + getAMQConnection().getMaxPrefetch(), + Option.UNRELIABLE); } getQpidSession() - .messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF); + .messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF, + Option.UNRELIABLE); } catch (Exception e) { @@ -661,6 +731,19 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic public void opened(Session ssn) {} + public void resumed(Session ssn) + { + _qpidConnection = ssn.getConnection(); + try + { + resubscribe(); + } + catch (AMQException e) + { + throw new RuntimeException(e); + } + } + public void message(Session ssn, MessageTransfer xfr) { messageReceived(new UnprocessedMessage_0_10(xfr)); @@ -677,7 +760,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic public void closed(Session ssn) {} protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, - final boolean noLocal) + final boolean noLocal, final boolean nowait) throws AMQException { /*return new FailoverRetrySupport<AMQShortString, AMQException>(*/ @@ -692,39 +775,16 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic String binddingKey = ""; for(AMQShortString key : amqd.getBindingKeys()) { - binddingKey = binddingKey + "_" + key.toString(); + binddingKey = binddingKey + "_" + key.toString(); } amqd.setQueueName(new AMQShortString( binddingKey + "@" + amqd.getExchangeName().toString() + "_" + UUID.randomUUID())); } - return send0_10QueueDeclare(amqd, protocolHandler, noLocal); + return send0_10QueueDeclare(amqd, protocolHandler, noLocal, nowait); } }, _connection).execute(); } - - void start() throws AMQException - { - super.start(); - for(BasicMessageConsumer c: _consumers.values()) - { - c.start(); - } - } - - - void stop() throws AMQException - { - super.stop(); - for(BasicMessageConsumer c: _consumers.values()) - { - c.stop(); - } - } - - - - public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException { @@ -800,14 +860,14 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic /** * Store non committed messages for this session * With 0.10 messages are consumed with window mode, we must send a completion - * before the window size is reached so credits don't dry up. + * before the window size is reached so credits don't dry up. * @param id */ @Override protected void addDeliveredMessage(long id) { _txRangeSet.add((int) id); _txSize++; - // this is a heuristic, we may want to have that configurable + // this is a heuristic, we may want to have that configurable if (_connection.getMaxPrefetch() == 1 || _connection.getMaxPrefetch() != 0 && _txSize % (_connection.getMaxPrefetch() / 2) == 0) { diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java index 6451ae60be..ff8631c12e 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java @@ -106,7 +106,8 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B } public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments, - final AMQShortString exchangeName, final AMQDestination dest) throws AMQException, FailoverException + final AMQShortString exchangeName, final AMQDestination dest, + final boolean nowait) throws AMQException, FailoverException { getProtocolHandler().syncWrite(getProtocolHandler().getMethodRegistry().createQueueBindBody (getTicket(),queueName,exchangeName,routingKey,false,arguments). @@ -300,13 +301,14 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B { ExchangeDeclareBody body = getMethodRegistry().createExchangeDeclareBody(getTicket(),name,type, name.toString().startsWith("amq."), - false,false,false,nowait,null); + false,false,false,false,null); AMQFrame exchangeDeclare = body.generateFrame(_channelId); protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class); } - public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler) throws AMQException, FailoverException + public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler, + final boolean nowait) throws AMQException, FailoverException { QueueDeclareBody body = getMethodRegistry().createQueueDeclareBody(getTicket(),amqd.getAMQQueueName(),false,amqd.isDurable(),amqd.isExclusive(),amqd.isAutoDelete(),false,null); diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java index 76422c6297..2bb443a090 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java @@ -441,7 +441,9 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa o = _synchronousQueue.take(); } return o; - } + } + + abstract Message receiveBrowse() throws JMSException; public Message receiveNoWait() throws JMSException { @@ -1037,23 +1039,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa _synchronousQueue.clear(); } - public void start() - { - // do nothing as this is a 0_10 feature - } - - - public void stop() - { - // do nothing as this is a 0_10 feature - } - - public boolean isStrated() - { - // do nothing as this is a 0_10 feature - return false; - } - public AMQShortString getQueuename() { return _queuename; @@ -1070,10 +1055,13 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa } /** to be called when a failover has occured */ - public void failedOver() + public void failedOverPre() { clearReceiveQueue(); // TGM FIXME: think this should just be removed // clearUnackedMessages(); } + + public void failedOverPost() {} + } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java index 7d535643c0..8b17dcf91f 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java @@ -31,6 +31,7 @@ import org.apache.qpid.filter.JMSSelectorFilter; import javax.jms.InvalidSelectorException; import javax.jms.JMSException; +import javax.jms.Message; import javax.jms.MessageListener; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; @@ -148,7 +149,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM if (isMessageListenerSet() && ! getSession().prefetch()) { _0_10session.getQpidSession().messageFlow(getConsumerTagString(), - MessageCreditUnit.MESSAGE, 1); + MessageCreditUnit.MESSAGE, 1, + Option.UNRELIABLE); } _logger.debug("messageOk, trying to notify"); super.notifyMessage(jmsMessage); @@ -246,7 +248,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM if(! getSession().prefetch()) { _0_10session.getQpidSession().messageFlow(getConsumerTagString(), - MessageCreditUnit.MESSAGE, 1); + MessageCreditUnit.MESSAGE, 1, + Option.UNRELIABLE); } } // now we need to acquire this message if needed @@ -258,9 +261,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM _logger.debug("filterMessage - trying to acquire message"); } messageOk = acquireMessage(message); - _logger.debug("filterMessage - *************************************"); _logger.debug("filterMessage - message acquire status : " + messageOk); - _logger.debug("filterMessage - *************************************"); } return messageOk; } @@ -335,7 +336,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM if (messageListener != null && ! getSession().prefetch()) { _0_10session.getQpidSession().messageFlow(getConsumerTagString(), - MessageCreditUnit.MESSAGE, 1); + MessageCreditUnit.MESSAGE, 1, + Option.UNRELIABLE); } if (messageListener != null && !_synchronousQueue.isEmpty()) { @@ -349,26 +351,16 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM } } - public boolean isStrated() + public void failedOverPost() { - return _isStarted; - } - - public void start() - { - _isStarted = true; - if (_syncReceive.get()) + if (_0_10session.isStarted() && _syncReceive.get()) { - _0_10session.getQpidSession().messageFlow(getConsumerTagString(), - MessageCreditUnit.MESSAGE, 1); + _0_10session.getQpidSession().messageFlow + (getConsumerTagString(), MessageCreditUnit.MESSAGE, 1, + Option.UNRELIABLE); } } - public void stop() - { - _isStarted = false; - } - /** * When messages are not prefetched we need to request a message from the * broker. @@ -380,16 +372,35 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM */ public Object getMessageFromQueue(long l) throws InterruptedException { - if (isStrated() && ! getSession().prefetch() && _synchronousQueue.isEmpty()) - { - _0_10session.getQpidSession().messageFlow(getConsumerTagString(), - MessageCreditUnit.MESSAGE, 1); - } if (! getSession().prefetch()) { _syncReceive.set(true); } + if (_0_10session.isStarted() && ! getSession().prefetch() && _synchronousQueue.isEmpty()) + { + _0_10session.getQpidSession().messageFlow(getConsumerTagString(), + MessageCreditUnit.MESSAGE, 1, + Option.UNRELIABLE); + } Object o = super.getMessageFromQueue(l); + if (o == null && _0_10session.isStarted()) + { + _0_10session.getQpidSession().messageFlush + (getConsumerTagString(), Option.UNRELIABLE, Option.SYNC); + _0_10session.getQpidSession().sync(); + _0_10session.getQpidSession().messageFlow + (getConsumerTagString(), MessageCreditUnit.BYTE, + 0xFFFFFFFF, Option.UNRELIABLE); + if (getSession().prefetch()) + { + _0_10session.getQpidSession().messageFlow + (getConsumerTagString(), MessageCreditUnit.MESSAGE, + _0_10session.getAMQConnection().getMaxPrefetch(), + Option.UNRELIABLE); + } + _0_10session.syncDispatchQueue(); + o = super.getMessageFromQueue(-1); + } if (! getSession().prefetch()) { _syncReceive.set(false); @@ -404,6 +415,19 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM { _session.acknowledgeMessage(msg.getDeliveryTag(), false); } + + if (_acknowledgeMode == org.apache.qpid.jms.Session.AUTO_ACKNOWLEDGE && + !_session.isInRecovery() && + _session.getAMQConnection().getSyncAck()) + { + ((AMQSession_0_10) getSession()).flushAcknowledgments(); + ((AMQSession_0_10) getSession()).getQpidSession().sync(); + } + } + + Message receiveBrowse() throws JMSException + { + return receiveNoWait(); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java index 494a8fb43d..308f04f082 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java @@ -22,6 +22,7 @@ package org.apache.qpid.client; import javax.jms.InvalidSelectorException; import javax.jms.JMSException; +import javax.jms.Message; import org.apache.qpid.AMQException; import org.apache.qpid.QpidException; @@ -38,9 +39,9 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe protected final Logger _logger = LoggerFactory.getLogger(getClass()); protected BasicMessageConsumer_0_8(int channelId, AMQConnection connection, AMQDestination destination, - String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session, - AMQProtocolHandler protocolHandler, FieldTable arguments, int prefetchHigh, int prefetchLow, - boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) throws JMSException + String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session, + AMQProtocolHandler protocolHandler, FieldTable arguments, int prefetchHigh, int prefetchLow, + boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) throws JMSException { super(channelId, connection, destination,messageSelector,noLocal,messageFactory,session, protocolHandler, arguments, prefetchHigh, prefetchLow, exclusive, @@ -73,13 +74,18 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe } } - public AbstractJMSMessage createJMSMessageFromUnprocessedMessage(AMQMessageDelegateFactory delegateFactory, UnprocessedMessage_0_8 messageFrame)throws Exception - { + public AbstractJMSMessage createJMSMessageFromUnprocessedMessage(AMQMessageDelegateFactory delegateFactory, UnprocessedMessage_0_8 messageFrame)throws Exception + { return _messageFactory.createMessage(messageFrame.getDeliveryTag(), - messageFrame.isRedelivered(), messageFrame.getExchange(), - messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies()); + messageFrame.isRedelivered(), messageFrame.getExchange(), + messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies()); + + } + Message receiveBrowse() throws JMSException + { + return receive(); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java index 954a3bc28f..5ff6066ddc 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java @@ -46,6 +46,8 @@ import org.slf4j.LoggerFactory; public abstract class BasicMessageProducer extends Closeable implements org.apache.qpid.jms.MessageProducer { + enum PublishMode { ASYNC_PUBLISH_ALL, SYNC_PUBLISH_PERSISTENT, SYNC_PUBLISH_ALL }; + protected final Logger _logger = LoggerFactory.getLogger(getClass()); private AMQConnection _connection; @@ -120,6 +122,8 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac protected String _userID; // ref user id used in the connection. private static final ContentBody[] NO_CONTENT_BODIES = new ContentBody[0]; + + protected PublishMode publishMode = PublishMode.ASYNC_PUBLISH_ALL; protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId, AMQSession session, AMQProtocolHandler protocolHandler, long producerId, boolean immediate, boolean mandatory, @@ -141,6 +145,26 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac _mandatory = mandatory; _waitUntilSent = waitUntilSent; _userID = connection.getUsername(); + setPublishMode(); + } + + void setPublishMode() + { + // Publish mode could be configured at destination level as well. + // Will add support for this when we provide a more robust binding URL + + String syncPub = _connection.getSyncPublish(); + // Support for deprecated option sync_persistence + if (syncPub.equals("persistent") || _connection.getSyncPersistence()) + { + publishMode = PublishMode.SYNC_PUBLISH_PERSISTENT; + } + else if (syncPub.equals("all")) + { + publishMode = PublishMode.SYNC_PUBLISH_ALL; + } + + _logger.info("MessageProducer " + toString() + " using publish mode : " + publishMode); } void resubscribe() throws AMQException diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java index 4e5077f0cd..b8c5fc8faf 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java @@ -151,9 +151,13 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer ((AMQSession_0_10) getSession()).getQpidSession(); // if true, we need to sync the delivery of this message - boolean sync = (deliveryMode == DeliveryMode.PERSISTENT && - getSession().getAMQConnection().getSyncPersistence()); + boolean sync = false; + sync = ( (publishMode == PublishMode.SYNC_PUBLISH_ALL) || + (publishMode == PublishMode.SYNC_PUBLISH_PERSISTENT && + deliveryMode == DeliveryMode.PERSISTENT) + ); + org.apache.mina.common.ByteBuffer data = message.getData(); ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.buf().slice(); diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java b/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java index 986154cda8..3627618e68 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java @@ -47,6 +47,19 @@ public class ClientProperties */ public static final String SYNC_PERSISTENT_PROP_NAME = "sync_persistence"; + /** + * When true a sync command is sent after sending a message ack. + * type: boolean + */ + public static final String SYNC_ACK_PROP_NAME = "sync_ack"; + + /** + * sync_publish property - {persistent|all} + * If set to 'persistent',then persistent messages will be publish synchronously + * If set to 'all', then all messages regardless of the delivery mode will be + * published synchronously. + */ + public static final String SYNC_PUBLISH_PROP_NAME = "sync_publish"; /** * This value will be used in the following settings diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java index c0d51fa726..234212c301 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java @@ -31,6 +31,7 @@ import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.transport.util.Functions; /** * @author Apache Software Foundation @@ -84,53 +85,19 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage } public String toBodyString() throws JMSException - { + { checkReadable(); try { - return getText(); + return Functions.str(_data.buf(), 100); } - catch (IOException e) + catch (Exception e) { JMSException jmse = new JMSException(e.toString()); jmse.setLinkedException(e); throw jmse; } - } - - /** - * We reset the stream before and after reading the data. This means that toString() will always output - * the entire message and also that the caller can then immediately start reading as if toString() had - * never been called. - * - * @return - * @throws IOException - */ - private String getText() throws IOException - { - // this will use the default platform encoding - if (_data == null) - { - return null; - } - - int pos = _data.position(); - _data.rewind(); - // one byte left is for the end of frame marker - if (_data.remaining() == 0) - { - // this is really redundant since pos must be zero - _data.position(pos); - - return null; - } - else - { - String data = _data.getString(Charset.forName("UTF8").newDecoder()); - _data.position(pos); - - return data; - } + } /** diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java index 0700ce5d23..60c6048e43 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java @@ -367,13 +367,14 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message try { StringBuffer buf = new StringBuffer("Body:\n"); + buf.append(toBodyString()); buf.append("\nJMS Correlation ID: ").append(getJMSCorrelationID()); buf.append("\nJMS timestamp: ").append(getJMSTimestamp()); buf.append("\nJMS expiration: ").append(getJMSExpiration()); buf.append("\nJMS priority: ").append(getJMSPriority()); buf.append("\nJMS delivery mode: ").append(getJMSDeliveryMode()); - //buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo())); + buf.append("\nJMS reply to: ").append(getReplyToString()); buf.append("\nJMS Redelivered: ").append(_redelivered); buf.append("\nJMS Destination: ").append(getJMSDestination()); buf.append("\nJMS Type: ").append(getJMSType()); @@ -392,7 +393,7 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message while(propertyNames.hasMoreElements()) { String propertyName = (String) propertyNames.nextElement(); - buf.append(propertyName).append(":\t").append(getObjectProperty(propertyName)); + buf.append("\t").append(propertyName).append(" = ").append(getObjectProperty(propertyName)).append("\n"); } } @@ -401,7 +402,9 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message } catch (JMSException e) { - return e.toString(); + e.printStackTrace(); + + throw new RuntimeException(e); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java index cd9d7ccf8b..8681dae2bd 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java @@ -381,10 +381,4 @@ public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessag throw new MessageFormatException("Only primitives plus byte arrays and String are valid types"); } } - - public String toString() - { - return String.valueOf(System.identityHashCode(this)); - } - } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java index 39b9597af1..56e9a5dc73 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java @@ -25,8 +25,6 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; import javax.jms.JMSException; import javax.jms.MessageFormatException; @@ -35,8 +33,6 @@ import javax.jms.ObjectMessage; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicContentHeaderProperties; public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage { @@ -157,7 +153,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag } finally { - _data.rewind(); + // _data.rewind(); close(in); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java index c290149cef..f83ae6ace0 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java @@ -100,6 +100,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text if (encoding == null || encoding.equalsIgnoreCase("UTF-8")) { _data = ByteBuffer.wrap(Strings.toUTF8(text)); + setEncoding("UTF-8"); } else { diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java index d1b3baff6c..a7d41e2cde 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java @@ -48,6 +48,7 @@ public class MessageFactoryRegistry private final Map<String, MessageFactory> _mimeStringToFactoryMap = new HashMap<String, MessageFactory>(); private final Map<AMQShortString, MessageFactory> _mimeShortStringToFactoryMap = new HashMap<AMQShortString, MessageFactory>(); + private final MessageFactory _default = new JMSBytesMessageFactory(); /** * Construct a new registry with the default message factories registered @@ -63,7 +64,7 @@ public class MessageFactoryRegistry mf.registerFactory(JMSBytesMessage.MIME_TYPE, new JMSBytesMessageFactory()); mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory()); mf.registerFactory(JMSStreamMessage.MIME_TYPE, new JMSStreamMessageFactory()); - mf.registerFactory(null, new JMSBytesMessageFactory()); + mf.registerFactory(null, mf._default); return mf; } @@ -113,12 +114,10 @@ public class MessageFactoryRegistry MessageFactory mf = _mimeShortStringToFactoryMap.get(contentTypeShortString); if (mf == null) { - throw new AMQException(null, "Unsupport MIME type of " + properties.getContentTypeAsString(), null); - } - else - { - return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies); + mf = _default; } + + return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies); } public AbstractJMSMessage createMessage(MessageTransfer transfer) throws AMQException, JMSException @@ -138,22 +137,20 @@ public class MessageFactoryRegistry MessageFactory mf = _mimeStringToFactoryMap.get(messageType); if (mf == null) { - throw new AMQException(null, "Unsupport MIME type of " + messageType, null); + mf = _default; } - else + + boolean redelivered = false; + DeliveryProperties deliverProps; + if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null) { - boolean redelivered = false; - DeliveryProperties deliverProps; - if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null) - { - redelivered = deliverProps.getRedelivered(); - } - return mf.createMessage(transfer.getId(), - redelivered, - mprop == null? new MessageProperties():mprop, - deliverProps == null? new DeliveryProperties():deliverProps, - transfer.getBody()); + redelivered = deliverProps.getRedelivered(); } + return mf.createMessage(transfer.getId(), + redelivered, + mprop == null? new MessageProperties():mprop, + deliverProps == null? new DeliveryProperties():deliverProps, + transfer.getBody()); } @@ -167,11 +164,9 @@ public class MessageFactoryRegistry MessageFactory mf = _mimeStringToFactoryMap.get(mimeType); if (mf == null) { - throw new AMQException(null, "Unsupport MIME type of " + mimeType, null); - } - else - { - return mf.createMessage(delegateFactory); + mf = _default; } + + return mf.createMessage(delegateFactory); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java b/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java index fab95f754c..f3f74dd332 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java @@ -58,22 +58,31 @@ public class URLParser if ((connection.getHost() == null) || connection.getHost().equals("")) { - String uid = AMQConnectionFactory.getUniqueClientID(); - if (uid == null) - { - throw URLHelper.parseError(-1, "Client Name not specified", fullURL); + String tmp = connection.getAuthority(); + // hack to read a clientid such as "my_clientID" + if (tmp != null && tmp.indexOf('@') < tmp.length()-1) + { + _url.setClientName(tmp.substring(tmp.indexOf('@')+1,tmp.length())); } else { - _url.setClientName(uid); + String uid = AMQConnectionFactory.getUniqueClientID(); + if (uid == null) + { + throw URLHelper.parseError(-1, "Client Name not specified", fullURL); + } + else + { + _url.setClientName(uid); + } } - } + } else { _url.setClientName(connection.getHost()); } - + String userInfo = connection.getUserInfo(); if (userInfo == null) diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java index da8cd4f750..03ab967c36 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java @@ -33,9 +33,11 @@ import java.util.List; */ public interface ConnectionURL { - public static final String AMQ_SYNC_PERSISTENCE = "sync_persistence"; - public static final String AMQ_MAXPREFETCH = "maxprefetch"; public static final String AMQ_PROTOCOL = "amqp"; + public static final String OPTIONS_SYNC_PERSISTENCE = "sync_persistence"; + public static final String OPTIONS_MAXPREFETCH = "maxprefetch"; + public static final String OPTIONS_SYNC_ACK = "sync_ack"; + public static final String OPTIONS_SYNC_PUBLISH = "sync_publish"; public static final String OPTIONS_BROKERLIST = "brokerlist"; public static final String OPTIONS_FAILOVER = "failover"; public static final String OPTIONS_FAILOVER_CYCLE = "cyclecount"; diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java index 6f945687cf..e05a7ab6e2 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.jms.failover; +import java.net.InetAddress; import java.util.ArrayList; import java.util.List; @@ -52,7 +53,7 @@ import org.slf4j.LoggerFactory; * from the list. */ -public class FailoverExchangeMethod extends FailoverRoundRobinServers implements FailoverMethod, MessageListener +public class FailoverExchangeMethod implements FailoverMethod, MessageListener { private static final Logger _logger = LoggerFactory.getLogger(FailoverExchangeMethod.class); @@ -65,17 +66,29 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements /** The session used to subscribe to failover exchange */ private Session _ssn; - private BrokerDetails _orginalBrokerDetail; + private BrokerDetails _originalBrokerDetail; + + /** The index into the hostDetails array of the broker to which we are connected */ + private int _currentBrokerIndex = 0; + + /** The broker currently selected **/ + private BrokerDetails _currentBrokerDetail; + + /** Array of BrokerDetail used to make connections. */ + private ConnectionURL _connectionDetails; + + /** Denotes the number of failed attempts **/ + private int _failedAttemps = 0; public FailoverExchangeMethod(ConnectionURL connectionDetails, AMQConnection conn) { - super(connectionDetails); - _orginalBrokerDetail = _connectionDetails.getBrokerDetails(0); + _connectionDetails = connectionDetails; + _originalBrokerDetail = _connectionDetails.getBrokerDetails(0); // This is not safe to use until attainConnection is called, as this ref will not initialized fully. // The reason being this constructor is called inside the AMWConnection constructor. // It would be best if we find a way to pass this ref after AMQConnection is fully initialized. - _conn = conn; + _conn = conn; } private void subscribeForUpdates() throws JMSException @@ -96,6 +109,17 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements public void onMessage(Message m) { _logger.info("Failover exchange notified cluster membership change"); + + String currentBrokerIP = ""; + try + { + currentBrokerIP = InetAddress.getByName(_currentBrokerDetail.getHost()).getHostAddress(); + } + catch(Exception e) + { + _logger.warn("Unable to resolve current broker host name",e); + } + List<BrokerDetails> brokerList = new ArrayList<BrokerDetails>(); try { @@ -109,15 +133,22 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements for (String url:urls) { String[] tokens = url.split(":"); - if (tokens[0].equalsIgnoreCase(_orginalBrokerDetail.getTransport())) + if (tokens[0].equalsIgnoreCase(_originalBrokerDetail.getTransport())) { BrokerDetails broker = new AMQBrokerDetails(); broker.setTransport(tokens[0]); broker.setHost(tokens[1]); broker.setPort(Integer.parseInt(tokens[2])); - broker.setProperties(_orginalBrokerDetail.getProperties()); - broker.setSSLConfiguration(_orginalBrokerDetail.getSSLConfiguration()); + broker.setProperties(_originalBrokerDetail.getProperties()); + broker.setSSLConfiguration(_originalBrokerDetail.getSSLConfiguration()); brokerList.add(broker); + + if (currentBrokerIP.equals(broker.getHost()) && + _currentBrokerDetail.getPort() == broker.getPort()) + { + _currentBrokerIndex = brokerList.indexOf(broker); + } + break; } } @@ -132,13 +163,20 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements { _connectionDetails.setBrokerDetails(brokerList); } + + _logger.info("============================================================"); + _logger.info("Updated cluster membership details " + _connectionDetails); + _logger.info("============================================================"); } public void attainedConnection() { - super.attainedConnection(); try { + _failedAttemps = 0; + _logger.info("============================================================"); + _logger.info("Attained connection "); + _logger.info("============================================================"); subscribeForUpdates(); } catch (JMSException e) @@ -151,17 +189,92 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements { synchronized (_brokerListLock) { - return super.getCurrentBrokerDetails(); + return _connectionDetails.getBrokerDetails(_currentBrokerIndex); } - } - + } + public BrokerDetails getNextBrokerDetails() { synchronized(_brokerListLock) { - return super.getNextBrokerDetails(); + if (_currentBrokerIndex == (_connectionDetails.getBrokerCount() - 1)) + { + _currentBrokerIndex = 0; + } + else + { + _currentBrokerIndex++; + } + + BrokerDetails broker = _connectionDetails.getBrokerDetails(_currentBrokerIndex); + + // When the broker list is updated it will include the current broker as well + // There is no point trying it again, so trying the next one. + if (_currentBrokerDetail != null && + broker.getHost().equals(_currentBrokerDetail.getHost()) && + broker.getPort() == _currentBrokerDetail.getPort()) + { + return getNextBrokerDetails(); + } + + String delayStr = broker.getProperty(BrokerDetails.OPTIONS_CONNECT_DELAY); + if (delayStr != null) + { + Long delay = Long.parseLong(delayStr); + _logger.info("Delay between connect retries:" + delay); + try + { + Thread.sleep(delay); + } + catch (InterruptedException ie) + { + return null; + } + } + else + { + _logger.info("No delay between connect retries, use tcp://host:port?connectdelay='value' to enable."); + } + + _failedAttemps ++; + _currentBrokerDetail = broker; + return broker; } } + + public boolean failoverAllowed() + { + // We allow to Failover provided + // our broker list is not empty and + // we haven't gone through all of them + + boolean b = _connectionDetails.getBrokerCount() > 0 && + _failedAttemps <= _connectionDetails.getBrokerCount(); + + + _logger.info("============================================================"); + _logger.info(toString()); + _logger.info("FailoverAllowed " + b); + _logger.info("============================================================"); + + return b; + } + + public void reset() + { + _failedAttemps = 0; + } + + public void setBroker(BrokerDetails broker) + { + // not sure if this method is needed + } + + public void setRetries(int maxRetries) + { + // no max retries we keep trying as long + // as we get updates + } public String methodName() { @@ -172,7 +285,24 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements { StringBuffer sb = new StringBuffer(); sb.append("FailoverExchange:\n"); - sb.append(super.toString()); + sb.append("\n Current Broker Index:"); + sb.append(_currentBrokerIndex); + sb.append("\n Failed Attempts:"); + sb.append(_failedAttemps); + sb.append("\n Orignal broker details:"); + sb.append(_originalBrokerDetail).append("\n"); + sb.append("\n -------- Broker List -----------\n"); + for (int i = 0; i < _connectionDetails.getBrokerCount(); i++) + { + if (i == _currentBrokerIndex) + { + sb.append(">"); + } + + sb.append(_connectionDetails.getBrokerDetails(i)); + sb.append("\n"); + } + sb.append("--------------------------------\n"); return sb.toString(); } } diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java index 7190344f59..c7d8c69fff 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java @@ -30,7 +30,7 @@ public class FailoverRoundRobinServers implements FailoverMethod private static final Logger _logger = LoggerFactory.getLogger(FailoverRoundRobinServers.class); /** The default number of times to cycle through all servers */ - public static final int DEFAULT_CYCLE_RETRIES = 0; + public static final int DEFAULT_CYCLE_RETRIES = 1; /** The default number of times to retry each server */ public static final int DEFAULT_SERVER_RETRIES = 0; @@ -66,6 +66,8 @@ public class FailoverRoundRobinServers implements FailoverMethod String cycleRetries = _connectionDetails.getFailoverOption(ConnectionURL.OPTIONS_FAILOVER_CYCLE); + _cycleRetries = DEFAULT_CYCLE_RETRIES; + if (cycleRetries != null) { try @@ -74,7 +76,7 @@ public class FailoverRoundRobinServers implements FailoverMethod } catch (NumberFormatException nfe) { - _cycleRetries = DEFAULT_CYCLE_RETRIES; + _logger.warn("Cannot set cycle Retries, " + cycleRetries + " is not a number. Using default: " + DEFAULT_CYCLE_RETRIES); } } @@ -93,8 +95,8 @@ public class FailoverRoundRobinServers implements FailoverMethod public boolean failoverAllowed() { - return ((_currentCycleRetries < _cycleRetries) || (_currentServerRetry < _serverRetries) - || (_currentBrokerIndex < (_connectionDetails.getBrokerCount() - 1))); + return ((_currentCycleRetries < _cycleRetries) || (_currentServerRetry < _serverRetries)); + //|| (_currentBrokerIndex <= (_connectionDetails.getBrokerCount() - 1))); } public void attainedConnection() diff --git a/qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java b/qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java deleted file mode 100644 index e19058881e..0000000000 --- a/qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.nclient; - -import java.util.Enumeration; - -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Queue; -import javax.jms.QueueBrowser; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.framing.AMQShortString; - -public class JMSTestCase -{ - - public static void main(String[] args) - { - - try - { - javax.jms.Connection con = new AMQConnection("qpid:password=pass;username=name@tcp:localhost:5672"); - con.start(); - - javax.jms.Session ssn = con.createSession(false, 1); - - javax.jms.Destination dest = new AMQQueue(new AMQShortString("direct"),"test"); - javax.jms.MessageProducer prod = ssn.createProducer(dest); - QueueBrowser browser = ssn.createBrowser((Queue)dest, "Test = 'test'"); - - javax.jms.TextMessage msg = ssn.createTextMessage(); - msg.setStringProperty("TEST", "test"); - msg.setText("Should get this"); - prod.send(msg); - - javax.jms.TextMessage msg2 = ssn.createTextMessage(); - msg2.setStringProperty("TEST", "test2"); - msg2.setText("Shouldn't get this"); - prod.send(msg2); - - - Enumeration enu = browser.getEnumeration(); - for (;enu.hasMoreElements();) - { - System.out.println(enu.nextElement()); - System.out.println("\n"); - } - - javax.jms.MessageConsumer cons = ssn.createConsumer(dest, "Test = 'test'"); - javax.jms.TextMessage m = null; // (javax.jms.TextMessage)cons.receive(); - cons.setMessageListener(new MessageListener() - { - public void onMessage(Message m) - { - javax.jms.TextMessage m2 = (javax.jms.TextMessage)m; - try - { - System.out.println("headers : " + m2.toString()); - System.out.println("m : " + m2.getText()); - System.out.println("\n\n"); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - - }); - - con.setExceptionListener(new ExceptionListener() - { - public void onException(JMSException e) - { - e.printStackTrace(); - } - }); - - System.out.println("Waiting"); - while (m == null) - { - - } - - System.out.println("Exiting"); - - /*javax.jms.TextMessage msg = ssn.createTextMessage(); - msg.setText("This is a test message"); - msg.setBooleanProperty("targetMessage", false); - prod.send(msg); - - msg.setBooleanProperty("targetMessage", true); - prod.send(msg); - - javax.jms.TextMessage m = (javax.jms.TextMessage)cons.receiveNoWait(); - - if (m == null) - { - System.out.println("message is null"); - } - else - { - System.out.println("message is not null" + m); - }*/ - - } - catch(Exception e) - { - e.printStackTrace(); - } - } - -} diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java index d05e90823c..7400b524fd 100644 --- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java +++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java @@ -375,6 +375,19 @@ public class ConnectionURLTest extends TestCase assertTrue(connectionurl.getBrokerCount() == 1); } + public void testClientIDWithUnderscore() throws URLSyntaxException + { + String url = "amqp://user:pass@client_id/test?brokerlist='tcp://localhost:5672'"; + + ConnectionURL connectionurl = new AMQConnectionURL(url); + + assertTrue(connectionurl.getUsername().equals("user")); + assertTrue(connectionurl.getPassword().equals("pass")); + assertTrue(connectionurl.getVirtualHost().equals("/test")); + assertTrue(connectionurl.getClientName().equals("client_id")); + + assertTrue(connectionurl.getBrokerCount() == 1); + } public void testWrongOptionSeparatorInOptions() { diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java index bbabf0b57d..65013e7e6d 100644 --- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java +++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java @@ -559,7 +559,7 @@ public class BytesMessageTest extends TestCase JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage(); bm.reset(); String result = bm.toBodyString(); - assertNull(result); + assertEquals("\"\"", result); } public static junit.framework.Test suite() diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java index 802f1e6c2e..085dd81079 100644 --- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java +++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java @@ -435,7 +435,7 @@ public class StreamMessageTest extends TestCase JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage(); bm.reset(); String result = bm.toBodyString(); - assertNull(result); + assertEquals("\"\"", result); } private void checkConversionsFail(StreamMessage sm, int[] conversions) throws JMSException diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java index a881f6a822..566a222897 100644 --- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java +++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java @@ -44,7 +44,9 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe } - public void sendQueueBind(AMQShortString queueName, AMQShortString routingKey, FieldTable arguments, AMQShortString exchangeName, AMQDestination destination) throws AMQException, FailoverException + public void sendQueueBind(AMQShortString queueName, AMQShortString routingKey, FieldTable arguments, + AMQShortString exchangeName, AMQDestination destination, + boolean nowait) throws AMQException, FailoverException { } @@ -129,7 +131,8 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe } - public void sendQueueDeclare(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException, FailoverException + public void sendQueueDeclare(AMQDestination amqd, AMQProtocolHandler protocolHandler, + boolean nowait) throws AMQException, FailoverException { } diff --git a/qpid/java/common.xml b/qpid/java/common.xml index e9e007c8ef..511cdc6a10 100644 --- a/qpid/java/common.xml +++ b/qpid/java/common.xml @@ -23,7 +23,7 @@ <dirname property="project.root" file="${ant.file.common}"/> <property name="project.name" value="qpid"/> - <property name="project.version" value="M4"/> + <property name="project.version" value="0.5"/> <property name="project.namever" value="${project.name}-${project.version}"/> <property name="resources" location="${project.root}/resources"/> diff --git a/qpid/java/common/Composite.tpl b/qpid/java/common/Composite.tpl index 17cf846d8c..c46d0a12cc 100644 --- a/qpid/java/common/Composite.tpl +++ b/qpid/java/common/Composite.tpl @@ -145,6 +145,7 @@ if options or base == "Method": if base == "Method": out(""" case SYNC: this.setSync(true); break; case BATCH: this.setBatch(true); break; + case UNRELIABLE: this.setUnreliable(true); break; """) out(""" case NONE: break; default: throw new IllegalArgumentException("invalid option: " + _options[i]); diff --git a/qpid/java/common/Option.tpl b/qpid/java/common/Option.tpl index 776b211ad5..c22b35b999 100644 --- a/qpid/java/common/Option.tpl +++ b/qpid/java/common/Option.tpl @@ -37,5 +37,6 @@ for c in composites: options[option] = None out(" $option,\n")} BATCH, + UNRELIABLE, NONE } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java index 3491af8cd2..5b2db10613 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java @@ -37,6 +37,8 @@ class ToyClient implements SessionListener { public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void exception(Session ssn, SessionException exc) { exc.printStackTrace(); 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 adaf2ccd37..e0f239b566 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 @@ -74,7 +74,7 @@ public class Connection extends ConnectionInvoker final private Map<Integer,Session> channels = new HashMap<Integer,Session>(); private State state = NEW; - private Object lock = new Object(); + final private Object lock = new Object(); private long timeout = 60000; private ConnectionListener listener = new DefaultConnectionListener(); private ConnectionException error = null; @@ -164,7 +164,7 @@ public class Connection extends ConnectionInvoker public void connect(String host, int port, String vhost, String username, String password, boolean ssl) { - connect(host, port, vhost, username, password, false,"PLAIN"); + connect(host, port, vhost, username, password, ssl,"PLAIN"); } public void connect(String host, int port, String vhost, String username, String password, boolean ssl,String saslMechs) diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java index c1031c9a1c..0e969464ab 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java @@ -37,6 +37,8 @@ public class Echo implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { int id = xfr.getId(); diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java index 09cfd119be..611c742fb1 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java @@ -48,6 +48,7 @@ public abstract class Method extends Struct implements ProtocolEvent private boolean idSet = false; private boolean sync = false; private boolean batch = false; + private boolean unreliable = false; public final int getId() { @@ -90,6 +91,16 @@ public abstract class Method extends Struct implements ProtocolEvent this.batch = value; } + public final boolean isUnreliable() + { + return unreliable; + } + + final void setUnreliable(boolean value) + { + this.unreliable = value; + } + public abstract boolean hasPayload(); public Header getHeader() diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java index f94edcc655..3dca4fc44e 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java @@ -53,13 +53,15 @@ public class Session extends SessionInvoker private static final Logger log = Logger.get(Session.class); - enum State { NEW, DETACHED, OPEN, CLOSING, CLOSED } + enum State { NEW, DETACHED, RESUMING, OPEN, CLOSING, CLOSED } class DefaultSessionListener implements SessionListener { public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { log.info("message: %s", xfr); @@ -107,6 +109,8 @@ public class Session extends SessionInvoker private volatile boolean flowControl = false; private Semaphore credit = new Semaphore(0); + private Thread resumer = null; + Session(Connection connection, Binary name, long expiry) { this.connection = connection; @@ -234,15 +238,21 @@ public class Session extends SessionInvoker for (int i = maxComplete + 1; lt(i, commandsOut); i++) { Method m = commands[mod(i, commands.length)]; - if (m != null) + if (m == null) { - sessionCommandPoint(m.getId(), 0); - send(m); + m = new ExecutionSync(); + m.setId(i); } + sessionCommandPoint(m.getId(), 0); + send(m); } sessionCommandPoint(commandsOut, 0); sessionFlush(COMPLETED); + resumer = Thread.currentThread(); + state = RESUMING; + listener.resumed(this); + resumer = null; } } @@ -384,7 +394,15 @@ public class Session extends SessionInvoker { copy = processed.copy(); } - sessionCompleted(copy, options); + + synchronized (commands) + { + if (state == DETACHED || state == CLOSING) + { + return; + } + sessionCompleted(copy, options); + } } void knownComplete(RangeSet kc) @@ -484,12 +502,25 @@ public class Session extends SessionInvoker synchronized (commands) { + if (state == DETACHED && m.isUnreliable()) + { + Thread current = Thread.currentThread(); + if (!current.equals(resumer)) + { + return; + } + } + if (state != OPEN && state != CLOSED) { - Waiter w = new Waiter(commands, timeout); - while (w.hasTime() && (state != OPEN && state != CLOSED)) + Thread current = Thread.currentThread(); + if (!current.equals(resumer)) { - w.await(); + Waiter w = new Waiter(commands, timeout); + while (w.hasTime() && (state != OPEN && state != CLOSED)) + { + w.await(); + } } } @@ -497,8 +528,24 @@ public class Session extends SessionInvoker { case OPEN: break; + case RESUMING: + Thread current = Thread.currentThread(); + if (!current.equals(resumer)) + { + throw new SessionException + ("timed out waiting for resume to finish"); + } + break; case CLOSED: - throw new SessionClosedException(); + ExecutionException exc = getException(); + if (exc != null) + { + throw new SessionException(exc); + } + else + { + throw new SessionClosedException(); + } default: throw new SessionException (String.format @@ -512,9 +559,9 @@ public class Session extends SessionInvoker if (isFull(next)) { Waiter w = new Waiter(commands, timeout); - while (w.hasTime() && isFull(next)) + while (w.hasTime() && isFull(next) && state != CLOSED) { - if (state == OPEN) + if (state == OPEN || state == RESUMING) { try { @@ -538,6 +585,19 @@ public class Session extends SessionInvoker } } + if (state == CLOSED) + { + ExecutionException exc = getException(); + if (exc != null) + { + throw new SessionException(exc); + } + else + { + throw new SessionClosedException(); + } + } + if (isFull(next)) { throw new SessionException("timed out waiting for completion"); @@ -547,7 +607,7 @@ public class Session extends SessionInvoker { sessionCommandPoint(0, 0); } - if (expiry > 0) + if (expiry > 0 && !m.isUnreliable()) { commands[mod(next, commands.length)] = m; commandBytes += m.getBodySize(); @@ -815,9 +875,9 @@ public class Session extends SessionInvoker { throw new SessionException("close() timed out"); } - - connection.removeSession(this); } + + connection.removeSession(this); } public void exception(Throwable t) @@ -829,7 +889,7 @@ public class Session extends SessionInvoker { synchronized (commands) { - if (expiry == 0) + if (expiry == 0 || getException() != null) { state = CLOSED; } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java index 63690177f9..eb650eb9ed 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java @@ -31,6 +31,8 @@ public interface SessionListener void opened(Session session); + void resumed(Session session); + void message(Session ssn, MessageTransfer xfr); void exception(Session session, SessionException exception); diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java index 622993effb..88870284f6 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java @@ -87,6 +87,8 @@ public class Sink implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { count++; diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java index 532c19ec18..d18a0f64db 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java @@ -59,12 +59,23 @@ public final class BBEncoder extends AbstractEncoder return slice; } + public ByteBuffer buffer() + { + int pos = out.position(); + out.position(segment); + ByteBuffer slice = out.slice(); + slice.limit(pos - segment); + out.position(pos); + return slice; + } + private void grow(int size) { ByteBuffer old = out; int capacity = old.capacity(); out = ByteBuffer.allocate(Math.max(capacity + size, 2*capacity)); out.order(ByteOrder.BIG_ENDIAN); + old.flip(); out.put(old); } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java index 3e13259ee3..e4bfb9c664 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java @@ -252,16 +252,16 @@ public class FileUtils { for (File subFile : file.listFiles()) { - success = delete(subFile, true) & success ; + success = delete(subFile, true) && success; } - return file.delete(); + return success && file.delete(); } return false; } - return success && file.delete(); + return file.delete(); } diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java deleted file mode 100644 index d90e3b1a17..0000000000 --- a/qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.util; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Iterator; -import java.util.Properties; - -/** - * PropertiesHelper defines some static methods which are useful when working with properties - * files. - * - * <p><table id="crc"><caption>CRC Card</caption> - * <tr><th> Responsibilities <th> Collaborations - * <tr><td> Read properties from an input stream - * <tr><td> Read properties from a file - * <tr><td> Read properties from a URL - * <tr><td> Read properties given a path to a file - * <tr><td> Trim any whitespace from property values - * </table> - */ -public class PropertiesUtils -{ - /** Used for logging. */ - private static final Logger log = LoggerFactory.getLogger(PropertiesUtils.class); - - /** - * Get properties from an input stream. - * - * @param is The input stream. - * - * @return The properties loaded from the input stream. - * - * @throws IOException If the is an I/O error reading from the stream. - */ - public static Properties getProperties(InputStream is) throws IOException - { - log.debug("getProperties(InputStream): called"); - - // Create properties object laoded from input stream - Properties properties = new Properties(); - - properties.load(is); - - return properties; - } - - /** - * Get properties from a file. - * - * @param file The file. - * - * @return The properties loaded from the file. - * - * @throws IOException If there is an I/O error reading from the file. - */ - public static Properties getProperties(File file) throws IOException - { - log.debug("getProperties(File): called"); - - // Open the file as an input stream - InputStream is = new FileInputStream(file); - - // Create properties object loaded from the stream - Properties properties = getProperties(is); - - // Close the file - is.close(); - - return properties; - } - - /** - * Get properties from a url. - * - * @param url The URL. - * - * @return The properties loaded from the url. - * - * @throws IOException If there is an I/O error reading from the URL. - */ - public static Properties getProperties(URL url) throws IOException - { - log.debug("getProperties(URL): called"); - - // Open the URL as an input stream - InputStream is = url.openStream(); - - // Create properties object loaded from the stream - Properties properties = getProperties(is); - - // Close the url - is.close(); - - return properties; - } - - /** - * Get properties from a path name. The path name may refer to either a file or a URL. - * - * @param pathname The path name. - * - * @return The properties loaded from the file or URL. - * - * @throws IOException If there is an I/O error reading from the URL or file named by the path. - */ - public static Properties getProperties(String pathname) throws IOException - { - log.debug("getProperties(String): called"); - - // Check that the path is not null - if (pathname == null) - { - return null; - } - - // Check if the path is a URL - if (isURL(pathname)) - { - // The path is a URL - return getProperties(new URL(pathname)); - } - else - { - // Assume the path is a file name - return getProperties(new File(pathname)); - } - } - - /** - * Trims whitespace from property values. This method returns a new set of properties - * the same as the properties specified as an argument but with any white space removed by - * the {@link java.lang.String#trim} method. - * - * @param properties The properties to trim whitespace from. - * - * @return The white space trimmed properties. - */ - public static Properties trim(Properties properties) - { - Properties trimmedProperties = new Properties(); - - // Loop over all the properties - for (Iterator i = properties.keySet().iterator(); i.hasNext();) - { - String next = (String) i.next(); - String nextValue = properties.getProperty(next); - - // Trim the value if it is not null - if (nextValue != null) - { - nextValue.trim(); - } - - // Store the trimmed value in the trimmed properties - trimmedProperties.setProperty(next, nextValue); - } - - return trimmedProperties; - } - - /** - * Helper method. Guesses whether a string is a URL or not. A String is considered to be a url if it begins with - * http:, ftp:, or uucp:. - * - * @param name The string to test for being a URL. - * - * @return True if the string is a URL and false if not. - */ - private static boolean isURL(String name) - { - return (name.toLowerCase().startsWith("http:") || name.toLowerCase().startsWith("ftp:") - || name.toLowerCase().startsWith("uucp:")); - } -} diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java index dca6264367..8aa8c5f647 100644 --- a/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java +++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java @@ -74,6 +74,8 @@ public class ConnectionTest extends TestCase implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(final Session ssn, MessageTransfer xfr) { if (queue) @@ -122,6 +124,13 @@ public class ConnectionTest extends TestCase implements SessionListener { // do nothing } + else if (body.startsWith("EXCP")) + { + ExecutionException exc = new ExecutionException(); + exc.setDescription("intentional exception for testing"); + ssn.invoke(exc); + ssn.close(); + } else { throw new IllegalArgumentException @@ -138,9 +147,14 @@ public class ConnectionTest extends TestCase implements SessionListener private void send(Session ssn, String msg) { + send(ssn, msg, false); + } + + private void send(Session ssn, String msg, boolean sync) + { ssn.messageTransfer ("xxx", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED, - null, msg); + null, msg, sync ? SYNC : NONE); } private Connection connect(final Condition closed) @@ -277,6 +291,7 @@ public class ConnectionTest extends TestCase implements SessionListener class TestSessionListener implements SessionListener { public void opened(Session s) {} + public void resumed(Session s) {} public void exception(Session s, SessionException e) {} public void message(Session s, MessageTransfer xfr) { @@ -391,4 +406,41 @@ public class ConnectionTest extends TestCase implements SessionListener conn.close(); } + public void testExecutionExceptionInvoke() throws Exception + { + startServer(); + + Connection conn = new Connection(); + conn.connect("localhost", port, null, "guest", "guest"); + Session ssn = conn.createSession(); + send(ssn, "EXCP 0"); + Thread.sleep(3000); + try + { + send(ssn, "SINK 1"); + } + catch (SessionException exc) + { + assertNotNull(exc.getException()); + } + } + + public void testExecutionExceptionSync() throws Exception + { + startServer(); + + Connection conn = new Connection(); + conn.connect("localhost", port, null, "guest", "guest"); + Session ssn = conn.createSession(); + send(ssn, "EXCP 0", true); + try + { + ssn.sync(); + } + catch (SessionException exc) + { + assertNotNull(exc.getException()); + } + } + } diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java new file mode 100644 index 0000000000..79bf184fe2 --- /dev/null +++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java @@ -0,0 +1,47 @@ +/* + * + * 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.transport.codec; + +import junit.framework.TestCase; + +import java.nio.ByteBuffer; + +/** + * BBEncoderTest + * + */ + +public class BBEncoderTest extends TestCase +{ + + public void testGrow() + { + BBEncoder enc = new BBEncoder(4); + enc.writeInt32(0xDEADBEEF); + ByteBuffer buf = enc.buffer(); + assertEquals(0xDEADBEEF, buf.getInt(0)); + enc.writeInt32(0xBEEFDEAD); + buf = enc.buffer(); + assertEquals(0xDEADBEEF, buf.getInt(0)); + assertEquals(0xBEEFDEAD, buf.getInt(4)); + } + +} diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java b/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java index fb367d042c..94e7e20a86 100644 --- a/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java +++ b/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java @@ -280,6 +280,30 @@ public class FileUtilsTest extends TestCase checkFileLists(filesBefore, filesAfter); } + public void testDeleteNonExistentFile() + { + File test = new File("FileUtilsTest-testDelete-"+System.currentTimeMillis()); + + assertTrue("File exists", !test.exists()); + assertFalse("File is a directory", test.isDirectory()); + + assertTrue("Delete Succeeded ", !FileUtils.delete(test, true)); + } + + public void testDeleteNull() + { + try + { + FileUtils.delete(null, true); + fail("Delete with null value should throw NPE."); + } + catch (NullPointerException npe) + { + // expected path + } + } + + /** * Given two lists of File arrays ensure they are the same length and all entries in Before are in After * diff --git a/qpid/java/cpp.cluster.testprofile b/qpid/java/cpp.cluster.testprofile index 1807ae098b..765eb714f3 100644 --- a/qpid/java/cpp.cluster.testprofile +++ b/qpid/java/cpp.cluster.testprofile @@ -3,3 +3,6 @@ broker=${project.root}/../cpp/src/qpidd --load-module ${project.root}/../cpp/src test.excludesfile=${project.root}/ExcludeList ${project.root}/XAExcludeList ${project.root}/010ExcludeList profile.clustered=true +profile.failoverMsgCount=10 +profile.failoverIterations=10 +profile.failoverRandomSeed=20080921 diff --git a/qpid/java/lib/commons-beanutils-core-1.8.0.jar b/qpid/java/lib/commons-beanutils-core-1.8.0.jar Binary files differnew file mode 100644 index 0000000000..87c15f4565 --- /dev/null +++ b/qpid/java/lib/commons-beanutils-core-1.8.0.jar diff --git a/qpid/java/lib/commons-configuration-1.2.jar b/qpid/java/lib/commons-configuration-1.2.jar Binary files differdeleted file mode 100644 index 574d0ac789..0000000000 --- a/qpid/java/lib/commons-configuration-1.2.jar +++ /dev/null diff --git a/qpid/java/lib/commons-configuration-1.6.jar b/qpid/java/lib/commons-configuration-1.6.jar Binary files differnew file mode 100644 index 0000000000..2d4689a1b8 --- /dev/null +++ b/qpid/java/lib/commons-configuration-1.6.jar diff --git a/qpid/java/lib/commons-digester-1.8.1.jar b/qpid/java/lib/commons-digester-1.8.1.jar Binary files differnew file mode 100644 index 0000000000..7abda9696a --- /dev/null +++ b/qpid/java/lib/commons-digester-1.8.1.jar diff --git a/qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar b/qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar Binary files differnew file mode 100644 index 0000000000..d9b4c8ea1f --- /dev/null +++ b/qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA Binary files differnew file mode 100644 index 0000000000..df6b24ad57 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF new file mode 100644 index 0000000000..4193e97338 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF @@ -0,0 +1,17 @@ +Signature-Version: 1.0
+SHA1-Digest-Manifest: gnfArgp6eM77c1JxQF9X3q9/Hd8=
+Created-By: 1.5.0 (IBM Corporation)
+SHA1-Digest-Manifest-Main-Attributes: hR6QNnvCGlzBxiyTmh4DMZ03Yyg=
+
+Name: about.html
+SHA1-Digest: xGcp/Hbq/ywyvVWkPzD/2vkIzdY=
+
+Name: eclipse_1115.so
+SHA1-Digest: 33jSy/p2jY6bvgg4W0xBlxjxMWA=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: SAqY+5ITAL0mkdYeijlSRhyIaZk=
+
+Name: launcher.gtk.linux.x86_64.properties
+SHA1-Digest: Q2rsj7VmfkLLH24miqu0v+2sZjE=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..b790c0af9a --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0
+Bundle-SymbolicName: org.eclipse.equinox.launcher.gtk.linux.x86_64;sin
+ gleton:=true
+Bundle-ManifestVersion: 2
+Bundle-Localization: launcher.gtk.linux.x86_64
+Bundle-Name: %pluginName
+Eclipse-PlatformFilter: (& (osgi.ws=gtk) (osgi.os=linux) (osgi.arch=x8
+ 6_64))
+Bundle-Version: 1.0.101.R34x_v20080731
+Fragment-Host: org.eclipse.equinox.launcher;bundle-version="[1.0.0,1.1
+ .0)"
+Bundle-Vendor: %providerName
+
+Name: eclipse_1115.so
+SHA1-Digest: l0VkVxLXANjcUEWTLRqXKUmIfn8=
+
+Name: about.html
+SHA1-Digest: a9lDHrGuLPkvHBUhsqWU+V2mhPw=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: KyT9FF7C7t86NoBoa2kZT3ZJBfw=
+
+Name: launcher.gtk.linux.x86_64.properties
+SHA1-Digest: thXaNI0tmsHrCOYNbQBW2zzAh+Q=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf new file mode 100644 index 0000000000..7864d3c4c3 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf @@ -0,0 +1,3 @@ +#Processed using Jarprocessor +pack200.args = -E4 +pack200.conditioned = true diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html new file mode 100644 index 0000000000..395df3ba90 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>June 5, 2006</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). +Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license +that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + +</body> +</html>
\ No newline at end of file diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.so b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.so Binary files differnew file mode 100644 index 0000000000..8bf855533c --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.so diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties new file mode 100644 index 0000000000..da448aadbb --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +pluginName = Equinox Launcher Linux X86_64 Fragment +providerName = Eclipse.org diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA Binary files differnew file mode 100644 index 0000000000..81599f2e21 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF new file mode 100644 index 0000000000..20fe507cdf --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF @@ -0,0 +1,17 @@ +Signature-Version: 1.0
+SHA1-Digest-Manifest: kR1kAxZlcW3W0rm/xjIZED9LrAo=
+Created-By: 1.5.0 (IBM Corporation)
+SHA1-Digest-Manifest-Main-Attributes: pqNWWWTyBz8hsANASpU3hoVl9kc=
+
+Name: about.html
+SHA1-Digest: xGcp/Hbq/ywyvVWkPzD/2vkIzdY=
+
+Name: eclipse_1115.so
+SHA1-Digest: o5PGzpcLRdWF5shzEwmVFCwZrb0=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: SAqY+5ITAL0mkdYeijlSRhyIaZk=
+
+Name: launcher.gtk.solaris.sparc.properties
+SHA1-Digest: gu+HrnaK+kn508ppLY/iXys12yA=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..f81e6141bb --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0
+Bundle-SymbolicName: org.eclipse.equinox.launcher.gtk.solaris.sparc;si
+ ngleton:=true
+Bundle-ManifestVersion: 2
+Bundle-Localization: launcher.gtk.solaris.sparc
+Bundle-Name: %pluginName
+Eclipse-PlatformFilter: (& (osgi.ws=gtk) (osgi.os=solaris) (osgi.arch=
+ sparc))
+Bundle-Version: 1.0.101.R34x_v20080731
+Fragment-Host: org.eclipse.equinox.launcher;bundle-version="[1.0.0,1.1
+ .0)"
+Bundle-Vendor: %providerName
+
+Name: eclipse_1115.so
+SHA1-Digest: 5km5rPngvbWH3aWIYrl+xMejhCE=
+
+Name: about.html
+SHA1-Digest: a9lDHrGuLPkvHBUhsqWU+V2mhPw=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: KyT9FF7C7t86NoBoa2kZT3ZJBfw=
+
+Name: launcher.gtk.solaris.sparc.properties
+SHA1-Digest: B/N7qN8v4Os5flFl4mE2UaqnMZs=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf new file mode 100644 index 0000000000..7864d3c4c3 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf @@ -0,0 +1,3 @@ +#Processed using Jarprocessor +pack200.args = -E4 +pack200.conditioned = true diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html new file mode 100644 index 0000000000..395df3ba90 --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>June 5, 2006</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). +Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license +that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + +</body> +</html>
\ No newline at end of file diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.so b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.so Binary files differnew file mode 100644 index 0000000000..3d8beb88dd --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.so diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties new file mode 100644 index 0000000000..c3f2ae186e --- /dev/null +++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties @@ -0,0 +1,12 @@ +############################################################################### +# Copyright (c) 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +pluginName = Equinox Launcher Sparc Fragment +providerName = Eclipse.org diff --git a/qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar b/qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar Binary files differnew file mode 100644 index 0000000000..95909028d4 --- /dev/null +++ b/qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar diff --git a/qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar b/qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar Binary files differnew file mode 100644 index 0000000000..d7143505a4 --- /dev/null +++ b/qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar diff --git a/qpid/java/management/client/bin/qman-wsdm-start.cmd b/qpid/java/management/client/bin/qman-wsdm-start.cmd index 4e80177521..df30ce8617 100644 --- a/qpid/java/management/client/bin/qman-wsdm-start.cmd +++ b/qpid/java/management/client/bin/qman-wsdm-start.cmd @@ -58,7 +58,6 @@ SET CLASSPATH=%QMAN_HOME%\etc SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\start.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-6.1.14.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-util-6.1.14.jar
-SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-util-6.1.14.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\geronimo-servlet_2.5_spec-1.2.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-api-1.4.0.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-log4j12-1.4.0.jar
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.sh b/qpid/java/management/client/bin/qman-wsdm-start.sh index 239d1bf2f0..39a4cba66e 100644 --- a/qpid/java/management/client/bin/qman-wsdm-start.sh +++ b/qpid/java/management/client/bin/qman-wsdm-start.sh @@ -58,7 +58,7 @@ ADMIN_KEY=gazzax QMAN_LIBS=$QMAN_HOME/lib JETTY_CONFIG_FILE=$QMAN_HOME/etc/jetty.xml -QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_LIBS/start.jar:$QMAN_LIBS/jetty-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/geronimo-servlet_2.5_spec-1.2.jar:$QMAN_LIBS/slf4j-api-1.4.0.jar:$QMAN_LIBS/slf4j-log4j12-1.4.0.jar:$QMAN_LIBS/log4j-1.2.12.jar +QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_LIBS/start.jar:$QMAN_LIBS/jetty-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/geronimo-servlet_2.5_spec-1.2.jar:$QMAN_LIBS/slf4j-api-1.4.0.jar:$QMAN_LIBS/slf4j-log4j12-1.4.0.jar:$QMAN_LIBS/log4j-1.2.12.jar echo "===============================================================================" echo"" diff --git a/qpid/java/management/client/build.xml b/qpid/java/management/client/build.xml index 6543a569ee..729c15e2a6 100644 --- a/qpid/java/management/client/build.xml +++ b/qpid/java/management/client/build.xml @@ -25,7 +25,6 @@ <import file="../../module.xml"/> - <property name="war.name" value="qman.war"/> <property name="build.root" value="${module.build}"/> <property name="web.module" value="${module.build}${file.separator}wsdm-module"/> <property name="web-inf.folder" value="${web.module}${file.separator}WEB-INF"/> @@ -49,7 +48,6 @@ </copy> </target> - <target name="libs-release" description="copy dependencies into module release"> <copy todir="${module.release}${file.separator}" failonerror="true" verbose="true"> <fileset dir="${build}" casesensitive="yes" includes="${module.libs}"> @@ -59,6 +57,8 @@ <not><filename name="**/*xalan*"/></not> <not><filename name="**/*wsdl*"/></not> <not><filename name="**/*muse*"/></not> + <not><filename name="**/*jsp*"/></not> + <not><filename name="**/*core-3.1.1.jar*"/></not> </fileset> </copy> <copy todir="${module.release}${file.separator}lib" failonerror="true"> @@ -195,7 +195,7 @@ <batchtest fork="${test.fork}" todir="${module.results}"> <fileset dir="${module.test.src}" excludes="${module.test.excludes}"> - <include name="**/${test}.java"/> + <include name="**/${test}.java"/> </fileset> </batchtest> </junit> diff --git a/qpid/java/management/client/console/brokers_management.jsp b/qpid/java/management/client/console/brokers_management.jsp index ab9da15d29..449eabfcc1 100644 --- a/qpid/java/management/client/console/brokers_management.jsp +++ b/qpid/java/management/client/console/brokers_management.jsp @@ -97,7 +97,7 @@ Virtual Host :
</td>
<td>
- <input type="text" name="port"/>
+ <input type="text" name="virtualHost"/>
</td>
<td style="font-size: x-small;">
The virtual host name.
diff --git a/qpid/java/management/client/console/fragments/menu.jsp b/qpid/java/management/client/console/fragments/menu.jsp index 5833f209ad..971123e996 100644 --- a/qpid/java/management/client/console/fragments/menu.jsp +++ b/qpid/java/management/client/console/fragments/menu.jsp @@ -3,8 +3,8 @@ <a href="<%=request.getContextPath()%>/console"> > System Overview</a>
<a href="<%=request.getContextPath()%>/brokers_management"> > Brokers Management</a>
<a href="<%=request.getContextPath()%>/resources_management"> > Resources Management</a>
- <a href="<%=request.getContextPath()%>/tbd.jsp"> > Subscriptions Management</a>
- <a href="<%=request.getContextPath()%>/tbd.jsp"> > System Health</a>
+ <a> > Subscriptions Management</a>
+ <a> > System Health</a>
<a href="<%=request.getContextPath()%>/logging_configuration"> > Logging Configuration</a>
</div>
</div>
diff --git a/qpid/java/management/client/console/wsdl-viewer.xsl b/qpid/java/management/client/console/wsdl-viewer.xsl deleted file mode 100644 index c3c9767e10..0000000000 --- a/qpid/java/management/client/console/wsdl-viewer.xsl +++ /dev/null @@ -1,2523 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-
-<!--
-* ====================================================================
-* wsdl-viewer.xsl
-* Version: 3.1.02
-*
-* URL: http://tomi.vanek.sk/xml/wsdl-viewer.xsl
-*
-* Author: tomi vanek
-* Inspiration: Uche Ogbui - WSDL processing with XSLT
-* http://www-106.ibm.com/developerworks/library/ws-trans/index.html
-* ====================================================================
--->
-
-
-<!--
-* ====================================================================
-* Description:
-* wsdl-viewer.xsl is a lightweight XSLT 1.0 transformation with minimal
-* usage of any hacks that extend the possibilities of the transformation
-* over the XSLT 1.0 constraints but eventually would harm the engine independance.
-*
-* The transformation has to run even in the browser offered XSLT engines
-* (tested in IE 6 and Firefox) and in ANT "batch" processing.
-* ====================================================================
-* How to add the HTML look to a WSDL:
-* <?xml version="1.0" encoding="utf-8"?>
-* <?xml-stylesheet type="text/xsl" href="wsdl-viewer.xsl"?>
-* <wsdl:definitions ...>
-* ... Here is the service declaration
-* </wsdl:definitions>
-*
-* The web-browsers (in Windows) are not able by default automatically recognize
-* the ".wsdl" file type (suffix). For the type recognition the WSDL file has
-* to be renamed by adding the suffix ".xml" - i.e. "myservice.wsdl.xml".
-* ====================================================================
-* Constraints:
-* 1. Processing of imported files
-* 1.1 Only 1 imported WSDL and 1 imported XSD is processed
-* (well, maybe with a smarter recursive strategy this restriction could be overcome)
-* 1.2 No recursive including is supported (i.e. includes in included XSD are ignored)
-* 2. Namespace support
-* 2.1 Namespaces are not taken in account by processing (references with NS)
-* 3. Source code
-* 3.1 Only the source code allready processed by the XML parser is rendered - implications:
-* == no access to the XML head line (<?xml version="1.0" encoding="utf-8"?>)
-* == "expanded" CDATA blocks (parser processes the CDATA,
-* XSLT does not have access to the original code)
-* == no control over the code page
-* == processing of special characters
-* == namespace nodes are not rendered (just the namespace aliases)
-* ====================================================================
-* Possible improvements:
-* * Functional requirements
-* + SOAP 1.2 binding (http://schemas.xmlsoap.org/wsdl/soap12/WSDL11SOAP12.pdf)
-* + WSDL 2.0 (http://www.w3.org/TR/2006/CR-wsdl20-primer-20060327/)
-* + Recognition of WSDL patterns (interface, binding, service instance, ...)
-* - Creating an xsd-viewer.xsl for XML-Schema file viewing
-* (extracting the functionality from wsdl-viewer into separate XSLT)
-* - Check the full support of the WSDL and XSD going through the standards
-* - Real-world WSDL testing
-* - XSLT 2.0 (http://www-128.ibm.com/developerworks/library/x-xslt20pt5.html) ???
-* ? Adding more derived information
-* * to be defined, what non-trivial information can we read out from the WSDL
-* * XSLT
-* + Modularization
-* - Is it meaningful?
-* - Maybe more distribution alternatives (modular, fat monolithic, thin performance monolithic)?
-* - Distribution build automatization
-* + Dynamic page: JavaSript
-* + Performance
-* - Better code comments / documentation
-* - SOAP client form - for testing the web service (AJAX based)
-* - New XSD parser - clean-up the algorithm
-* - Complete (recursive, multiple) include support
-* ? Namespace-aware version (no string processing hacks ;-)
-* * I think, because of the goal to support as many engines as possible,
-* this requirement is unrealistic. Maybe when XSLT 2.0 will be supported
-* in a huge majority of platforms, we can rethink this point....
-* (problems with different functionality of namespace-uri XPath function by different engines)
-* * Development architecture
-* - Setup of the development infrastructure
-* - Unit testing
-* ? Collaboration platform
-* * Documentation, web
-* - Better user guide
-* ? Forum, Wiki
-* ====================================================================
--->
-
-
-<!--
-* ====================================================================
-* History:
-* 2005-04-15 - Initial implementation
-* 2005-09-12 - Removed xsl:key to be able to use the James Clark's XT engine on W3C web-site
-* 2006-10-06 - Removed the Oliver Becker's method of conditional selection
-* of a value in a single expression (in Xalan/XSLTC this hack does not work!)
-* 2005-10-07 - Duplicated operations
-* 2006-12-08 - Import element support
-* 2006-12-14 - Displays all fault elements (not just the first one)
-* 2006-12-28 - W3C replaced silently the James Clark's XT engine with Michael Kay's closed-source Saxon!
-* wsdl-viewer.xsl will no longer support XT engine
-* 2007-02-28 - Stack-overflow bug (if the XSD element @name and @type are identic)
-* 2007-03-08 - 3.0.00 - New parsing, new layout
-* 2007-03-28 - 3.0.01 - Fix: New anti-recursion defense (no error message by recursion
-* because of dirty solution of namespace processing)
-* - Added: variables at the top to turn on/off certain details
-* 2007-03-29 - 3.0.02 - Layout clean-up for IE
-* 2007-03-29 - 3.0.03 - Fix: Anti-recursion algorithm
-* 2007-03-30 - 3.0.04 - Added: source code rendering of imported WSDL and XSD
-* 2007-04-15 - 3.0.05 - Fix: Recursive calls in element type rendering
-* - Fix: Rendering of messages (did not render the message types of complex types)
-* - Fix: Links in src. by arrays
-* - Fix: $binding-info
-* 2007-04-15 - 3.0.06 - Added: Extended rendering control ENABLE-xxx parameters
-* - Changed: Anti-recursion algorithm has recursion-depth parameter
-* 2007-07-19 - 3.0.07 - Fix: Rendering of array type in detail
-* 2007-08-01 - 3.0.08 - Fix: xsl:template name="render-type"
-* Fix: typo - "Impotred WSDL" should be "Impotred WSDL"
-* 2007-08-16 - 3.0.09 - Fix: xsl:template name="render-type" - anti recursion
-* 2007-12-05 - 3.1.00 - Modularized
-* 2007-12-23 - 3.1.01 - Terminating message by WS without interface or service definition was removed
-* (seems to be a correct state)
-* 2008-08-20 - 3.1.02 - Woden-214: Anti-recursion bypassed in xsd:choice element
-* ====================================================================
--->
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:ws="http://schemas.xmlsoap.org/wsdl/"
- xmlns:ws2="http://www.w3.org/ns/wsdl"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:local="http://tomi.vanek.sk/xml/wsdl-viewer"
- version="1.0"
- exclude-result-prefixes="ws ws2 xsd soap local">
-
- <xsl:output method="xml" version="1.0" encoding="utf-8" indent="no"
- omit-xml-declaration="no"
- media-type="text/html"
- doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
- doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
-
- <xsl:strip-space elements="*"/>
-
- <xsl:param name="wsdl-viewer.version">3.1.01</xsl:param>
-
-
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-global.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:param name="ENABLE-SERVICE-PARAGRAPH" select="true()"/>
- <xsl:param name="ENABLE-OPERATIONS-PARAGRAPH" select="true()"/>
- <xsl:param name="ENABLE-SRC-CODE-PARAGRAPH" select="true()"/>
- <xsl:param name="ENABLE-ABOUT-PARAGRAPH" select="false()"/>
- <xsl:param name="ENABLE-OPERATIONS-TYPE" select="true()"/>
- <xsl:param name="ENABLE-LINK" select="true()"/>
- <xsl:param name="ENABLE-INOUTFAULT" select="true()"/>
- <xsl:param name="ENABLE-STYLEOPTYPEPATH" select="true()"/>
- <xsl:param name="ENABLE-DESCRIPTION" select="true()"/>
- <xsl:param name="ENABLE-PORTTYPE-NAME" select="true()"/>
- <xsl:param name="ENABLE-ANTIRECURSION-PROTECTION" select="true()"/>
- <xsl:param name="ANTIRECURSION-DEPTH">3</xsl:param>
- <xsl:variable name="GENERATED-BY">Generated by wsdl-viewer.xsl</xsl:variable>
- <xsl:variable name="PORT-TYPE-TEXT">Port type</xsl:variable>
- <xsl:variable name="IFACE-TEXT">Interface</xsl:variable>
- <xsl:variable name="SOURCE-CODE-TEXT">Source code</xsl:variable>
- <xsl:variable name="RECURSIVE"> ... is recursive</xsl:variable>
- <xsl:variable name="SRC-PREFIX">src.</xsl:variable>
- <xsl:variable name="SRC-FILE-PREFIX">src.file.</xsl:variable>
- <xsl:variable name="OPERATIONS-PREFIX">op.</xsl:variable>
- <xsl:variable name="PORT-PREFIX">port.</xsl:variable>
- <xsl:variable name="IFACE-PREFIX">iface.</xsl:variable>
- <xsl:variable name="global.wsdl-name"
- select="/*/*[(local-name() = 'import' or local-name() = 'include') and @location][1]/@location"/>
- <xsl:variable name="consolidated-wsdl" select="/* | document($global.wsdl-name)/*"/>
- <xsl:variable name="global.xsd-name"
- select="($consolidated-wsdl/*[local-name() = 'types']//xsd:import[@schemaLocation] | $consolidated-wsdl/*[local-name() = 'types']//xsd:include[@schemaLocation])[1]/@schemaLocation"/>
- <xsl:variable name="consolidated-xsd"
- select="(document($global.xsd-name)/xsd:schema/xsd:*|/*/*[local-name() = 'types']/xsd:schema/xsd:*)[local-name() = 'complexType' or local-name() = 'element' or local-name() = 'simpleType']"/>
- <xsl:variable name="global.service-name"
- select="concat($consolidated-wsdl/ws:service/@name, $consolidated-wsdl/ws2:service/@name)"/>
- <xsl:variable name="global.binding-name"
- select="concat($consolidated-wsdl/ws:binding/@name, $consolidated-wsdl/ws2:binding/@name)"/>
- <xsl:variable name="html-title">
- <xsl:apply-templates select="/*" mode="html-title.render"/>
- </xsl:variable>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-global.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-css.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:variable name="css">
-
-/**
- wsdl-viewer.css
-*/
-
-/**
-=========================================
- Body
-=========================================
-
-html {
- background-color: #FFFFFF;
-}
-
-body {
- margin: 0;
- padding: 0;
- height: auto;
- color: white;
- background-color: #FFFFFF;
- font: normal Tahoma;
-}
-*/
-#outer_box {
- padding: 3px 3px 3px 194px;
- width: 400px;
-}
-
-#inner_box {
-
- background-color: white;
- color: black;
- font: normal Tahoma;
- font-size : x-small;
-}
-
-/**
-=========================================
- Fixed box with links
-=========================================
-*/
-#outer_links {
- position: fixed;
- left: 0px;
- top: 0px;
- margin: 3px;
- padding: 1px;
- z-index: 200;
- width: 180px;
- height: auto;
- background-color: gainsboro;
- padding-top: 2px;
- border: 1px solid navy;
-}
-
-* html #outer_links /* Override above rule for IE */
-{
- position: absolute;
- width: 188px;
- top: expression(offsetParent.scrollTop + 0);
-}
-
-#links {
- margin: 1px;
- padding: 3px;
- background-color: white;
- height: 350px;
- overflow: auto;
- border: 1px solid navy;
-}
-
-#links ul {
- left: -999em;
- list-style: none;
- margin: 0;
- padding: 0;
- z-index: 100;
-}
-
-#links li {
- margin: 0;
- padding: 2px 4px;
- width: auto;
- z-index: 100;
-}
-
-#links ul li {
- margin: 0;
- padding: 2px 4px;
- width: auto;
- z-index: 100;
-}
-
-#links a {
- display: block;
- padding: 0 2px;
- color: blue;
- width: auto;
- border: 1px solid white;
- text-decoration: none;
- white-space: nowrap;
-}
-
-#links a:hover {
- color: white;
- background-color: gray;
- border: 1px solid gray;
-}
-
-
-/**
-=========================================
- Navigation tabs
-=========================================
-*/
-
-#outer_nav {
- background-color: yellow;
- padding: 0;
- margin: 0;
-}
-
-#nav {
- height: 100%;
- width: auto;
- margin: 0;
- padding: 0;
- background-color: gainsboro;
- border-top: 1px solid gray;
- border-bottom: 3px solid gray;
- z-index: 100;
- font: bold Tahoma;
- letter-spacing: 2px;
-}
-
-#nav ul {
- background-color: gainsboro;
- height: auto;
- width: auto;
- list-style: none;
- margin: 0;
- padding: 0;
- z-index: 100;
-
- border: 1px solid silver;
- border-top-color: black;
- border-width: 1px 0 9px;
-}
-
-#nav li {
- display: inline;
- padding: 0;
- margin: 0;
-}
-
-#nav a {
- position: relative;
- top: 3px;
- float:left;
- width:auto;
- padding: 8px 10px 6px 10px;
- margin: 3px 3px 0;
- border: 1px solid gray;
- border-width: 2px 2px 3px 2px;
-
- color: black;
- background-color: silver;
- text-decoration:none;
- text-transform: uppercase;
-}
-
-#nav a:hover {
- margin-top: 1px;
- padding-top: 9px;
- padding-bottom: 7px;
- color: blue;
- background-color: gainsboro;
-}
-
-#nav a.current:link,
-#nav a.current:visited,
-#nav a.current:hover {
- background: white;
- color: black;
- text-shadow:none;
- margin-top: 0;
- padding-top: 11px;
- padding-bottom: 9px;
- border-bottom-width: 0;
- border-color: #A5CE77;
-}
-
-#nav a:active {
- background-color: silver;
- color: white;
-}
-
-
-
-/**
-=========================================
- Content
-=========================================
-*/
-#header {
- margin: 0;
- padding: .5em 4em;
- color: white;
- background-color: #369;
-}
-
-#content {
- margin: 0;
- padding: 0 2em .5em;
-}
-
-#footer {
- clear: both;
- margin: 0;
- padding: .5em 2em;
- color: gray;
- background-color: gainsboro;
- font-size: 80%;
- border-top: 1px dotted gray;
- text-align: right
-}
-
-.single_column {
- padding: 10px 10px 10px 10px;
- /*margin: 0px 33% 0px 0px; */
- margin: 3px 0;
-}
-
-#flexi_column {
- padding: 10px 10px 10px 10px;
- /*margin: 0px 33% 0px 0px; */
- margin: 0px 212px 0px 0px;
-}
-
-#fix_column {
- float: right;
- padding: 10px 10px 10px 10px;
- margin: 0px;
- width: 205px;
- /*width: 30%; */
- voice-family: "\"}\"";
- voice-family:inherit;
- /* width: 30%; */
- width: 205px;
-}
-html>body #rightColumn {
- width: 205px; /* ie5win fudge ends */
-} /* Opera5.02 shows a 2px gap between. N6.01Win sometimes does.
- Depends on amount of fill and window size and wind direction. */
-
-/**
-=========================================
- Label / value
-=========================================
-*/
-
-.page {
- border-bottom: 3px dotted navy;
- margin: 0;
- padding: 10px 0 20px 0;
-}
-
-.value, .label {
- margin: 0;
- padding: 0;
-}
-
-.label {
- float: left;
- width: 140px;
- text-align: right;
- font-weight: bold;
- padding-bottom: .5em;
- margin-right: 0;
- color: darkblue;
-}
-
-.value {
- margin-left: 147px;
- color: darkblue;
- padding-bottom: .5em;
-}
-
-strong, strong a {
- color: darkblue;
- font-weight: bold;
- letter-spacing: 1px;
- margin-left: 2px;
-}
-
-
-/**
-=========================================
- Links
-=========================================
-*/
-
-a.local:link,
-a.local:visited {
- color: blue;
- margin-left: 10px;
- border-bottom: 1px dotted blue;
- text-decoration: none;
- font-style: italic;
-}
-
-a.local:hover {
- background-color: gainsboro;
- color: darkblue;
- padding-bottom: 1px;
- border-bottom: 1px solid darkblue;
-}
-
-a.target:link,
-a.target:visited,
-a.target:hover
-{
- text-decoration: none;
- background-color: transparent;
- border-bottom-type: none;
-}
-
-/**
-=========================================
- Box, Shadow
-=========================================
-*/
-
-.box {
- padding: 6px;
- color: black;
- background-color: gainsboro;
- border: 1px solid gray;
-}
-
-.shadow {
- background: silver;
- position: relative;
- top: 5px;
- left: 4px;
-}
-
-.shadow div {
- position: relative;
- top: -5px;
- left: -4px;
-}
-
-/**
-=========================================
- Floatcontainer
-=========================================
-*/
-
-.spacer
-{
- display: block;
- height: 0;
- font-size: 0;
- line-height: 0;
- margin: 0;
- padding: 0;
- border-style: none;
- clear: both;
- visibility:hidden;
-}
-
-.floatcontainer:after {
- content: ".";
- display: block;
- height: 0;
- font-size:0;
- clear: both;
- visibility:hidden;
-}
-.floatcontainer{
- display: inline-table;
-} /* Mark Hadley's fix for IE Mac */ /* Hides from IE Mac \*/ *
-html .floatcontainer {
- height: 1%;
-}
-.floatcontainer{
- display:block;
-} /* End Hack
-*/
-
-/**
-=========================================
- Source code
-=========================================
-*/
-
-.indent {
- margin: 2px 0 2px 20px;
-}
-
-.xml-element, .xml-proc, .xml-comment {
- margin: 2px 0;
- padding: 2px 0 2px 0;
-}
-
-.xml-element {
- word-spacing: 3px;
- color: red;
- font-weight: bold;
- font-style:normal;
- border-left: 1px dotted silver;
-}
-
-.xml-element div {
- margin: 2px 0 2px 40px;
-}
-
-.xml-att {
- color: blue;
- font-weight: bold;
-}
-
-.xml-att-val {
- color: blue;
- font-weight: normal;
-}
-
-.xml-proc {
- color: darkred;
- font-weight: normal;
- font-style: italic;
-}
-
-.xml-comment {
- color: green;
- font-weight: normal;
- font-style: italic;
-}
-
-.xml-text {
- color: green;
- font-weight: normal;
- font-style: normal;
-}
-
-
-/**
-=========================================
- Heading
-=========================================
-*/
-h1, h2, h3 {
- margin: 10px 10px 2px;
- font-family: Tahoma;
- font-weight: normal;
- }
-
-h1 {
- font-weight: bold;
- letter-spacing: 3px;
- font-size: 220%;
- line-height: 100%;
-}
-
-h2 {
- font-weight: bold;
- font-size: 175%;
- line-height: 200%;
-}
-
-h3 {
- font-size: 150%;
- line-height: 150%;
- font-style: italic;
-}
-
-/**
-=========================================
- Content formatting
-=========================================
-*/
-.port {
- margin-bottom: 10px;
- padding-bottom: 10px;
- border-bottom: 1px dashed gray;
-}
-
-.operation {
- margin-bottom: 20px;
- padding-bottom: 10px;
- border-bottom: 1px dashed gray;
-}
-
-
-/* --------------------------------------------------------
- Printing
-*/
-
-/*
-@media print
-{
- #outer_links, #outer_nav {
- display: none;
- }
-*/
-
- #outer_box {
- padding: 3px;
- }
-/* END print media definition
-}
-*/
-
-</xsl:variable>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-css.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-util.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="@*" mode="qname.normalized">
- <xsl:variable name="local" select="substring-after(., ':')"/>
- <xsl:choose>
- <xsl:when test="$local">
- <xsl:value-of select="$local"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="."/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="ws:definitions | ws2:description" mode="html-title.render">
- <xsl:choose>
- <xsl:when test="$global.service-name">
- <xsl:value-of select="concat('Service : ', $global.service-name)"/>
- </xsl:when>
- <xsl:when test="$global.binding-name">
- <xsl:value-of select="concat('WS Binding: ', $global.binding-name)"/>
- </xsl:when>
- <xsl:when test="ws2:interface/@name">
- <xsl:value-of select="concat('WS Interface: ', ws2:interface/@name)"/>
- </xsl:when>
- <xsl:otherwise>Web Service Fragment</xsl:otherwise>
- <!-- <xsl:otherwise><xsl:message terminate="yes">Syntax error in element <xsl:call-template name="src.syntax-error.path"/></xsl:message>
- </xsl:otherwise>
--->
- </xsl:choose>
- </xsl:template>
- <xsl:template name="src.syntax-error">
- <xsl:message terminate="yes">Syntax error by WSDL source rendering in element <xsl:call-template name="src.syntax-error.path"/>
- </xsl:message>
- </xsl:template>
- <xsl:template name="src.syntax-error.path">
- <xsl:for-each select="parent::*">
- <xsl:call-template name="src.syntax-error.path"/>
- </xsl:for-each>
- <xsl:value-of select="concat('/', name(), '[', position(), ']')"/>
- </xsl:template>
- <xsl:template match="*[local-name(.) = 'documentation']" mode="documentation.render">
- <xsl:if test="$ENABLE-DESCRIPTION and string-length(.) > 0">
- <div class="label">Description:</div>
- <div class="value">
- <xsl:value-of select="." disable-output-escaping="yes"/>
- </div>
- </xsl:if>
- </xsl:template>
- <xsl:template name="render.source-code-link">
- <xsl:if test="$ENABLE-SRC-CODE-PARAGRAPH and $ENABLE-LINK">
- <a class="local" href="{concat('#', $SRC-PREFIX, generate-id(.))}">
- <xsl:value-of select="$SOURCE-CODE-TEXT"/>
- </a>
- </xsl:if>
- </xsl:template>
- <xsl:template name="about.detail">
- <!-- <xsl:param name="version"/>
- <div>
- This page has been generated by <big>wsdl-viewer.xsl</big>, version <xsl:value-of select="$version"/>
- <br/>
- Author: <a href="http://tomi.vanek.sk/">tomi vanek</a>
- <br/>
- Download at <a href="http://tomi.vanek.sk/xml/wsdl-viewer.xsl">http://tomi.vanek.sk/xml/wsdl-viewer.xsl</a>.<br/>
- <br/>
- The transformation was inspired by the article<br/>
- Uche Ogbuji: <a href="http://www-106.ibm.com/developerworks/library/ws-trans/index.html">WSDL processing with XSLT</a>
- <br/>
- </div>
- </xsl:template>
- <xsl:template name="processor-info.render">
- <xsl:text>
-</xsl:text>
- <xsl:text>This document was generated by </xsl:text>
- <a href="{system-property('xsl:vendor-url')}">
- <xsl:value-of select="system-property('xsl:vendor')"/>
- </a>
- <xsl:text> XSLT engine.
-
-</xsl:text>
-
- <xsl:text>The engine processed the WSDL in XSLT </xsl:text>
- <xsl:value-of select="format-number(system-property('xsl:version'), '#.0')"/>
- <xsl:text> compliant mode.
-</xsl:text>
- -->
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-util.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-service.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="ws:service|ws2:service" mode="service-start">
- <div class="indent">
- <div class="label">Target Namespace:</div>
- <div class="value">
- <xsl:value-of select="$consolidated-wsdl/@targetNamespace"/>
- </div>
- <xsl:apply-templates select="*[local-name(.) = 'documentation']" mode="documentation.render"/>
- <xsl:apply-templates select="ws:port|ws2:endpoint" mode="service"/>
- </div>
- </xsl:template>
- <xsl:template match="ws2:endpoint" mode="service">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:variable name="binding" select="$consolidated-wsdl/ws2:binding[@name = $binding-name]"/>
-
- <xsl:variable name="binding-type" select="$binding/@type"/>
- <xsl:variable name="binding-protocol" select="$binding/@*[local-name() = 'protocol']"/>
- <xsl:variable name="protocol">
- <xsl:choose>
- <xsl:when test="starts-with($binding-type, 'http://schemas.xmlsoap.org/wsdl/soap')">SOAP 1.1</xsl:when>
- <xsl:when test="starts-with($binding-type, 'http://www.w3.org/2005/08/wsdl/soap')">SOAP 1.2</xsl:when>
- <xsl:when test="starts-with($binding-type, 'http://schemas.xmlsoap.org/wsdl/mime')">MIME</xsl:when>
- <xsl:when test="starts-with($binding-type, 'http://schemas.xmlsoap.org/wsdl/http')">HTTP</xsl:when>
- <xsl:otherwise>Unknown</xsl:otherwise>
- </xsl:choose>
-
- <!-- TODO: Add all bindings to transport protocols -->
- <xsl:choose>
- <xsl:when test="starts-with($binding-protocol, 'http://www.w3.org/2003/05/soap/bindings/HTTP')"> over HTTP</xsl:when>
- <xsl:otherwise/>
- </xsl:choose>
- </xsl:variable>
-
- <div class="label">Location:</div>
- <div class="value">
- <xsl:value-of select="@address"/>
- </div>
-
- <div class="label">Protocol:</div>
- <div class="value">
- <xsl:value-of select="$protocol"/>
- </div>
-
- <xsl:apply-templates select="$binding" mode="service"/>
-
- <xsl:variable name="iface-name">
- <xsl:apply-templates select="../@interface" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[@name = $iface-name]" mode="service"/>
-
- </xsl:template>
- <xsl:template match="ws2:interface" mode="service">
- <h3>Interface <b>
- <xsl:value-of select="@name"/>
- </b>
- <xsl:if test="$ENABLE-LINK">
- <xsl:text> </xsl:text>
- <span>
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <a class="local" href="#{concat($PORT-PREFIX, generate-id(.))}">
- <xsl:value-of select="$PORT-TYPE-TEXT"/>
- </a>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- </span>
- </xsl:if>
- </h3>
-
- <xsl:variable name="base-iface-name">
- <xsl:apply-templates select="@extends" mode="qname.normalized"/>
- </xsl:variable>
-
- <xsl:if test="$base-iface-name">
- <div class="label">Extends: </div>
- <div class="value">
- <xsl:value-of select="$base-iface-name"/>
- </div>
- </xsl:if>
-
- <xsl:variable name="base-iface"
- select="$consolidated-wsdl/ws2:interface[@name = $base-iface-name]"/>
-
- <div class="label">Operations:</div>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <ol style="line-height: 180%;">
- <xsl:apply-templates select="$base-iface/ws2:operation | ws2:operation" mode="service">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </div>
- </xsl:template>
- <xsl:template match="ws:port" mode="service">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:variable name="binding" select="$consolidated-wsdl/ws:binding[@name = $binding-name]"/>
-
- <xsl:variable name="binding-uri"
- select="namespace-uri( $binding/*[local-name() = 'binding'] )"/>
- <xsl:variable name="protocol">
- <xsl:choose>
- <xsl:when test="starts-with($binding-uri, 'http://schemas.xmlsoap.org/wsdl/soap')">SOAP</xsl:when>
- <xsl:when test="starts-with($binding-uri, 'http://schemas.xmlsoap.org/wsdl/mime')">MIME</xsl:when>
- <xsl:when test="starts-with($binding-uri, 'http://schemas.xmlsoap.org/wsdl/http')">HTTP</xsl:when>
- <xsl:otherwise>unknown</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="port-type-name">
- <xsl:apply-templates select="$binding/@type" mode="qname.normalized"/>
- </xsl:variable>
-
- <xsl:variable name="port-type"
- select="$consolidated-wsdl/ws:portType[@name = $port-type-name]"/>
-
-
- <h3>Port <b>
- <xsl:value-of select="@name"/>
- </b>
- <xsl:if test="$ENABLE-LINK">
- <xsl:text> </xsl:text>
- <!-- <small>-->
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <a class="local" href="#{concat($PORT-PREFIX, generate-id($port-type))}">
- <xsl:value-of select="$PORT-TYPE-TEXT"/>
- </a>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- <!-- </small>-->
- </xsl:if>
- </h3>
-
- <div class="label">Location:</div>
- <div class="value">
- <xsl:value-of select="*[local-name() = 'address']/@location"/>
- </div>
-
- <div class="label">Protocol:</div>
- <div class="value">
- <xsl:value-of select="$protocol"/>
- </div>
-
- <xsl:apply-templates select="$binding" mode="service"/>
-
- <div class="label">Operations:</div>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <ol style="line-height: 180%;">
- <xsl:apply-templates select="$consolidated-wsdl/ws:portType[@name = $port-type-name]/ws:operation"
- mode="service">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </div>
- </xsl:template>
- <xsl:template match="ws:operation|ws2:operation" mode="service">
- <li>
- <big>
- <i>
- <xsl:value-of select="@name"/>
- </i>
- </big>
- <xsl:if test="$ENABLE-LINK">
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <a class="local" href="{concat('#', $OPERATIONS-PREFIX, generate-id(.))}">Detail</a>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- </xsl:if>
- </li>
- </xsl:template>
- <xsl:template match="ws:binding|ws2:binding" mode="service">
- <xsl:variable name="real-binding" select="*[local-name() = 'binding']|self::ws2:*"/>
-
- <xsl:if test="$real-binding/@style">
- <div class="label">Default style:</div>
- <div class="value">
- <xsl:value-of select="$real-binding/@style"/>
- </div>
- </xsl:if>
-
-
- <xsl:if test="$real-binding/@transport|$real-binding/*[local-name() = 'protocol']">
- <xsl:variable name="protocol"
- select="concat($real-binding/@transport, $real-binding/*[local-name() = 'protocol'])"/>
- <div class="label">Transport protocol:</div>
- <div class="value">
- <xsl:choose>
- <xsl:when test="$protocol = 'http://schemas.xmlsoap.org/soap/http'">SOAP over HTTP</xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$protocol"/>
- </xsl:otherwise>
- </xsl:choose>
- </div>
- </xsl:if>
-
- <xsl:if test="$real-binding/@verb">
- <div class="label">Default method:</div>
- <div class="value">
- <xsl:value-of select="$real-binding/@verb"/>
- </div>
- </xsl:if>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-service.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-operations.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="ws2:interface" mode="operations">
- <xsl:if test="$ENABLE-PORTTYPE-NAME">
- <h3>
- <a name="{concat($IFACE-PREFIX, generate-id(.))}">
- <xsl:value-of select="$IFACE-TEXT"/>
- <xsl:text>
-</xsl:text>
- <b>
- <xsl:value-of select="@name"/>
- </b>
- </a>
- <xsl:call-template name="render.source-code-link"/>
- </h3>
- </xsl:if>
-
- <ol>
- <xsl:apply-templates select="ws2:operation" mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </xsl:template>
- <xsl:template match="ws2:operation" mode="operations">
- <xsl:variable name="binding-info"
- select="$consolidated-wsdl/ws2:binding[@interface = current()/../@name or substring-after(@interface, ':') = current()/../@name]/ws2:operation[@ref = current()/@name or substring-after(@ref, ':') = current()/@name]"/>
- <li>
- <xsl:if test="position() != last()">
- <xsl:attribute name="class">operation</xsl:attribute>
- </xsl:if>
- <big>
- <b>
- <a name="{concat($OPERATIONS-PREFIX, generate-id(.))}">
- <xsl:value-of select="@name"/>
- </a>
- </b>
- </big>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <xsl:call-template name="render.source-code-link"/>
- </div>
- <xsl:apply-templates select="ws2:documentation" mode="documentation.render"/>
-
- <xsl:if test="$ENABLE-STYLEOPTYPEPATH">
- <!-- TODO: add the operation attributes - according the WSDL 2.0 spec. -->
- </xsl:if>
- <xsl:apply-templates select="ws2:input|ws2:output|../ws2:fault[@name = ws2:infault/@ref or @name = ws2:outfault/@ref]"
- mode="operations.message">
- <xsl:with-param name="binding-data" select="$binding-info"/>
- </xsl:apply-templates>
- </li>
- </xsl:template>
- <xsl:template match="ws2:input|ws2:output|ws2:fault" mode="operations.message">
- <xsl:param name="binding-data"/>
- <xsl:if test="$ENABLE-INOUTFAULT">
- <div class="label">
- <xsl:value-of select="concat(translate(substring(local-name(.), 1, 1), 'abcdefghijklmnoprstuvwxyz', 'ABCDEFGHIJKLMNOPRSTUVWXYZ'), substring(local-name(.), 2), ':')"/>
- </div>
-
- <div class="value">
- <xsl:variable name="type-name">
- <xsl:apply-templates select="@element" mode="qname.normalized"/>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:call-template name="render.source-code-link"/>
-
- <xsl:variable name="type-tree"
- select="$consolidated-xsd[@name = $type-name and not(xsd:simpleType)][1]"/>
- <xsl:apply-templates select="$type-tree" mode="operations.message.part"/>
- </div>
- </xsl:if>
- </xsl:template>
- <xsl:template match="ws:portType" mode="operations">
- <div>
- <xsl:if test="position() != last()">
- <xsl:attribute name="class">port</xsl:attribute>
- </xsl:if>
- <xsl:if test="$ENABLE-PORTTYPE-NAME">
- <h3>
- <a name="{concat($PORT-PREFIX, generate-id(.))}">
- <xsl:value-of select="$PORT-TYPE-TEXT"/>
- <xsl:text>
-</xsl:text>
- <b>
- <xsl:value-of select="@name"/>
- </b>
- </a>
- <xsl:call-template name="render.source-code-link"/>
- </h3>
- </xsl:if>
- <ol>
- <xsl:apply-templates select="ws:operation" mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </div>
- </xsl:template>
- <xsl:template match="ws:operation" mode="operations">
- <xsl:variable name="binding-info"
- select="$consolidated-wsdl/ws:binding[@type = current()/../@name or substring-after(@type, ':') = current()/../@name]/ws:operation[@name = current()/@name]"/>
- <li>
- <xsl:if test="position() != last()">
- <xsl:attribute name="class">operation</xsl:attribute>
- </xsl:if>
- <big>
- <b>
- <a name="{concat($OPERATIONS-PREFIX, generate-id(.))}">
- <xsl:value-of select="@name"/>
- </a>
- </b>
- </big>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <xsl:call-template name="render.source-code-link"/>
- </div>
-
- <xsl:if test="$ENABLE-DESCRIPTION and string-length(ws:documentation) > 0">
- <div class="label">Description:</div>
- <div class="value">
- <xsl:value-of select="ws:documentation" disable-output-escaping="yes"/>
- </div>
- </xsl:if>
-
- <xsl:if test="$ENABLE-STYLEOPTYPEPATH">
- <xsl:variable name="binding-operation" select="$binding-info/*[local-name() = 'operation']"/>
- <xsl:if test="$binding-operation/@style">
- <div class="label">Style:</div>
- <div class="value">
- <xsl:value-of select="$binding-operation/@style"/>
- </div>
- </xsl:if>
-
- <div class="label">Operation type:</div>
- <div class="value">
- <xsl:choose>
- <xsl:when test="$binding-info/ws:input[not(../ws:output)]">
- <i>One-way.</i> The endpoint receives a message.</xsl:when>
- <xsl:when test="$binding-info/ws:input[following-sibling::ws:output]">
- <i>Request-response.</i> The endpoint receives a message, and sends a correlated message.</xsl:when>
- <xsl:when test="$binding-info/ws:input[preceding-sibling::ws:output]">
- <i>Solicit-response.</i> The endpoint sends a message, and receives a correlated message.</xsl:when>
- <xsl:when test="$binding-info/ws:output[not(../ws:input)]">
- <i>Notification.</i> The endpoint sends a message.</xsl:when>
- <xsl:otherwise>unknown</xsl:otherwise>
- </xsl:choose>
- </div>
-
- <xsl:if test="string-length($binding-operation/@soapAction) > 0">
- <div class="label">SOAP action:</div>
- <div class="value">
- <xsl:value-of select="$binding-operation/@soapAction"/>
- </div>
- </xsl:if>
-
- <xsl:if test="$binding-operation/@location">
- <div class="label">HTTP path:</div>
- <div class="value">
- <xsl:value-of select="$binding-operation/@location"/>
- </div>
- </xsl:if>
- </xsl:if>
- <xsl:apply-templates select="ws:input|ws:output|ws:fault" mode="operations.message">
- <xsl:with-param name="binding-data" select="$binding-info"/>
- </xsl:apply-templates>
- </li>
- </xsl:template>
- <xsl:template match="ws:input|ws:output|ws:fault" mode="operations.message">
- <xsl:param name="binding-data"/>
- <xsl:if test="$ENABLE-INOUTFAULT">
- <div class="label">
- <xsl:value-of select="concat(translate(substring(local-name(.), 1, 1), 'abcdefghijklmnoprstuvwxyz', 'ABCDEFGHIJKLMNOPRSTUVWXYZ'), substring(local-name(.), 2), ':')"/>
- </div>
-
- <xsl:variable name="msg-local-name" select="substring-after(@message, ':')"/>
- <xsl:variable name="msg-name">
- <xsl:choose>
- <xsl:when test="$msg-local-name">
- <xsl:value-of select="$msg-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@message"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="msg" select="$consolidated-wsdl/ws:message[@name = $msg-name]"/>
- <xsl:choose>
- <xsl:when test="$msg">
- <xsl:apply-templates select="$msg" mode="operations.message">
- <xsl:with-param name="binding-data"
- select="$binding-data/ws:*[local-name(.) = local-name(current())]/*"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <div class="value">
- <i>none</i>
- </div>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
- <xsl:template match="ws:message" mode="operations.message">
- <xsl:param name="binding-data"/>
- <div class="value">
- <xsl:value-of select="@name"/>
- <xsl:if test="$binding-data">
- <xsl:text> (</xsl:text>
- <xsl:value-of select="name($binding-data)"/>
- <xsl:variable name="use" select="$binding-data/@use"/>
- <xsl:if test="$use">
- <xsl:text>, use = </xsl:text>
- <xsl:value-of select="$use"/>
- </xsl:if>
- <xsl:variable name="part" select="$binding-data/@part"/>
- <xsl:if test="$part">
- <xsl:text>, part = </xsl:text>
- <xsl:value-of select="$part"/>
- </xsl:if>
- <xsl:text>)</xsl:text>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- </div>
-
- <xsl:apply-templates select="ws:part" mode="operations.message"/>
- </xsl:template>
- <xsl:template match="ws:part" mode="operations.message">
- <div class="value box" style="margin-bottom: 3px">
- <xsl:choose>
- <xsl:when test="string-length(@name) > 0">
- <b>
- <xsl:value-of select="@name"/>
- </b>
-
- <xsl:variable name="elem-or-type">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@element"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="type-local-name" select="substring-after($elem-or-type, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="$elem-or-type">
- <xsl:value-of select="$elem-or-type"/>
- </xsl:when>
- <xsl:otherwise>unknown</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:variable name="part-type"
- select="$consolidated-xsd[@name = $type-name and not(xsd:simpleType)][1]"/>
- <xsl:apply-templates select="$part-type" mode="operations.message.part"/>
-
- </xsl:when>
- <xsl:otherwise>
- <i>none</i>
- </xsl:otherwise>
- </xsl:choose>
- </div>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-operations.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-xsd-tree.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="xsd:simpleType" mode="operations.message.part"/>
- <xsl:template name="recursion.should.continue">
- <xsl:param name="anti.recursion"/>
- <xsl:param name="recursion.label"/>
- <xsl:param name="recursion.count">1</xsl:param>
- <xsl:variable name="has.recursion" select="contains($anti.recursion, $recursion.label)"/>
- <xsl:variable name="anti.recursion.fragment"
- select="substring-after($anti.recursion, $recursion.label)"/>
- <xsl:choose>
- <xsl:when test="$recursion.count > $ANTIRECURSION-DEPTH"/>
-
- <xsl:when test="not($ENABLE-ANTIRECURSION-PROTECTION) or string-length($anti.recursion) = 0 or not($has.recursion)">
- <xsl:text>1</xsl:text>
- </xsl:when>
-
- <xsl:otherwise>
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion.fragment"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- <xsl:with-param name="recursion.count" select="$recursion.count + 1"/>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="xsd:complexType" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
-
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
- <xsl:template match="xsd:complexContent" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
-
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:complexType[descendant::xsd:attribute[ not(@*[local-name() = 'arrayType']) ]]"
- mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <ul type="circle">
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </ul>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="xsd:restriction | xsd:extension" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="type-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@base">
- <xsl:value-of select="@base"/>
- </xsl:when>
- <xsl:otherwise>unknown type</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="base-type" select="$consolidated-xsd[@name = $type-name][1]"/>
- <!-- xsl:if test="not($type/@abstract)">
- <xsl:apply-templates select="$type"/>
- </xsl:if -->
- <xsl:if test="$base-type != 'Array'">
- <xsl:apply-templates select="$base-type" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:if>
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:union" mode="operations.message.part">
- <xsl:call-template name="process-union">
- <xsl:with-param name="set" select="@memberTypes"/>
- </xsl:call-template>
- </xsl:template>
- <xsl:template name="process-union">
- <xsl:param name="set"/>
- <xsl:if test="$set">
- <xsl:variable name="item" select="substring-before($set, ' ')"/>
- <xsl:variable name="the-rest" select="substring-after($set, ' ')"/>
-
- <xsl:variable name="type-local-name" select="substring-after($item, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$item"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:call-template name="process-union">
- <xsl:with-param name="set" select="$the-rest"/>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
- <xsl:template match="xsd:sequence" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <ul type="square">
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </ul>
- </xsl:template>
- <xsl:template match="xsd:all|xsd:any|xsd:choice" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="list-type">
- <xsl:choose>
- <xsl:when test="self::xsd:all">disc</xsl:when>
- <xsl:when test="self::xsd:any">circle</xsl:when>
- <xsl:otherwise>square</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:element name="ul">
- <xsl:attribute name="style">
- <xsl:value-of select="concat('list-style-type:', $list-type)"/>
- </xsl:attribute>
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:element>
- </xsl:template>
- <xsl:template match="xsd:element[parent::xsd:schema]" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <xsl:variable name="type-name">
- <xsl:call-template name="xsd.element-type"/>
- </xsl:variable>
- <xsl:variable name="elem-type"
- select="$consolidated-xsd[generate-id() != generate-id(current()) and $type-name and @name=$type-name and contains(local-name(), 'Type')][1]"/>
-
- <xsl:if test="$type-name != @name">
- <xsl:apply-templates select="$elem-type" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
-
- <xsl:if test="not($elem-type)">
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
- <xsl:template match="xsd:element | xsd:attribute" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <!--
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
--->
- <li>
- <xsl:variable name="local-ref" select="concat(@name, substring-after(@ref, ':'))"/>
- <xsl:variable name="elem-name">
- <xsl:choose>
- <xsl:when test="@name">
- <xsl:value-of select="@name"/>
- </xsl:when>
- <xsl:when test="$local-ref">
- <xsl:value-of select="$local-ref"/>
- </xsl:when>
- <xsl:when test="@ref">
- <xsl:value-of select="@ref"/>
- </xsl:when>
- <xsl:otherwise>anonymous</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="$elem-name"/>
-
- <xsl:variable name="type-name">
- <xsl:call-template name="xsd.element-type"/>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:variable name="elem-type"
- select="$consolidated-xsd[@name = $type-name and contains(local-name(), 'Type')][1]"/>
- <xsl:apply-templates select="$elem-type | *" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </li>
- </xsl:template>
- <xsl:template match="xsd:attribute[ @*[local-name() = 'arrayType'] ]"
- mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="array-local-name"
- select="substring-after(@*[local-name() = 'arrayType'], ':')"/>
- <xsl:variable name="type-local-name" select="substring-before($array-local-name, '[')"/>
- <xsl:variable name="array-type" select="$consolidated-xsd[@name = $type-local-name][1]"/>
-
- <xsl:variable name="recursion.label" select="concat('[', $type-local-name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <xsl:apply-templates select="$array-type" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template name="xsd.element-type">
- <xsl:variable name="ref-or-type">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@ref"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="type-local-name" select="substring-after($ref-or-type, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="$ref-or-type">
- <xsl:value-of select="$ref-or-type"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="$type-name"/>
- </xsl:template>
- <xsl:template match="xsd:documentation" mode="operations.message.part">
- <div style="color:green">
- <xsl:value-of select="." disable-output-escaping="yes"/>
- </div>
- </xsl:template>
- <xsl:template name="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:param name="type-local-name"/>
-
- <xsl:if test="$ENABLE-OPERATIONS-TYPE">
- <xsl:variable name="properties">
- <xsl:if test="self::xsd:element | self::xsd:attribute[parent::xsd:complexType]">
- <xsl:variable name="min">
- <xsl:if test="@minOccurs = '0'">optional</xsl:if>
- </xsl:variable>
- <xsl:variable name="max">
- <xsl:if test="@maxOccurs = 'unbounded'">unbounded</xsl:if>
- </xsl:variable>
- <xsl:variable name="nillable">
- <xsl:if test="@nillable">nillable</xsl:if>
- </xsl:variable>
-
- <xsl:if test="(string-length($min) + string-length($max) + string-length($nillable) + string-length(@use)) > 0">
- <xsl:text> - </xsl:text>
- <xsl:value-of select="$min"/>
- <xsl:if test="string-length($min) and string-length($max)">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:value-of select="$max"/>
- <xsl:if test="(string-length($min) + string-length($max)) > 0 and string-length($nillable)">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:value-of select="$nillable"/>
- <xsl:if test="(string-length($min) + string-length($max) + string-length($nillable)) > 0 and string-length(@use)">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:value-of select="@use"/>
- <xsl:text>; </xsl:text>
- </xsl:if>
- </xsl:if>
- </xsl:variable>
-
- <xsl:variable name="recursion.label" select="concat('[', $type-local-name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- <xsl:with-param name="recursion.count" select="$ANTIRECURSION-DEPTH"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:if test="string-length($recursion.test) != 0">
- <span style="color:blue">
- <xsl:value-of select="$properties"/>
- <xsl:variable name="elem-type"
- select="$consolidated-xsd[@name = $type-local-name and (not(contains(local-name(current()), 'element')) or contains(local-name(), 'Type'))][1]"/>
- <xsl:if test="string-length($type-local-name) > 0">
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-local-name"/>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:choose>
- <xsl:when test="$elem-type">
-
- <xsl:apply-templates select="$elem-type" mode="render-type">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
-
- <xsl:apply-templates select="*" mode="render-type">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:otherwise>
- </xsl:choose>
- </span>
- </xsl:if>
- </xsl:if>
- </xsl:template>
- <xsl:template name="render-type.write-name">
- <xsl:param name="type-local-name"/>
- <xsl:text> type </xsl:text>
- <big>
- <i>
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </i>
- </big>
- </xsl:template>
- <xsl:template match="*" mode="render-type"/>
- <xsl:template match="xsd:element | xsd:complexType | xsd:simpleType | xsd:complexContent"
- mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:apply-templates select="*" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:restriction[ parent::xsd:simpleType ]" mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="type-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@base">
- <xsl:value-of select="@base"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:text> - </xsl:text>
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-local-name"/>
- </xsl:call-template>
- <xsl:text> with </xsl:text>
- <xsl:value-of select="local-name()"/>
- <xsl:apply-templates select="*" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:simpleType/xsd:restriction/xsd:*[not(self::xsd:enumeration)]"
- mode="render-type">
- <xsl:text> </xsl:text>
- <xsl:value-of select="local-name()"/>
- <xsl:text>(</xsl:text>
- <xsl:value-of select="@value"/>
- <xsl:text>)</xsl:text>
- </xsl:template>
- <xsl:template match="xsd:restriction | xsd:extension" mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="type-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@base">
- <xsl:value-of select="@base"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="base-type" select="$consolidated-xsd[@name = $type-name][1]"/>
- <xsl:variable name="abstract">
- <xsl:if test="$base-type/@abstract">abstract </xsl:if>
- </xsl:variable>
-
- <xsl:if test="not($type-name = 'Array')">
- <xsl:value-of select="concat(' - ', local-name(), ' of ', $abstract)"/>
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:apply-templates select="$base-type | *" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:attribute[ @*[local-name() = 'arrayType'] ]" mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="array-local-name"
- select="substring-after(@*[local-name() = 'arrayType'], ':')"/>
- <xsl:variable name="type-local-name" select="substring-before($array-local-name, '[')"/>
- <xsl:variable name="array-type" select="$consolidated-xsd[@name = $type-local-name][1]"/>
-
- <xsl:text> - array of </xsl:text>
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-local-name"/>
- </xsl:call-template>
-
- <xsl:apply-templates select="$array-type" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:enumeration" mode="render-type"/>
- <xsl:template match="xsd:enumeration[not(preceding-sibling::xsd:enumeration)]"
- mode="render-type">
- <xsl:text> - enum { </xsl:text>
- <xsl:apply-templates select="self::* | following-sibling::xsd:enumeration" mode="render-type.enum"/>
- <xsl:text> }</xsl:text>
- </xsl:template>
- <xsl:template match="xsd:enumeration" mode="render-type.enum">
- <xsl:if test="preceding-sibling::xsd:enumeration">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:text disable-output-escaping="yes">'</xsl:text>
- <xsl:value-of select="@value"/>
- <xsl:text disable-output-escaping="yes">'</xsl:text>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-xsd-tree.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-src.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="@*" mode="src.import">
- <xsl:param name="src.import.stack"/>
- <xsl:variable name="recursion.label" select="concat('[', string(.), ']')"/>
- <xsl:variable name="recursion.check" select="concat($src.import.stack, $recursion.label)"/>
-
- <xsl:choose>
- <xsl:when test="contains($src.import.stack, $recursion.label)">
- <h2 style="red">
- <xsl:value-of select="concat('Cyclic include / import: ', $recursion.check)"/>
- </h2>
- </xsl:when>
- <xsl:otherwise>
- <h2>
- <a name="{concat($SRC-FILE-PREFIX, generate-id(..))}">
- <xsl:choose>
- <xsl:when test="parent::xsd:include">Included </xsl:when>
- <xsl:otherwise>Imported </xsl:otherwise>
- </xsl:choose>
-
- <xsl:choose>
- <xsl:when test="name() = 'location'">WSDL </xsl:when>
- <xsl:otherwise>Schema </xsl:otherwise>
- </xsl:choose>
- <i>
- <xsl:value-of select="."/>
- </i>
- </a>
- </h2>
-
- <div class="box">
- <xsl:apply-templates select="document(string(.))" mode="src"/>
- </div>
-
- <xsl:apply-templates select="document(string(.))/*/*[local-name() = 'import'][@location]/@location"
- mode="src.import">
- <xsl:with-param name="src.import.stack" select="$recursion.check"/>
- </xsl:apply-templates>
- <xsl:apply-templates select="document(string(.))//xsd:import[@schemaLocation]/@schemaLocation"
- mode="src.import">
- <xsl:with-param name="src.import.stack" select="$recursion.check"/>
- </xsl:apply-templates>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="*" mode="src">
- <div class="xml-element">
- <a name="{concat($SRC-PREFIX, generate-id(.))}">
- <xsl:apply-templates select="." mode="src.link"/>
- <xsl:apply-templates select="." mode="src.start-tag"/>
- </a>
- <xsl:apply-templates select="*|comment()|processing-instruction()|text()[string-length(normalize-space(.)) > 0]"
- mode="src"/>
- <xsl:apply-templates select="." mode="src.end-tag"/>
- </div>
- </xsl:template>
- <xsl:template match="*" mode="src.start-tag">
- <xsl:call-template name="src.elem">
- <xsl:with-param name="src.elem.end-slash"> /</xsl:with-param>
- </xsl:call-template>
- </xsl:template>
- <xsl:template match="*[*|comment()|processing-instruction()|text()[string-length(normalize-space(.)) > 0]]"
- mode="src.start-tag">
- <xsl:call-template name="src.elem"/>
- </xsl:template>
- <xsl:template match="*" mode="src.end-tag"/>
- <xsl:template match="*[*|comment()|processing-instruction()|text()[string-length(normalize-space(.)) > 0]]"
- mode="src.end-tag">
- <xsl:call-template name="src.elem">
- <xsl:with-param name="src.elem.start-slash">/</xsl:with-param>
- </xsl:call-template>
- </xsl:template>
- <xsl:template match="*" mode="src.link-attribute">
- <xsl:if test="$ENABLE-LINK">
- <xsl:attribute name="href">
- <xsl:value-of select="concat('#', $SRC-PREFIX, generate-id(.))"/>
- </xsl:attribute>
- </xsl:if>
- </xsl:template>
- <xsl:template match="*[local-name() = 'import' or local-name() = 'include'][@location or @schemaLocation]"
- mode="src.link">
- <xsl:if test="$ENABLE-LINK">
- <xsl:attribute name="href">
- <xsl:value-of select="concat('#', $SRC-FILE-PREFIX, generate-id(.))"/>
- </xsl:attribute>
- </xsl:if>
- </xsl:template>
- <xsl:template match="*" mode="src.link"/>
- <xsl:template match="ws2:service|ws2:binding" mode="src.link">
- <xsl:variable name="iface-name">
- <xsl:apply-templates select="@interface" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[@name = $iface-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:endpoint" mode="src.link">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:binding[@name = $binding-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:binding/ws2:operation" mode="src.link">
- <xsl:variable name="operation-name">
- <xsl:apply-templates select="@ref" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface/ws2:operation[@name = $operation-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:binding/ws2:fault|ws2:interface/ws2:operation/ws2:infault|ws2:interface/ws2:operation/ws2:outfault"
- mode="src.link">
- <xsl:variable name="operation-name">
- <xsl:apply-templates select="@ref" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface/ws2:fault[@name = $operation-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:interface/ws2:operation/ws2:input|ws2:interface/ws2:operation/ws2:output|ws2:interface/ws2:fault"
- mode="src.link">
- <xsl:variable name="elem-name">
- <xsl:apply-templates select="@element" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-xsd[@name = $elem-name]" mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:operation/ws:input[@message] | ws:operation/ws:output[@message] | ws:operation/ws:fault[@message] | soap:header[ancestor::ws:operation and @message]"
- mode="src.link">
- <xsl:apply-templates select="$consolidated-wsdl/ws:message[@name = substring-after( current()/@message, ':' )]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:operation/ws:input[@message] | ws:operation/ws:output[@message] | ws:operation/ws:fault[@message] | soap:header[ancestor::ws:operation and @message]"
- mode="src.link">
- <xsl:apply-templates select="$consolidated-wsdl/ws:message[@name = substring-after( current()/@message, ':' )]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:message/ws:part[@element or @type]" mode="src.link">
- <xsl:variable name="elem-local-name" select="substring-after(@element, ':')"/>
- <xsl:variable name="type-local-name" select="substring-after(@type, ':')"/>
- <xsl:variable name="elem-name">
- <xsl:choose>
- <xsl:when test="$elem-local-name">
- <xsl:value-of select="$elem-local-name"/>
- </xsl:when>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@element">
- <xsl:value-of select="@element"/>
- </xsl:when>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="src.syntax-error"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:apply-templates select="$consolidated-xsd[@name = $elem-name]" mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:service/ws:port[@binding]" mode="src.link">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws:binding[@name = $binding-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:operation[@name and parent::ws:binding/@type]" mode="src.link">
- <xsl:variable name="type-name">
- <xsl:apply-templates select="../@type" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws:portType[@name = $type-name]/ws:operation[@name = current()/@name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="xsd:element[@ref or @type]" mode="src.link">
- <xsl:variable name="ref-or-type">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@ref"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="type-local-name" select="substring-after($ref-or-type, ':')"/>
- <xsl:variable name="xsd-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="$ref-or-type">
- <xsl:value-of select="$ref-or-type"/>
- </xsl:when>
- <xsl:otherwise/>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:if test="$xsd-name">
- <xsl:variable name="msg"
- select="$consolidated-xsd[@name = $xsd-name and contains(local-name(), 'Type')][1]"/>
- <xsl:apply-templates select="$msg" mode="src.link-attribute"/>
- </xsl:if>
- </xsl:template>
- <xsl:template match="xsd:attribute[contains(@ref, 'arrayType')]" mode="src.link">
- <xsl:variable name="att-array-type"
- select="substring-before(@*[local-name() = 'arrayType'], '[]')"/>
- <xsl:variable name="xsd-local-name" select="substring-after($att-array-type, ':')"/>
- <xsl:variable name="xsd-name">
- <xsl:choose>
- <xsl:when test="$xsd-local-name">
- <xsl:value-of select="$xsd-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$att-array-type"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:if test="$xsd-name">
- <xsl:variable name="msg" select="$consolidated-xsd[@name = $xsd-name][1]"/>
- <xsl:apply-templates select="$msg" mode="src.link-attribute"/>
- </xsl:if>
- </xsl:template>
- <xsl:template match="xsd:extension | xsd:restriction" mode="src.link">
- <xsl:variable name="xsd-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="xsd-name">
- <xsl:choose>
- <xsl:when test="$xsd-local-name">
- <xsl:value-of select="$xsd-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@type"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="msg" select="$consolidated-xsd[@name = $xsd-name][1]"/>
- <xsl:apply-templates select="$msg" mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template name="src.elem">
- <xsl:param name="src.elem.start-slash"/>
- <xsl:param name="src.elem.end-slash"/>
-
- <xsl:value-of select="concat('<', $src.elem.start-slash, name(.))"
- disable-output-escaping="no"/>
- <xsl:if test="not($src.elem.start-slash)">
- <xsl:apply-templates select="@*" mode="src"/>
- <xsl:apply-templates select="." mode="src.namespace"/>
- </xsl:if>
- <xsl:value-of select="concat($src.elem.end-slash, '>')" disable-output-escaping="no"/>
- </xsl:template>
- <xsl:template match="@*" mode="src">
- <xsl:text> </xsl:text>
- <span class="xml-att">
- <xsl:value-of select="concat(name(), '=')"/>
- <span class="xml-att-val">
- <xsl:value-of select="concat('"', ., '"')" disable-output-escaping="yes"/>
- </span>
- </span>
- </xsl:template>
- <xsl:template match="*" mode="src.namespace">
- <xsl:variable name="supports-namespace-axis" select="count(/*/namespace::*) > 0"/>
- <xsl:variable name="current" select="current()"/>
-
- <xsl:choose>
- <xsl:when test="count(/*/namespace::*) > 0">
- <!--
- When the namespace axis is present (e.g. Internet Explorer), we can simulate
- the namespace declarations by comparing the namespaces in scope on this element
- with those in scope on the parent element. Any difference must have been the
- result of a namespace declaration. Note that this doesn't reflect the actual
- source - it will strip out redundant namespace declarations.
- -->
- <xsl:for-each select="namespace::*[. != 'http://www.w3.org/XML/1998/namespace']">
- <xsl:if test="not($current/parent::*[namespace::*[. = current()]])">
- <div class="xml-att">
- <xsl:text> xmlns</xsl:text>
- <xsl:if test="string-length(name())">:</xsl:if>
- <xsl:value-of select="concat(name(), '=')"/>
- <span class="xml-att-val">
- <xsl:value-of select="concat('"', ., '"')" disable-output-escaping="yes"/>
- </span>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <!--
- When the namespace axis isn't supported (e.g. Mozilla), we can simulate
- appropriate declarations from namespace elements.
- This currently doesn't check for namespaces on attributes.
- In the general case we can't reliably detect the use of QNames in content, but
- in the case of schema, we know which content could contain a QName and look
- there too. This mechanism is rather unpleasant though, since it records
- namespaces where they are used rather than showing where they are declared
- (on some parent element) in the source. Yukk!
- -->
- <xsl:if test="namespace-uri(.) != namespace-uri(parent::*) or not(parent::*)">
- <span class="xml-att">
- <xsl:text> xmlns</xsl:text>
- <xsl:if test="substring-before(name(),':') != ''">:</xsl:if>
- <xsl:value-of select="substring-before(name(),':')"/>
- <xsl:text>=</xsl:text>
- <span class="xml-att-val">
- <xsl:value-of select="concat('"', namespace-uri(.), '"')" disable-output-escaping="yes"/>
- </span>
- </span>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
- <xsl:template match="text()" mode="src">
- <span class="xml-text">
- <xsl:value-of select="." disable-output-escaping="no"/>
- </span>
- </xsl:template>
- <xsl:template match="comment()" mode="src">
- <div class="xml-comment">
- <xsl:text disable-output-escaping="no"><!-- </xsl:text>
- <xsl:value-of select="." disable-output-escaping="no"/>
- <xsl:text disable-output-escaping="no"> -->
-</xsl:text>
- </div>
- </xsl:template>
- <xsl:template match="processing-instruction()" mode="src">
- <div class="xml-proc">
- <xsl:text disable-output-escaping="no"><?</xsl:text>
- <xsl:copy-of select="name(.)"/>
- <xsl:value-of select="concat(' ', .)" disable-output-escaping="yes"/>
- <xsl:text disable-output-escaping="no"> ?>
-</xsl:text>
- </div>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-src.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-
-
-<!--
-==================================================================
- Starting point
-==================================================================
--->
-
-<xsl:template match="/">
- <html>
- <xsl:call-template name="head.render"/>
- <xsl:call-template name="body.render"/>
- </html>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: HTML head
-==================================================================
--->
-
-<xsl:template name="head.render">
- <head>
- <title>
- <xsl:value-of select="concat($html-title, ' - ', 'Generated by wsdl-viewer.xsl')"/>
- </title>
- <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
- <meta http-equiv="content-script-type" content="text/javascript"/>
- <meta http-equiv="content-style-type" content="text/css"/>
- <meta name="Generator" content="http://tomi.vanek.sk/xml/wsdl-viewer.xsl"/>
-
- <meta http-equiv="imagetoolbar" content="false"/>
- <meta name="MSSmartTagsPreventParsing" content="true"/>
-
- <style type="text/css">
- <xsl:value-of select="$css" disable-output-escaping="yes"/>
- </style>
-
- <script src="wsdl-viewer.js" type="text/javascript" language="javascript">
- <xsl:comment>
- <xsl:text>
- // </xsl:text>
- </xsl:comment>
- </script>
- </head>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: HTML body
-==================================================================
--->
-
-<xsl:template name="body.render">
- <body id="operations">
- <div id="outer_box">
- <div id="inner_box" onload="pagingInit()">
- <xsl:call-template name="title.render"/>
-
-
- <!-- TODO: pages with tabs for selecting some aspect of the WSDL
- <xsl:call-template name="navig.render"/>
--->
-
- <xsl:call-template name="content.render"/>
- <xsl:call-template name="footer.render"/>
- </div>
- </div>
- </body>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: heading
-==================================================================
--->
-
-<xsl:template name="title.render">
- <div id="header">
- <h1>
- <xsl:value-of select="$html-title"/>
- </h1>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: navigation
-==================================================================
--->
-
-<xsl:template name="navig.render">
- <div id="outer_nav">
- <div id="nav" class="floatcontainer">
- <ul>
- <li id="nav-service">
- <a href="#page.service">Service</a>
- </li>
- <li id="nav-operations">
- <a href="#page.operations">Operations</a>
- </li>
- <li id="nav-wsdl">
- <a href="#page.src">Source Code</a>
- </li>
-
-
- <!-- <li id="nav-client"><a href="#TODO-1">Client</a></li>
-
-
-
- <li id="nav-about">
- <a href="#page.about" class="current">About</a>
- </li>-->
- </ul>
- </div>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: content
-==================================================================
--->
-
-<xsl:template name="content.render">
- <div id="content">
- <xsl:if test="$ENABLE-SERVICE-PARAGRAPH">
- <xsl:call-template name="service.render"/>
- </xsl:if>
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <xsl:call-template name="operations.render"/>
- </xsl:if>
- <xsl:if test="$ENABLE-SRC-CODE-PARAGRAPH">
- <xsl:call-template name="src.render"/>
- </xsl:if>
- <xsl:if test="$ENABLE-ABOUT-PARAGRAPH">
- <xsl:call-template name="about.render">
- <xsl:with-param name="version" select="$wsdl-viewer.version"/>
- </xsl:call-template>
- </xsl:if>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: footer
-==================================================================
--->
-
-<xsl:template name="footer.render">
- <div id="footer">
- This page was generated by wsdl-viewer.xsl (<a href="http://tomi.vanek.sk">http://tomi.vanek.sk</a>)
-</div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: WSDL service information
-==================================================================
--->
-
-<xsl:template name="service.render">
- <div class="page">
- <a class="target" name="page.service">
- <h2>
- <xsl:value-of select="$html-title"/>
- </h2>
- </a>
- <xsl:apply-templates select="$consolidated-wsdl/*[local-name(.) = 'documentation']"
- mode="documentation.render"/>
- <xsl:apply-templates select="$consolidated-wsdl/ws:service|$consolidated-wsdl/ws2:service"
- mode="service-start"/>
- <xsl:if test="not($consolidated-wsdl/*[local-name() = 'service']/@name)">
-
-
-<!-- If the WS is without implementation, just with binding points = WS interface -->
-
- <xsl:apply-templates select="$consolidated-wsdl/ws:binding" mode="service-start"/>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface" mode="service"/>
- </xsl:if>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: WSDL operations - detail
-==================================================================
--->
-
-<xsl:template name="operations.render">
- <div class="page">
- <a class="target" name="page.operations">
- <h2>Operations</h2>
- </a>
- <ul>
- <xsl:apply-templates select="$consolidated-wsdl/ws:portType" mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
-
- <xsl:choose>
- <xsl:when test="$consolidated-wsdl/*[local-name() = 'service']/@name">
- <xsl:variable name="iface-name">
- <xsl:apply-templates select="$consolidated-wsdl/*[local-name() = 'service']/@interface"
- mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[@name = $iface-name]"
- mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:when test="$consolidated-wsdl/ws2:interface/@name">
-
-
-<!-- TODO: What to do if there are more interfaces? -->
-
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[1]" mode="operations"/>
- </xsl:when>
- <xsl:otherwise>
-
-
-<!-- TODO: Error message or handling somehow this unexpected situation -->
-
- </xsl:otherwise>
- </xsl:choose>
- </ul>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: WSDL and XSD source code files
-==================================================================
--->
-
-<xsl:template name="src.render">
- <div class="page">
- <a class="target" name="page.src">
- <h2>WSDL source code</h2>
- </a>
- <div class="box">
- <div class="xml-proc">
- <xsl:text><?xml version="1.0"?></xsl:text>
- </div>
- <xsl:apply-templates select="/" mode="src"/>
- </div>
-
- <xsl:apply-templates select="/*/*[local-name() = 'import'][@location]/@location" mode="src.import"/>
- <xsl:apply-templates select="$consolidated-wsdl/*[local-name() = 'types']//xsd:import[@schemaLocation]/@schemaLocation | $consolidated-wsdl/*[local-name() = 'types']//xsd:include[@schemaLocation]/@schemaLocation"
- mode="src.import"/>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: About
-==================================================================
--->
-
-<xsl:template name="about.render">
- <xsl:param name="version"/>
- <div class="page">
- <a class="target" name="page.about">
- <h2>About <em>wsdl-viewer.xsl</em>
- </h2>
- </a>
- <div class="floatcontainer">
- <div id="fix_column">
- <div class="shadow">
- <div class="box">
- <xsl:call-template name="processor-info.render"/>
- </div>
- </div>
- </div>
-
- <div id="flexi_column">
- <xsl:call-template name="about.detail">
- <xsl:with-param name="version" select="$wsdl-viewer.version"/>
- </xsl:call-template>
- </div>
- </div>
- </div>
- </xsl:template>
-
-
-</xsl:stylesheet>
\ No newline at end of file diff --git a/qpid/java/management/client/console/wsdm_rmd_perspective.jsp b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp index fc114a962d..fe70930627 100644 --- a/qpid/java/management/client/console/wsdm_rmd_perspective.jsp +++ b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp @@ -18,7 +18,7 @@ <body>
<div id="page" align="center">
<jsp:include page="/fragments/header.jsp">
- <jsp:param name="title" value="Resource Management - WS-DM WSDL Perspective"/>
+ <jsp:param name="title" value="Resource Management - WS-DM RMD Perspective"/>
</jsp:include>
<div id="content" align="center">
@@ -63,12 +63,8 @@ </tr>
<tr>
<td valign="top">
- <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
- <c:set var="xml">
- ${wsdl}
- </c:set>
- <c:import var="xslt" url="wsdl-viewer.xsl" />
- <x:transform xml="${xml}" xslt="${xslt}" />
+ <div class="panel" align="left" style="height:500px; width=200px; overflow-y:auto; font-size: smaller; font-weight:bold;">
+ <pre> <c:out value="${rmd}" /> </pre>
</div>
</td>
</tr>
diff --git a/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp index b725716fd8..3759459842 100644 --- a/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp +++ b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp @@ -63,12 +63,8 @@ </tr>
<tr>
<td valign="top">
- <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
- <c:set var="xml">
- ${wsdl}
- </c:set>
- <c:import var="xslt" url="wsdl-viewer.xsl" />
- <x:transform xml="${xml}" xslt="${xslt}" />
+ <div class="panel" align="left" style="height:500px; width=200px; overflow-y:auto; font-size: smaller; font-weight:bold;">
+ <pre> <c:out value="${wsdl}" /> </pre>
</div>
</td>
</tr>
diff --git a/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok b/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok new file mode 100644 index 0000000000..8a98e1d0b7 --- /dev/null +++ b/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok @@ -0,0 +1,133 @@ +This example is demonstrating a WS-Notification scenario
+when (for simplicity) QMan is at the same time consumer
+and producer.
+
+Specifically the example shows how a requestor can create,
+pause and resume a subscription.
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:485cc87c-660e-de43-e8fa-4ad5fffa95a6</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:Subscribe xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
+ <wsnt:ConsumerReference>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/consumer</wsa:Address>
+ </wsnt:ConsumerReference>
+ </wsnt:Subscribe>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0ee610d1-e211-95c6-a498-e1084a610c44</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:485cc87c-660e-de43-e8fa-4ad5fffa95a6</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:SubscribeResponse xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
+ <wsnt:SubscriptionReference>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsnt:SubscriptionReference>
+ <wsnt:CurrentTime>2009-02-27T13:51:56+01:00</wsnt:CurrentTime>
+ </wsnt:SubscribeResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:35cc80af-84ac-2456-3e1f-edc2a7f60970</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:PauseSubscription xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bb53d38a-428c-3d90-cc45-29d5cb27a8df</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:35cc80af-84ac-2456-3e1f-edc2a7f60970</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <muse-op:PauseSubscriptionResponse xmlns:muse-op="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bfb48615-905a-e472-a9ca-5483fa592f60</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:ResumeSubscription xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:aab4cf18-3cc0-30c4-7036-009e26bb3213</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bfb48615-905a-e472-a9ca-5483fa592f60</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <muse-op:ResumeSubscriptionResponse xmlns:muse-op="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java index 93e78707e9..42587d78ff 100644 --- a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java +++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java @@ -26,7 +26,9 @@ import java.util.Date; import org.apache.muse.util.xml.XPathUtils;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.impl.FilterCollection;
import org.apache.muse.ws.notification.impl.MessagePatternFilter;
+import org.apache.muse.ws.notification.impl.ProducerPropertiesFilter;
import org.apache.muse.ws.notification.impl.TopicFilter;
import org.apache.muse.ws.notification.remote.NotificationProducerClient;
import org.apache.qpid.management.Names;
@@ -65,11 +67,11 @@ public class ConsumerAndProducerExample extends AbstractQManExample void executeExample(String host, int port) throws Exception
{
// This is QMan...
- URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
+ URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/adapter");
// ...and this is QMan too! Note that it has an hidden consumer capability that is used in
// order to run successfully this example...
- URI consumerURI = producerURI;
+ URI consumerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
EndpointReference producerEPR = new EndpointReference(producerURI);
EndpointReference consumerEPR = new EndpointReference(consumerURI);
@@ -93,8 +95,11 @@ public class ConsumerAndProducerExample extends AbstractQManExample // Example 6: a MessageFilter is installed in order to listen only for connection events
// (connections created or removed). The subscription will expire in 10 seconds.
allMessagesWithMessageFilterAndTerminationTime(producerEPR,consumerEPR);
+
+ // Example 7 : a subscription with more than one filter.
+ complexSubscription(producerEPR, consumerEPR);
}
-
+
/**
* Makes a subscription on all topics / all messages without an expiry date.
*
@@ -223,6 +228,41 @@ public class ConsumerAndProducerExample extends AbstractQManExample new Date(System.currentTimeMillis() + 10000)); // Termination Time
}
+ /**
+ * Makes a subscription on a specifc topic with an expiry date.
+ * Only messages published on the given topic will be delivered to the given consumer.
+ * The subscription will end after 10 seconds
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void complexSubscription(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ FilterCollection filter = new FilterCollection();
+
+ TopicFilter topicFilter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+ MessagePatternFilter messageFilter= new MessagePatternFilter(
+ "/wsnt:NotificationMessage/wsnt:Message/qman:LifeCycleEvent/qman:Resource/qman:Name/text()='connection'", // expression (XPath)
+ XPathUtils.NAMESPACE_URI); // Dialect : the only supported dialect is XPath 1.0
+
+ ProducerPropertiesFilter producerFilter = new ProducerPropertiesFilter(
+ "boolean(/*/MgtPubInterval > 100 and /*/MsgTotalEnqueues > 56272)",
+ XPathUtils.NAMESPACE_URI);
+
+ filter.addFilter(topicFilter);
+ filter.addFilter(messageFilter);
+ filter.addFilter(producerFilter);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
@Override
void printOutExampleDescription()
{
@@ -245,4 +285,9 @@ public class ConsumerAndProducerExample extends AbstractQManExample System.out.println("A subscription with a termination time will have a predefined expiry");
System.out.println("date while if there's no termination the subscription will never expire.");
}
+
+ public static void main(String[] args)
+ {
+ new ConsumerAndProducerExample().execute(new String[]{"localhost","8080"});
+ }
}
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java new file mode 100644 index 0000000000..01a27a16f9 --- /dev/null +++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java @@ -0,0 +1,88 @@ +/*
+ *
+ * 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.management.example;
+
+import java.net.URI;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.notification.remote.NotificationProducerClient;
+import org.apache.muse.ws.notification.remote.SubscriptionClient;
+
+/**
+ * This example is demonstrating a WS-Notification scenario
+ * when (for simplicity) QMan is at the same time consumer
+ * and producer.
+ *
+ * Specifically the example shows how a requestor can create, pause and resume
+ * a subscription.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class PausableSubscriptionExample extends AbstractQManExample
+{
+ @Override
+ void executeExample(String host, int port) throws Exception
+ {
+ // This is QMan...
+ URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/adapter");
+
+ // ...and this is QMan too! Note that it has an hidden consumer capability that is used in
+ // order to run successfully this example...
+ URI consumerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
+
+ EndpointReference producerEPR = new EndpointReference(producerURI);
+ EndpointReference consumerEPR = new EndpointReference(consumerURI);
+
+ NotificationProducerClient producerClient = new NotificationProducerClient(producerEPR);
+ producerClient.setTrace(true);
+
+ // 1) Creates a subscription and gets the corresponding reference.
+ SubscriptionClient subscriptionClient = producerClient.subscribe(
+ consumerEPR, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ null); // Termination Time : if null the subscription will never expire.
+ subscriptionClient.setTrace(true);
+
+
+ // 2) Pauses the subscription.
+ subscriptionClient.pauseSubscription();
+
+ // 3) Resumes the subscription.
+ subscriptionClient.resumeSubscription();
+ }
+
+ @Override
+ void printOutExampleDescription()
+ {
+ System.out.println("This example is demonstrating a WS-Notification scenario ");
+ System.out.println("when (for simplicity) QMan is at the same time consumer ");
+ System.out.println("and producer.");
+ System.out.println();
+ System.out.println("Specifically the example shows how a requestor can create,");
+ System.out.println("pause and resume a subscription.");
+ }
+
+ public static void main(String[] args)
+ {
+ new PausableSubscriptionExample().execute(new String[]{"romagazzarini","8080"});
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/muse.xml b/qpid/java/management/client/src/main/java/muse.xml index d2f499cef9..cf651c34ac 100644 --- a/qpid/java/management/client/src/main/java/muse.xml +++ b/qpid/java/management/client/src/main/java/muse.xml @@ -29,7 +29,7 @@ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.DateSerializer</java-serializer-class>
</custom-serializer>
<router>
- <java-router-class>org.apache.muse.core.routing.SimpleResourceRouter</java-router-class>
+ <java-router-class>org.apache.muse.ws.resource.impl.WsResourceRouter</java-router-class>
<logging>
<log-file>log/muse.log</log-file>
<log-level>SEVERE</log-level>
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java index 3d208835f0..4f84128fb3 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java @@ -170,6 +170,6 @@ public interface Messages String QMAN_100037_INVOKE_OPERATION_FAILURE = "<QMAN-100037> : Operation Invocation failure for operation.";
String QMAN_100038_UNABLE_TO_SEND_WS_NOTIFICATION = "<QMAN-100038> : Unable to send notification.";
String QMAN_100039_UNABLE_TO_CONFIGURE_PROPERLY_WORKER_MANAGER = "<QMAN-100039> : Unable to properly configure WorkManager. A malformed property (NaN) was given as input parameter.";
-
+ String QMAN_100040_UNABLE_TO_LOCATE_WSRP_PROPERTIES = "<QMAN-100040> : Unable to evaluate the WSRP XPath expression on resource WSDL.";
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java index 808cafb6a7..d3ce711d5d 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java @@ -45,7 +45,7 @@ public abstract class Names public static String CLASS = "class"; public static String EVENT = "event"; public static String OBJECT_ID="objectId"; - public static String BROKER_ID = "brokerID"; + public static String BROKER_ID = "brokerId"; public static String DOMAIN_NAME = "Q-MAN"; public static String ARG_COUNT_PARAM_NAME = "argCount"; @@ -86,7 +86,7 @@ public abstract class Names new StringBuilder() .append(DOMAIN_NAME) .append(':') - .append("Type=Service") + .append("Name=QMan,Type=Service") .toString()); } catch(Exception exception) { diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java deleted file mode 100644 index af6aaa36bf..0000000000 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.management.configuration; - -import org.apache.qpid.management.domain.model.AccessMode; - -/** - * Class used to encapsulate a mapping between an access mode and a code. - * - * @author Andrea Gazzarini - */ -class AccessModeMapping -{ - private final int _code; - private final AccessMode _accessMode; - - /** - * Builds a new access mode mapping with the given parameters. - * - * @param code the access code. - * @param accessMode the access mode. - */ - AccessModeMapping(int code, AccessMode accessMode) - { - this._code = code; - this._accessMode = accessMode; - } - - /** - * Returns the access mode of this mapping. - * - * @return the access mode of this mapping. - */ - AccessMode getAccessMode () - { - return _accessMode; - } - - /** - * Returns the code of this mapping. - * - * @return the code of this mapping. - */ - int getCode () - { - return _code; - } - - /** - * Returns a string representation of this mapping. - * The returned string is indicating the code and the corresponding access mode. - * - * @return a string representation of this mapping. - */ - @Override - public String toString () - { - return new StringBuilder() - .append("AccessMode mapping (") - .append(_code) - .append(',') - .append(_accessMode) - .append(')').toString(); - } -} diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java index c9d45c5023..51dc62f4fa 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java @@ -30,7 +30,16 @@ import org.apache.qpid.management.Messages; import org.apache.qpid.management.Names; import org.apache.qpid.management.domain.handler.base.IMessageHandler; import org.apache.qpid.management.domain.model.AccessMode; +import org.apache.qpid.management.domain.model.type.AbsTime; +import org.apache.qpid.management.domain.model.type.DeltaTime; +import org.apache.qpid.management.domain.model.type.ObjectReference; +import org.apache.qpid.management.domain.model.type.Str16; +import org.apache.qpid.management.domain.model.type.Str8; import org.apache.qpid.management.domain.model.type.Type; +import org.apache.qpid.management.domain.model.type.Uint16; +import org.apache.qpid.management.domain.model.type.Uint32; +import org.apache.qpid.management.domain.model.type.Uint64; +import org.apache.qpid.management.domain.model.type.Uint8; import org.apache.qpid.transport.DeliveryProperties; import org.apache.qpid.transport.Header; import org.apache.qpid.transport.MessageProperties; @@ -71,7 +80,12 @@ public final class Configuration private Configuration() { defineQueueNames(); + createHeaderForCommandMessages(); + + addAccessModeMappings(); + + addTypeMappings(); } void clean() @@ -90,9 +104,11 @@ public final class Configuration } /** - * Returns true if this configuration has at least one broker connection data. + * Returns true if this configuration has at least + * one broker configured. * - * @return true if this configuration has at least one broker connection data. + * @return true if this configuration has at least one + * broker configured. */ public boolean hasOneOrMoreBrokersDefined() { @@ -245,26 +261,46 @@ public final class Configuration /** * Adds a new type mapping to this configuration. * - * @param mapping the type mapping that will be added. + * @param code the code that will be associated with the declared type. + * @param type the type. + * @param vailidatorClassName the FQN of the validator class that will be + * associated with the given type. */ - void addTypeMapping(TypeMapping mapping) { - int code = mapping.getCode(); - Type type = mapping.getType(); - String validatorClassName = mapping.getValidatorClassName(); - _typeMappings.put(code, type); + void addTypeMapping(int code, Type type, String validatorClassName) { + _typeMappings.put(code, type); _validators.put(type, validatorClassName); - LOGGER.info(Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, code,type,validatorClassName); + LOGGER.info( + Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, + code, + type, + validatorClassName); } - + + + /** + * Adds a new type mapping to this configuration. + * + * @param code the code that will be associated with the declared type. + * @param type the type. + */ + void addTypeMapping(int code, Type type) { + _typeMappings.put(code, type); + + LOGGER.info( + Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, + code, + type, + "not configured for this type."); + } + /** * Adds a new access mode mapping to this configuration. * - * @param mapping the mapping that will be added. + * @param code the code that will be associated with the access mode, + * @param accessMode the accessMode. */ - void addAccessModeMapping(AccessModeMapping mapping){ - int code = mapping.getCode(); - AccessMode accessMode = mapping.getAccessMode(); + void addAccessModeMapping(int code, AccessMode accessMode){ _accessModes.put(code, accessMode); LOGGER.info(Messages.QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED, code,accessMode); @@ -420,4 +456,34 @@ public final class Configuration { this._keepAliveTime = keepAliveTime; } + + /** + * Configures access mode mappings. + * An access mode mapping is an association between a code and an access mode. + */ + private void addAccessModeMappings() { + addAccessModeMapping(1,AccessMode.RC); + addAccessModeMapping(2,AccessMode.RW); + addAccessModeMapping(3,AccessMode.RO); + } + + /** + * Configures type mappings. + * A type mapping is an association between a code and a management type. + */ + private void addTypeMappings() + { + addTypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR); + addTypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR); + addTypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR); + addTypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR); + addTypeMapping(6,new Str8(),Names.STRING_VALIDATOR); + addTypeMapping(7,new Str16(),Names.STRING_VALIDATOR); + addTypeMapping(8,new AbsTime()); + addTypeMapping(9,new DeltaTime()); + addTypeMapping(10,new ObjectReference()); + addTypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean()); + addTypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid()); + addTypeMapping(15,new org.apache.qpid.management.domain.model.type.Map()); + } }
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java index 1cde9d5f88..fe44c6aff7 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java @@ -38,16 +38,6 @@ import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessage import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler; import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler; import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler; -import org.apache.qpid.management.domain.model.AccessMode; -import org.apache.qpid.management.domain.model.type.AbsTime; -import org.apache.qpid.management.domain.model.type.DeltaTime; -import org.apache.qpid.management.domain.model.type.ObjectReference; -import org.apache.qpid.management.domain.model.type.Str16; -import org.apache.qpid.management.domain.model.type.Str8; -import org.apache.qpid.management.domain.model.type.Uint16; -import org.apache.qpid.management.domain.model.type.Uint32; -import org.apache.qpid.management.domain.model.type.Uint64; -import org.apache.qpid.management.domain.model.type.Uint8; import org.apache.qpid.transport.util.Logger; import org.xml.sax.Attributes; import org.xml.sax.InputSource; @@ -148,9 +138,6 @@ public class Configurator extends DefaultHandler } } - addTypeMappings(); - addAccessModeMappings(); - addMandatoryManagementMessageHandlers(); addMandatoryMethodReplyMessageHandlers(); } catch (Exception exception) @@ -209,38 +196,6 @@ public class Configurator extends DefaultHandler return data; } - /** - * Configures access mode mappings. - * An access mode mapping is an association between a code and an access mode. - */ - private void addAccessModeMappings() { - Configuration configuration = Configuration.getInstance(); - configuration.addAccessModeMapping(new AccessModeMapping(1,AccessMode.RC)); - configuration.addAccessModeMapping(new AccessModeMapping(2,AccessMode.RW)); - configuration.addAccessModeMapping(new AccessModeMapping(3,AccessMode.RO)); - } - - /** - * Configures type mappings. - * A type mapping is an association between a code and a management type. - */ - private void addTypeMappings() - { - Configuration configuration = Configuration.getInstance(); - configuration.addTypeMapping(new TypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(6,new Str8(),Names.STRING_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(7,new Str16(),Names.STRING_VALIDATOR)); - configuration.addTypeMapping(new TypeMapping(8,new AbsTime())); - configuration.addTypeMapping(new TypeMapping(9,new DeltaTime())); - configuration.addTypeMapping(new TypeMapping(10,new ObjectReference())); - configuration.addTypeMapping(new TypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean())); - configuration.addTypeMapping(new TypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid())); - configuration.addTypeMapping(new TypeMapping(15,new org.apache.qpid.management.domain.model.type.Map())); - } - /** * Configures the mandatory management message handlers. */ diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java deleted file mode 100644 index 2c0a460c1a..0000000000 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.management.configuration; - -import org.apache.qpid.management.domain.model.type.Type; - -/** - * Type Mapping used for associating a code with a management type. - * - * @author Andrea Gazzarini - */ -class TypeMapping -{ - private final int _code; - private final Type _type; - private final String _validatorClass; - - /** - * Builds a new type mapping with the given parameters and no validator. - * - * @param code the code. - * @param type the management type. - */ - TypeMapping(int code, Type type) - { - this(code,type,null); - } - - /** - * Builds a new type mapping with the given parameters. - * - * @param code the code. - * @param type the management type. - * @param validatorClassName the class name of the validator to be used. - */ - TypeMapping(int code, Type type, String validatorClassName) - { - this._code = code; - this._type = type; - this._validatorClass = validatorClassName; - } - - /** - * Returns the code of this mapping. - * - * @return the code of this mapping. - */ - int getCode () - { - return _code; - } - - /** - * Returns the type for this mapping. - * - * @return the type for this mapping. - */ - Type getType () - { - return _type; - } - - /** - * Returns the validator class of this mapping. - * - * @return the validator class (as a string) of this mapping. - */ - public String getValidatorClassName() - { - return _validatorClass; - } -} diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java index 176cec451e..657d7e6210 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java @@ -54,11 +54,10 @@ public class JmxService */ public void registerQManService(QMan qman) throws MBeanException { - ObjectName name = createQManName(); - if (!_mxServer.isRegistered(name)) + if (!_mxServer.isRegistered(Names.QMAN_OBJECT_NAME)) { try { - _mxServer.registerMBean(qman, name); + _mxServer.registerMBean(qman, Names.QMAN_OBJECT_NAME); } catch (Exception exception) { throw new MBeanException(exception); } @@ -358,27 +357,6 @@ public class JmxService throw new RuntimeException(exception); } } - - /** - * Creates the QMan object name. - * - * @return the QMan object name. - */ - private ObjectName createQManName() - { - String asString = new StringBuilder() - .append(Names.DOMAIN_NAME) - .append(':') - .append("Type=Service") - .toString(); - try - { - return new ObjectName(asString); - } catch (MalformedObjectNameException exception) - { - throw new RuntimeException(exception); - } - } ObjectName createEntityDefinitionName(String packageName, String className, String type) { @@ -407,7 +385,7 @@ public class JmxService { if (!_mxServer.isRegistered(name)) _mxServer.registerMBean(entity, name); - _mxServer.addNotificationListener(name, createQManName(), null, null); + _mxServer.addNotificationListener(name, Names.QMAN_OBJECT_NAME, null, null); } catch(Exception exception) { throw new RuntimeException(exception); diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java index d124593472..c4c0ce5e74 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java @@ -26,6 +26,9 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import javax.management.Attribute; import javax.management.AttributeList; @@ -45,6 +48,7 @@ import org.apache.qpid.management.Names; import org.apache.qpid.management.configuration.BrokerAlreadyConnectedException; import org.apache.qpid.management.configuration.BrokerConnectionData; import org.apache.qpid.management.configuration.BrokerConnectionException; +import org.apache.qpid.management.configuration.Configuration; import org.apache.qpid.management.configuration.Configurator; import org.apache.qpid.management.domain.model.JmxService; import org.apache.qpid.transport.util.Logger; @@ -58,6 +62,7 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>(); private Configurator _configurator = new Configurator(); + private ThreadPoolExecutor _workManager; /** * Starts QMan. @@ -74,6 +79,8 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean _configurator.configure(); + configureWorkManager(); + LOGGER.info(Messages.QMAN_000019_QMAN_STARTED); } catch(Exception exception) { LOGGER.error(exception,Messages.QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY ); @@ -143,6 +150,36 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean LOGGER.info(Messages.QMAN_000021_SHUT_DOWN); } + /** + * Creates a management client using the given data. + * + * @param brokerId the broker identifier. + * @param data the broker connection data. + */ + public void createManagementClient(UUID brokerId, BrokerConnectionData data) + { + try + { + ManagementClient client = new ManagementClient(brokerId,data); + client.estabilishFirstConnectionWithBroker(); + managementClients.add(client); + + LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId); + } catch(StartupFailureException exception) { + LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data); + } + } + + /** + * Returns the list of management clients currently handled by QMan. + * + * @return the list of management clients currently handled by QMan. + */ + public List<ManagementClient> getManagementClients() + { + return managementClients; + } + /** * Injects the configurator on this QMan instance. * That configutator later will be responsible to manage the configuration. @@ -330,13 +367,20 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean /** * Simply dispatches the incoming notification to registered listeners. + * Consider that the notification is sent asynchronously so the QMan current thread is not + * waiting for completion of receiver task. * * @param notification the incoming notification. * @param handback the context associated to this notification. */ - public void handleNotification(Notification notification, Object handback) + public void handleNotification(final Notification notification, Object handback) { - sendNotification(notification); + _workManager.execute(new Runnable(){ + public void run() + { + sendNotification(notification); + } + }); } /** @@ -352,33 +396,17 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean LOGGER.info(Messages.QMAN_000023_QMAN_REGISTERED_AS_MBEAN); } - /** - * Creates a management client using the given data. - * - * @param brokerId the broker identifier. - * @param data the broker connection data. - */ - public void createManagementClient(UUID brokerId, BrokerConnectionData data) - { - try - { - ManagementClient client = new ManagementClient(brokerId,data); - client.estabilishFirstConnectionWithBroker(); - managementClients.add(client); - - LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId); - } catch(StartupFailureException exception) { - LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data); - } - } - /** - * Returns the list of management clients currently handled by QMan. - * - * @return the list of management clients currently handled by QMan. + * Configures work manager component. */ - public List<ManagementClient> getManagementClients() - { - return managementClients; - } + private void configureWorkManager() + { + Configuration configuration = Configuration.getInstance(); + _workManager = new ThreadPoolExecutor( + configuration.getWorkerManagerPoolSize(), + configuration.getWorkerManagerMaxPoolSize(), + configuration.getWorkerManagerKeepAliveTime(), + TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<Runnable>(30)); + } } diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java index a12993d40e..ee41beaf50 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java @@ -86,6 +86,8 @@ public class QpidService implements SessionListener public void opened(Session ssn) {} + public void resumed(Session ssn) {} + public void message(Session ssn, MessageTransfer xfr) { MessagePartListenerAdapter l = _listeners.get(xfr.getDestination()); diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java index 03e772b9b1..09b7309b96 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java @@ -30,12 +30,21 @@ import javax.management.ObjectName; import org.apache.qpid.management.Names;
+/**
+ * Value Object encapsulating a broker management domain model.
+ *
+ * @author Andrea Gazzarini
+ */
public class BrokerModel
{
- private Map<String, List<ObjectName>> objectsByType = new HashMap<String, List<ObjectName>>();
-
- private String id;
+ private Map<String, List<ObjectName>> _objectsByType = new HashMap<String, List<ObjectName>>();
+ private String _id;
+ /**
+ * Adds a new object to this domain model.
+ *
+ * @param name the object name of the JMX entity.
+ */
void addObject(ObjectName name)
{
String packageName = name.getKeyProperty(Names.PACKAGE);
@@ -44,37 +53,48 @@ public class BrokerModel {
String fqn = packageName+"."+className;
- List<ObjectName> objects = objectsByType.get(fqn);
+ List<ObjectName> objects = _objectsByType.get(fqn);
if (objects == null)
{
objects = new ArrayList<ObjectName>();
- objectsByType.put(fqn,objects);
+ _objectsByType.put(fqn,objects);
}
objects.add(name);
}
}
+ /**
+ * Gets the identifier of the owner of this model.
+ *
+ * @return the identifier of the owner of this model.
+ */
public String getId()
{
- return id;
+ return _id;
}
+ /**
+ * Sets the identifier of the owner of this model.
+ *
+ * @param id the identifier of the owner of this model.
+ */
public void setId(String id)
{
- this.id = id;
+ this._id = id;
}
- public Set<String> getCategoryNames(){
- return objectsByType.keySet();
+ public Set<String> getCategoryNames()
+ {
+ return _objectsByType.keySet();
}
public List<ObjectName> getCategory(String name)
{
- return objectsByType.get(name);
+ return _objectsByType.get(name);
}
public int getCategoryCount()
{
- return objectsByType.keySet().size();
+ return _objectsByType.keySet().size();
}
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java index ae886767e2..509c86c08b 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java @@ -42,9 +42,10 @@ import org.apache.qpid.management.domain.services.QMan; * This controller is responsible to :
*
* <ul>
- * <li> prepare data for the page that is showing all connected brokers.</li>.
- * </li> connect QMan with a broker on demand.
+ * <li> prepare data for the page that is showing all connected brokers.</li>.
+ * </li> connect QMan with a broker on demand.
* </ul>
+ *
* @author Andrea Gazzarini
*/
public class BrokersManagementAction extends HttpServlet
@@ -54,6 +55,11 @@ public class BrokersManagementAction extends HttpServlet /**
* Retrieves all connected brokers (their connection data) and prepare the model that
* is then forwarded to the appropriate view page.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of failure while forwarding to the view component.
+ * @throws IOException in case of failure while forwarding to the view component.
*/
@SuppressWarnings("unchecked")
@Override
@@ -87,7 +93,13 @@ public class BrokersManagementAction extends HttpServlet }
/**
- * Connects QMan with a new broker.
+ * Connects QMan with a new broker and forwards to
+ * the brokers list view page.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of failure while forwarding to the view component.
+ * @throws IOException in case of failure while forwarding to the view component.
*/
@SuppressWarnings("unchecked")
@Override
@@ -123,28 +135,32 @@ public class BrokersManagementAction extends HttpServlet errors.add("Invalid value for \"virtualHost\" attribute. Must be not null.");
}
- try{
+ try
+ {
port = Integer.parseInt(portString);
} catch(Exception exception)
{
errors.add("Invalid value for \"port\" attribute. Must be not null and must be a number.");
}
- try{
+ try
+ {
initialPoolCapacity = Integer.parseInt(initialCapacityString);
} catch(Exception exception)
{
errors.add("Invalid value for \"Initial Pool Capacity\" attribute. Must be not null and must be a number.");
}
- try{
+ try
+ {
maxPoolCapacity = Integer.parseInt(maxCapacityString);
} catch(Exception exception)
{
errors.add("Invalid value for \"Max Pool Capacity\" attribute. Must be not null and must be a number.");
}
- try{
+ try
+ {
maxWaitTimeout = Long.parseLong(maxWaitTimeoutString);
} catch(Exception exception)
{
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java index de479a00d6..e3a8eb50d7 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java @@ -43,15 +43,12 @@ import javax.xml.namespace.QName; import org.apache.muse.core.proxy.ProxyHandler;
import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.ws.addressing.EndpointReference;
-import org.apache.muse.ws.resource.remote.WsResourceClient;
import org.apache.qpid.management.Names;
import org.w3c.dom.Element;
public class WsdmPropertiesPerspectiveAction extends HttpServlet
{
private static final long serialVersionUID = -2411413147821629363L;
- private static final Object [] WSDL_DIALECT = new Object[]{"http://schemas.xmlsoap.org/wsdl/"};
- private static final Object [] RMD_DIALECT = new Object[]{"http://docs.oasis-open.org/wsrf/rmd-1"};
private ProxyHandler proxyHandler;
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java index bafdc06633..b4c488e97c 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java @@ -35,6 +35,8 @@ import org.apache.muse.core.proxy.ProxyHandler; import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
import org.apache.muse.ws.resource.remote.WsResourceClient;
import org.apache.qpid.management.Names;
import org.w3c.dom.Element;
@@ -42,7 +44,7 @@ import org.w3c.dom.Element; public class WsdmRmdPerspectiveAction extends HttpServlet
{
private static final long serialVersionUID = -2411413147821629363L;
- private static final Object [] DIALECT = new Object[]{"http://docs.oasis-open.org/wsrf/rmd-1"};
+ private static final Object [] RMD_DIALECT = new Object[]{WsrmdConstants.NAMESPACE_URI};
private ProxyHandler proxyHandler;
@@ -52,10 +54,14 @@ public class WsdmRmdPerspectiveAction extends HttpServlet public void init() throws ServletException
{
proxyHandler = new ReflectionProxyHandler();
- proxyHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
- proxyHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", Names.PREFIX));
- proxyHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", Names.PREFIX)});
- proxyHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", Names.PREFIX));
+ proxyHandler.setAction(WsxConstants.GET_METADATA_URI);
+ proxyHandler.setRequestName(WsxConstants.GET_METADATA_QNAME);
+ proxyHandler.setRequestParameterNames(new QName[]{
+ new QName(
+ WsxConstants.NAMESPACE_URI,
+ WsxConstants.DIALECT,
+ WsxConstants.PREFIX)});
+ proxyHandler.setResponseName(WsxConstants.METADATA_QNAME);
proxyHandler.setReturnType(Element[].class);
}
@@ -65,29 +71,49 @@ public class WsdmRmdPerspectiveAction extends HttpServlet {
try
{
-// String resourceId = request.getParameter("resourceId");
-// ObjectName objectName = new ObjectName(resourceId);
-//
-// String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
-// EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
-// resourceEndpointReference.addParameter(
-// Names.RESOURCE_ID_QNAME,
-// wsresourceid);
-//
-// WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
-// Element rmd = ((Element[])resourceClient.invoke(proxyHandler,DIALECT))[0];
-//
-// String output = XmlUtils.toString(rmd);
-//
-// String [] keyProperties = objectName.getKeyPropertyListString().split(",");
-//
-// request.setAttribute("resourceId", objectName);
-// request.setAttribute("nameAttributes",keyProperties);
-// request.setAttribute("rmd",output);
- RequestDispatcher dispatcher = request.getRequestDispatcher("/tbd.jsp");
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+
+ String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsresourceid);
+
+ WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+ Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+// NodeList nodelist = wsdl.getChildNodes();
+// Element definitions = null;
+// for (int i = 0; i < nodelist.getLength(); i++)
+// {
+// Node node = nodelist.item(i);
+// switch (node.getNodeType())
+// {
+// case Node.ELEMENT_NODE:
+// {
+// Element element = (Element) node;
+// if (element.getNodeName().indexOf("definitions") != -1)
+// {
+// definitions = element;
+// break;
+// }
+// }
+// }
+// }
+
+ String output = XmlUtils.toString(rmd);
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("rmd",output);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_rmd_perspective.jsp");
dispatcher.forward(request,response);
} catch(Exception exception)
- {
+ {
request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
request.setAttribute("exception",exception);
RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java index 9b47fe95b9..77a5237037 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java @@ -35,6 +35,7 @@ import org.apache.muse.core.proxy.ProxyHandler; import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.metadata.WsxConstants;
import org.apache.muse.ws.resource.remote.WsResourceClient;
import org.apache.qpid.management.Names;
import org.w3c.dom.Element;
@@ -44,7 +45,7 @@ import org.w3c.dom.NodeList; public class WsdmWsdlPerspectiveAction extends HttpServlet
{
private static final long serialVersionUID = -2411413147821629363L;
- private static final Object [] WSDL_DIALECT = new Object[]{"http://schemas.xmlsoap.org/wsdl/"};
+ private static final Object [] WSDL_DIALECT = new Object[]{WsxConstants.WSDL_DIALECT};
private ProxyHandler proxyHandler;
@@ -54,10 +55,14 @@ public class WsdmWsdlPerspectiveAction extends HttpServlet public void init() throws ServletException
{
proxyHandler = new ReflectionProxyHandler();
- proxyHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
- proxyHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", Names.PREFIX));
- proxyHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", Names.PREFIX)});
- proxyHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", Names.PREFIX));
+ proxyHandler.setAction(WsxConstants.GET_METADATA_URI);
+ proxyHandler.setRequestName(WsxConstants.GET_METADATA_QNAME);
+ proxyHandler.setRequestParameterNames(new QName[]{
+ new QName(
+ WsxConstants.NAMESPACE_URI,
+ WsxConstants.DIALECT,
+ WsxConstants.PREFIX)});
+ proxyHandler.setResponseName(WsxConstants.METADATA_QNAME);
proxyHandler.setReturnType(Element[].class);
}
@@ -72,6 +77,7 @@ public class WsdmWsdlPerspectiveAction extends HttpServlet String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+
resourceEndpointReference.addParameter(
Names.RESOURCE_ID_QNAME,
wsresourceid);
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java index 545e587f79..47aa4ea681 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java @@ -57,7 +57,9 @@ public class QEmuInitializer extends HttpServlet Names.QPID_EMULATOR_OBJECT_NAME);
} catch(Exception exception)
{
- LOGGER.warn(exception,Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
+ LOGGER.warn(
+ exception,
+ Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
throw new ServletException(exception);
}
}
@@ -84,8 +86,8 @@ public class QEmuInitializer extends HttpServlet {
try
{
- ManagementFactory.getPlatformMBeanServer()
- .unregisterMBean(Names.QPID_EMULATOR_OBJECT_NAME);
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(
+ Names.QPID_EMULATOR_OBJECT_NAME);
} catch (Exception exception)
{
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java new file mode 100644 index 0000000000..59a5801505 --- /dev/null +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java @@ -0,0 +1,44 @@ +/*
+ *
+ * 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.management.wsdm.capabilities;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+public interface Constants
+{
+ String WSRP_PROPERTIES_XPATH = "/wsdl:definitions/wsdl:types/xsd:schema[" +
+ "@targetNamespace='http://amqp.apache.org/qpid/management/qman']" +
+ "/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence";
+
+ String SERVICE_LOCATION_XPATH = "/wsdl:definitions/wsdl:service/wsdl:port/wsdl-soap:address/@location";
+ String QMAN_SCHEMA_XPATH = "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']";
+
+ String MIN_OCCURS = "minOccurs";
+ String REF_ATTRIBUTE = "ref";
+ String NAME_ATTRIBUTE = "name";
+ String TYPE_ATTRIBUTE ="type";
+
+ QName XSD_ELEMENT_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"element","xsd");
+ QName XSD_COMPLEX_TYPE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"complexType","xsd");
+ QName XSD_SEQUENCE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"sequence","xsd");
+
+}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java index dd5eb523c1..bde98092a0 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java @@ -29,6 +29,8 @@ import org.apache.muse.ws.notification.WsnConstants; /**
* WS-Notifications consumer capability.
+ * At the moment QMan is not a consumer of itself so this capability is here only
+ * for test purposes.
*
* @author Andrea Gazzarini
*/
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java index 0676b4ac49..370cf3086d 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java @@ -29,32 +29,57 @@ import org.apache.muse.core.Environment; /**
* Dummy capability builder used for avoid duplicated builds for the
* same class.
+ * Basically it acts likes a Null Object when the target capability class has been
+ * already built.
*
* @author Andrea Gazzarini
*/
public class DummyCapabilityBuilder implements IArtifactBuilder
{
-
- public void begin(ObjectName objectName) throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void begin(ObjectName objectName)
{
}
- public void endAttributes() throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endAttributes()
{
}
- public void endOperations() throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endOperations()
{
}
- public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata)
{
}
- public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onOperation(MBeanOperationInfo operationMetadata)
{
}
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
public void setEnvironment(Environment environment)
{
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java index 82d8e97d37..37ecc0c031 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java @@ -179,12 +179,8 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability params,
signature);
- Result result = new Result(
- output.getReturnCode(),
- output.getStatusText(),
- output.getOutputSection());
-
- return result;
+ return new Result(output.getOutputSection());
+
} catch (InstanceNotFoundException exception)
{
throw new EntityInstanceNotFoundFault(
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java index ea623138a4..ea67bdf9e1 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java @@ -178,6 +178,14 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{ }
}
+ /**
+ * Director callback.
+ * All attributes have been notified.
+ *
+ * This builder is using this callback in order to create the initial
+ * properties QNames declaration.
+ *
+ */
public void endAttributes() throws BuilderException
{
_endAttributeHandler.endAttributes();
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java index 7e58992540..d6255d0bed 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java @@ -21,6 +21,10 @@ package org.apache.qpid.management.wsdm.capabilities;
import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
import org.apache.muse.ws.resource.metadata.ext.WsrfMetadataExchange;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.apache.qpid.management.wsdm.muse.resources.QManWsResource;
@@ -60,4 +64,36 @@ public class QManMetadataExchangeCapability extends WsrfMetadataExchange return wsdl;
}
+
+ /**
+ * Returns the resource metadata descriptor associated with the owenr
+ * resource of thi capability.
+ *
+ * @return the resource metadata descriptor.
+ */
+ protected Element getResourceMetadataDescriptor()
+ {
+ WsResource resource = (WsResource)getResource();
+ MetadataDescriptor metadataDescriptor = resource.getPropertyCollection().getMetadata();
+ return metadataDescriptor.toXML();
+ }
+
+ public Element[] getMetadata(String dialect)
+ {
+ if (dialect == null)
+ {
+ return new Element[]{
+ getResourceMetadataDescriptor(),
+ getWSDL()};
+ } else {
+ if (WsrmdConstants.NAMESPACE_URI.equals(dialect))
+ {
+ return new Element[]{getResourceMetadataDescriptor()};
+ } else if (WsxConstants.WSDL_DIALECT.equals(dialect))
+ {
+ return new Element[]{getWSDL()};
+ }
+ }
+ return super.getMetadata(dialect);
+ }
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java index b8e22b4bc7..a00d2665ae 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java @@ -29,11 +29,9 @@ import java.util.*; *
* @author Andrea Gazzarini
*/
-public class Result
+public final class Result
{
- private long _statusCode;
- private String _statusText;
- private Map<String,Object> _outputParameters;
+ private final Map<String,Object> _outputParameters;
/**
* Builds a new result DTO with the given parameters.
@@ -42,53 +40,11 @@ public class Result * @param statusText the status message.
* @param outputParameters the output parameters.
*/
- public Result(long statusCode, String statusText,Map<String, Object> outputParameters)
+ public Result(Map<String, Object> outputParameters)
{
- this._statusCode = statusCode;
- this._statusText = statusText;
this._outputParameters = outputParameters;
}
-
- /**
- * Returns the status code.
- *
- * @return the status code.
- */
- public long getStatusCode()
- {
- return _statusCode;
- }
-
- /**
- * Sets the status code.
- *
- * @param statusCode the status code.
- */
- void setStatusCode(long statusCode)
- {
- this._statusCode = statusCode;
- }
-
- /**
- * Returns the status text.
- *
- * @return the status text.
- */
- public String getStatusText()
- {
- return _statusText;
- }
-
- /**
- * Sets the status text.
- *
- * @param statusText the status text.
- */
- void setStatusText(String statusText)
- {
- this._statusText = statusText;
- }
-
+
/**
* Returns the output parameterss.
*
@@ -98,14 +54,4 @@ public class Result {
return _outputParameters;
}
-
- /**
- * Sets the output parameters.
- *
- * @param outputParameters the output parameters.
- */
- void setOutputParameters(Map<String, Object> outputParameters)
- {
- this._outputParameters = outputParameters;
- }
-}
+}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java index 86aba0e5bb..c1678eb43f 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java @@ -128,7 +128,8 @@ class RmdBuilder implements IArtifactBuilder */
public Element[] getResourceMetadataDescriptor()
{
- Element [] properties = _metadataDescriptor.toArray(new Element[0]);
+ Element [] properties = _metadataDescriptor.toArray(
+ new Element[_metadataDescriptor.size()]);
return properties;
}
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java index c9ffd5eac0..35a919c295 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java @@ -35,7 +35,7 @@ import org.w3c.dom.Element; *
* @author Andrea Gazzarini
*/
-class WSDMArtifactsDirector
+final class WSDMArtifactsDirector
{
private final ObjectName _eventSourceObjectName;
private final MBeanInfo _metadata;
@@ -189,7 +189,8 @@ class WSDMArtifactsDirector *
* @param resource the ws resource.
*/
- public void setResource(Resource resource) {
+ public void setResource(Resource resource)
+ {
_wsdlBuilder.setWsdlPath(resource.getWsdlPath());
}
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java index 2a1bf059c3..94505d28f7 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java @@ -105,13 +105,18 @@ class WsArtifactsFactory _cache.put(searchKey, result);
- LOGGER.debug(Messages.QMAN_200040_WS_ARTIFACTS_CACHED,searchKey);
+ LOGGER.debug(
+ Messages.QMAN_200040_WS_ARTIFACTS_CACHED,
+ searchKey);
}
return result;
} catch(Exception exception)
{
- throw new ArtifactsNotAvailableException(result,exception,objectName);
+ throw new ArtifactsNotAvailableException(
+ result,
+ exception,
+ objectName);
}
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java index 02b25eb02f..6bfccda1ce 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java @@ -23,20 +23,22 @@ package org.apache.qpid.management.wsdm.capabilities; import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ObjectName;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
import org.apache.muse.core.Environment;
+import org.apache.muse.core.serializer.SerializerRegistry;
import org.apache.muse.util.ReflectUtils;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.apache.qpid.management.Messages;
import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterEnvironment;
import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
import org.apache.qpid.qman.debug.WsdlDebugger;
import org.apache.qpid.transport.util.Logger;
@@ -49,126 +51,61 @@ import org.w3c.dom.Element; *
* @author Andrea Gazzarini
*/
-class WsdlBuilder implements IArtifactBuilder {
+class WsdlBuilder implements IArtifactBuilder,Constants {
private final static Logger LOGGER = Logger.get(WsdlBuilder.class);
- private Environment _environment;
+ private WSDMAdapterEnvironment _environment;
private Document _document;
private Element schema;
-
- private ObjectSerializer serializer = new ObjectSerializer();
-
+ private Element _wsrpProperties;
+ private ObjectSerializer _serializer;
private ObjectName _objectName;
-
- private boolean mapTypeHasBeenDeclared;
- private boolean uuidTypeHasBeenDeclared;
private Map<String, String> arrayTypesAlreadyDeclared = new HashMap<String, String>();
+ private Element _arrayComplexType;
+ private Element _nestedArrayType;
+
+ /**
+ * For each attibute the corresponding xml type definition must be inserted on the QMan
+ * schema related section.
+ * After that, a reference to that definition must be declared on the wsrp element .
+ *
+ * @param attributeMetadata the attribute metadata.
+ * @throws BuilderException only if this builder wasn't able to get a reference (via XPath)
+ * to QMan schema section.
+ */
public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
{
try
{
- /*
- <xs:element name='accountAttributes'>
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs='unbounded' minOccurs='0' name='entry'>
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs='0' name='key' type='xs:string'/>
- <xs:element minOccurs='0' name='value' type='xs:anyType'/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-*/
- schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeMetadata.getName()));
- Element wsrpProperties = (Element) XPathAPI.selectSingleNode(
- _document,
- "/wsdl:definitions/wsdl:types/xsd:schema[" +
- "@targetNamespace='http://amqp.apache.org/qpid/management/qman']" +
- "/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence");
+ String attributeName = attributeMetadata.getName();
+ schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeName));
Element propertyRef= XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyRef.setAttribute(MIN_OCCURS, "0");
propertyRef.setAttribute(
- "ref",
- Names.PREFIX+":"+attributeMetadata.getName());
- propertyRef.setAttribute("minOccurs", "0");
- wsrpProperties.appendChild(propertyRef);
-
+ REF_ATTRIBUTE,
+ Names.PREFIX+":"+attributeName);
+
+ _wsrpProperties.appendChild(propertyRef);
} catch(Exception exception)
{
throw new BuilderException(exception);
}
}
- private final static QName XSD_ELEMENT_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"element","xsd");
- private final static QName XSD_COMPLEX_TYPE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"complexType","xsd");
- private final static QName XSD_SEQUENCE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"sequence","xsd");
-
@SuppressWarnings("unchecked")
private Element defineSchemaFor(String type, String attributeName) throws Exception
{
- if (type.equals("java.util.Map"))
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ String xmlType = null;
+ if (type.equals(Map.class.getName()))
{
- if (!mapTypeHasBeenDeclared)
- {
- Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- complexType.setAttribute("name","map");
- Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
-
- Element entry = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- entry.setAttribute("name", "entry");
- entry.setAttribute("minOccurs", "0");
- entry.setAttribute("maxOccurs", "unbounded");
-
- Element complexType2 = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- Element sequence2 = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
-
- Element key = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- key.setAttribute("name", "key");
- key.setAttribute("type", "xsd:string");
-
- Element value = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- value.setAttribute("name", "value");
- value.setAttribute("type", "xsd:anyType");
-
- sequence2.appendChild(key);
- sequence2.appendChild(value);
- complexType2.appendChild(sequence2);
- entry.appendChild(complexType2);
- sequence.appendChild(entry);
- complexType.appendChild(sequence);
- schema.appendChild(complexType);
- mapTypeHasBeenDeclared = true;
- }
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", "qman:map");
- return propertyDeclaration;
-
- } else if ("java.util.UUID".equals(type))
- {
- if (!uuidTypeHasBeenDeclared)
- {
- Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- complexType.setAttribute("name", "uuid");
- Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
- Element uuid = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- uuid.setAttribute("name", "uuid");
- uuid.setAttribute("type", "xsd:string");
- sequence.appendChild(uuid);
- complexType.appendChild(sequence);
- schema.appendChild(complexType);
- uuidTypeHasBeenDeclared = true;
- }
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", "qman:uuid");
- return propertyDeclaration;
+ xmlType="qman:map";
+ } else if (UUID.class.getName().equals(type))
+ {
+ xmlType = "qman:uuid";
} else if (type.startsWith("["))
{
Class arrayClass = Class.forName(type);
@@ -177,143 +114,40 @@ class WsdlBuilder implements IArtifactBuilder { arrayType = Character.toUpperCase(arrayType.charAt(0))+arrayType.substring(1);
if (!arrayTypesAlreadyDeclared.containsKey(type))
{
- Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- complexType.setAttribute("name", "arrayOf"+arrayType);
- Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
- Element entry = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- entry.setAttribute("name", "entry");
- entry.setAttribute("type", serializer.getXmlType(clazz));
- sequence.appendChild(entry);
- complexType.appendChild(sequence);
- schema.appendChild(complexType);
+ _arrayComplexType.setAttribute(NAME_ATTRIBUTE, "arrayOf"+arrayType);
+ _nestedArrayType.setAttribute(TYPE_ATTRIBUTE, _serializer.getXmlType(clazz));
+ schema.appendChild(_arrayComplexType);
arrayTypesAlreadyDeclared.put(type, arrayType);
}
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type));
- return propertyDeclaration;
+ xmlType = "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type);
}
- else {
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", serializer.getXmlType(Class.forName(type)));
-
- return propertyDeclaration;
+ else
+ {
+ xmlType = _serializer.getXmlType(Class.forName(type));
}
+ propertyDeclaration.setAttribute(NAME_ATTRIBUTE,attributeName);
+ propertyDeclaration.setAttribute(TYPE_ATTRIBUTE, xmlType);
+ return propertyDeclaration;
}
-
+
+ /**
+ * Initializes this builder.
+ *
+ * @param objectName the name of the current JMX entity.
+ * @throws BuilderException when it's not possible to proceed with the initialization.
+ */
public void begin(ObjectName objectName) throws BuilderException
{
this._objectName = objectName;
- try
- {
- Attr location = (Attr) XPathAPI.selectSingleNode(
- _document,
- "/wsdl:definitions/wsdl:service/wsdl:port/wsdl-soap:address/@location");
-
- StringBuilder builder = new StringBuilder("http://")
- .append(InetAddress.getLocalHost().getHostName())
- .append(':')
- .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
- .append('/')
- .append("qman")
- .append('/')
- .append("services/QManWsResource");
- location.setValue(builder.toString());
- } catch(Exception exception)
- {
- LOGGER.error(
- exception,
- Messages.QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE);
- throw new BuilderException(exception);
- }
-
- try
- {
- schema = (Element) XPathAPI.selectSingleNode(
- _document.getDocumentElement(),
- "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']");
- } catch(Exception exception)
- {
- LOGGER.error(
- exception,
- Messages.QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND);
- throw new BuilderException(exception);
- }
-/*
- <xs:complexType name='InvocationResult'>
- <xs:sequence>
- <xs:element name='statusCode' type="xsd:long" />
- <xs:element name='statusText' type="xsd:string" />
- <xs:element name='outputParameters'>
- <xs:complexType>
- <xs:sequence>
-
- <xs:element maxOccurs='unbounded' minOccurs='0' name='entry'>
-
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs='0' name="name' type='xs:string'/>
- <xs:element minOccurs='0' name="value" type='xs:anyType'/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
-*/
- Element complexTypeResult = _document.createElement("xsd:complexType");
- complexTypeResult.setAttribute("name", "result");
- Element sequence = _document.createElement("xsd:sequence");
- complexTypeResult.appendChild(sequence);
-
- Element statusCode = _document.createElement("xsd:element");
- statusCode.setAttribute("name", "statusCode");
- statusCode.setAttribute("type", "xsd:long");
-
- Element statusText = _document.createElement("xsd:element");
- statusText.setAttribute("name", "statusText");
- statusText.setAttribute("type", "xsd:string");
-
- sequence.appendChild(statusCode);
- sequence.appendChild(statusText);
-
- Element outputParams = _document.createElement("xsd:complexType");
- outputParams.setAttribute("name", "outputParameters");
- sequence.appendChild(outputParams);
-
- Element complexTypeOutput = _document.createElement("xsd:complexType");
- Element outputSequence = _document.createElement("xsd:sequence");
+ this._serializer = (ObjectSerializer) SerializerRegistry.getInstance().getSerializer(Object.class);
- outputParams.appendChild(complexTypeOutput);
- complexTypeOutput.appendChild(outputSequence);
+ createWsrpPropertiesElement();
- Element entry = _document.createElement("xsd:element");
- entry.setAttribute("maxOccurs", "unbounded");
- entry.setAttribute("minOccurs", "0");
- entry.setAttribute("name", "entry");
+ createReusableArrayComplextType();
- outputSequence.appendChild(entry);
+ replaceDummyServiceLocationOnWsdl();
- Element entryComplexType = _document.createElement("xsd:complexType");
- Element entrySequence = _document.createElement("xsd:sequence");
- entryComplexType.appendChild(entrySequence);
- entry.appendChild(entryComplexType);
-
- Element name = _document.createElement("xsd:name");
- name.setAttribute("name", "key");
- name.setAttribute("type", "xsd:string");
-
- Element value = _document.createElement("xsd:element");
- value.setAttribute("name", "value");
- value.setAttribute("type", "xsd:anyType");
-
- entrySequence.appendChild(name);
- entrySequence.appendChild(value);
-
- schema.appendChild(complexTypeResult);
+ createSchemaElement();
}
public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
@@ -350,9 +184,9 @@ class WsdlBuilder implements IArtifactBuilder { <xs:sequence />
</xs:complexType>
*/
+
try
{
- // <xs:element name='purgeRequest' type='qman:purgeRequest' />
// <xsd:element xmlns="" name="purgeRequest" type="qman:purgeRequest"/>
Element methodRequestElement= _document.createElement("xsd:element");
@@ -361,13 +195,13 @@ class WsdlBuilder implements IArtifactBuilder { methodRequestElement.setAttribute("type", "qman:"+methodNameRequest);
// <xs:element name='purgeResponse' type='qman:purgeResponse' />
- Element methodResponseElement= _document.createElement("xsd:element");
+// Element methodResponseElement= _document.createElement("xsd:element");
String methodNameResponse= operationMetadata.getName()+"Response";
- methodResponseElement.setAttribute("name", methodNameResponse);
- methodResponseElement.setAttribute("type", "qman:"+methodNameResponse);
+// methodResponseElement.setAttribute("name", methodNameResponse);
+// methodResponseElement.setAttribute("type", "qman:result");//+methodNameResponse);
schema.appendChild(methodRequestElement);
- schema.appendChild(methodResponseElement);
+// schema.appendChild(methodResponseElement);
/*
<xs:complexType name='purgeRequest'>
@@ -391,19 +225,6 @@ class WsdlBuilder implements IArtifactBuilder { methodNameRequestComplexType.appendChild(methodNameRequestComplexTypeSequence);
schema.appendChild(methodNameRequestComplexType);
- Element methodNameResponseComplexType = _document.createElement("xsd:complexType");
- methodNameResponseComplexType.setAttribute("name", methodNameResponse);
-
- Element methodNameResponseSequence = _document.createElement("xsd:sequence");
- methodNameResponseComplexType.appendChild(methodNameResponseSequence);
-
- Element result = _document.createElement("xsd:element");
- result.setAttribute("name", "result");
- result.setAttribute("type", "qman:result");
- methodNameResponseSequence.appendChild(result);
-
- schema.appendChild(methodNameResponseComplexType);
-
/*
<message name="purgeResponseMessage">
<part element='qman:purgeResponse' name='purgeResponse'></part>
@@ -428,7 +249,7 @@ class WsdlBuilder implements IArtifactBuilder { Element responseMessage = _document.createElement("wsdl:message");
responseMessage.setAttribute("name", responseMessageName);
Element responsePart = _document.createElement("wsdl:part");
- responsePart.setAttribute("element", "qman:"+methodNameResponse);
+ responsePart.setAttribute("element", "qman:result");//+methodNameResponse);
responsePart.setAttribute("name", methodNameResponse);
responseMessage.appendChild(responsePart);
@@ -506,29 +327,134 @@ class WsdlBuilder implements IArtifactBuilder { }
}
+ /**
+ * Director callback : all attributes have been notified.
+ * Nothing to do here.
+ */
public void endAttributes()
{
// N.A.
}
+ /**
+ * Director callback : all operations have been notified.
+ * Nothing to do here.
+ */
public void endOperations()
{
-
+ // N.A.
}
+ /**
+ * Returns the WSDL built by this builder.
+ *
+ * @return the WSDL built by this builder.
+ */
public Document getWsdl()
{
WsdlDebugger.debug(_objectName,_document);
return _document;
}
+ /**
+ * Injects the application context environment
+ * on this builder.
+ *
+ * @param environment the application context environment.
+ */
public void setEnvironment(Environment environment)
{
- this._environment = environment;
+ this._environment = (WSDMAdapterEnvironment)environment;
}
+ /**
+ * Injects the path of the wsdl document.
+ *
+ * @param wsdlPath the path of the wsdl document.
+ */
public void setWsdlPath(String wsdlPath)
{
_document = WsdlUtils.createWSDL(_environment, wsdlPath, true);
}
-}
+
+ /**
+ * Create a reference to the WSRP properties element.
+ *
+ * @throws BuilderException in case of XPath evaluation problem.
+ */
+ private void createWsrpPropertiesElement() throws BuilderException
+ {
+ try
+ {
+ _wsrpProperties = (Element) XPathAPI.selectSingleNode(
+ _document,
+ WSRP_PROPERTIES_XPATH);
+ } catch (TransformerException exception)
+ {
+ LOGGER.error(Messages.QMAN_100040_UNABLE_TO_LOCATE_WSRP_PROPERTIES);
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Creates a template element that will be used for array
+ * type schema declaration(s).
+ */
+ private void createReusableArrayComplextType()
+ {
+ _arrayComplexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+ _nestedArrayType = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ _nestedArrayType.setAttribute(NAME_ATTRIBUTE, "entry");
+ sequence.appendChild(_nestedArrayType);
+ _arrayComplexType.appendChild(sequence);
+ }
+
+ private void createSchemaElement() throws BuilderException
+ {
+ try
+ {
+ schema = (Element) XPathAPI.selectSingleNode(
+ _document.getDocumentElement(),
+ QMAN_SCHEMA_XPATH);
+ } catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND);
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * The template WSDL contains a dummy URL as service location that
+ * needs to be replaced with the real service address.
+ *
+ * @throws BuilderException when replacement fails (XPath problem).
+ */
+ private void replaceDummyServiceLocationOnWsdl() throws BuilderException
+ {
+ try
+ {
+ Attr location = (Attr) XPathAPI.selectSingleNode(
+ _document,
+ SERVICE_LOCATION_XPATH);
+
+ StringBuilder builder = new StringBuilder("http://")
+ .append(InetAddress.getLocalHost().getHostName())
+ .append(':')
+ .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
+ .append('/')
+ .append(_environment.getContextPath())
+ .append('/')
+ .append("services/QManWsResource");
+ location.setValue(builder.toString());
+ } catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE);
+ throw new BuilderException(exception);
+ }
+ }
+}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java index 25bb871e75..116d74727a 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java @@ -50,6 +50,9 @@ public class EntityInstanceNotFoundFault extends QManFault */
public EntityInstanceNotFoundFault(EndpointReference endpointReference, ObjectName targetEntityName)
{
- super(endpointReference,EXCEPTION_QNAME, targetEntityName.getCanonicalName());
+ super(
+ endpointReference,
+ EXCEPTION_QNAME,
+ targetEntityName.getCanonicalName());
}
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java index bc214b8b25..588879b951 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java @@ -25,7 +25,6 @@ import javax.management.ObjectName; import org.w3c.dom.Document; import org.w3c.dom.Element; - /** * Thread-scoped session. * @@ -35,7 +34,8 @@ public class ThreadSession { private ObjectName _objectName; private Document _wsdl; - private Element [] additionalProperties; + private Element [] _wsrmdProperties; + /** * Empty constructor. */ @@ -90,7 +90,7 @@ public class ThreadSession */ public Element[] getResourceMetadataDescriptor() { - return additionalProperties; + return _wsrmdProperties; } /** @@ -100,6 +100,6 @@ public class ThreadSession */ public void setResourceMetadataDescriptor(Element[] rmd) { - this.additionalProperties = rmd; + this._wsrmdProperties = rmd; } }
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java index f47a587830..b5d978e0e5 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java @@ -64,6 +64,11 @@ public class WSDMAdapterEnvironment extends AbstractEnvironment return _realDirectory;
}
+ /**
+ * Returns the default endpoint reference URI.
+ *
+ * @return the default endpoint reference URI.
+ */
public String getDefaultURIPrefix()
{
return new StringBuilder()
@@ -79,4 +84,14 @@ public class WSDMAdapterEnvironment extends AbstractEnvironment .append("/services/")
.toString();
}
+
+ /**
+ * Returns the context path name of QMan application.
+ *
+ * @return the context path name of QMan application.
+ */
+ public String getContextPath()
+ {
+ return _servletContext.getContextPath();
+ }
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java index 0af570eacf..b819d52ad1 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java @@ -38,8 +38,6 @@ import org.w3c.dom.Element; */
public class InvocationResultSerializer implements Serializer
{
- private Serializer _longSerializer = SerializerRegistry.getInstance().getSerializer(long.class);
- private Serializer _stringSerializer = SerializerRegistry.getInstance().getSerializer(String.class);
private Serializer _mapSerializer = SerializerRegistry.getInstance().getSerializer(Map.class);
/**
@@ -51,26 +49,8 @@ public class InvocationResultSerializer implements Serializer @SuppressWarnings("unchecked")
public Object fromXML(Element elementData) throws SoapFault
{
- long statusCode = 0;
- String statusText = null;
- Map<String, Object> outputSection = null;
-
- Element[] elements = XmlUtils.getAllElements(elementData);
- for (Element element : elements)
- {
- if ("statusCode".equals(element.getNodeName()))
- {
- statusCode = (Long) _longSerializer.fromXML(element);
- } else if ("statusText".equals(element.getNodeName()))
- {
- statusText = (String) _stringSerializer.fromXML(element);
- } else if ("outputParameters".equals(element.getNodeName()))
- {
- outputSection = (Map<String, Object>) _mapSerializer.fromXML(element);
- }
- }
-
- return new Result(statusCode,statusText,outputSection);
+ Element outputParameters = XmlUtils.getFirstElement(elementData);
+ return new Result((Map<String, Object>) _mapSerializer.fromXML(outputParameters));
}
/**
@@ -95,17 +75,11 @@ public class InvocationResultSerializer implements Serializer {
Result result = (Result) obj;
Element root = XmlUtils.createElement(qname);
- Element statusCode = SerializerRegistry.getInstance().getSerializer(long.class).toXML(result.getStatusCode(), new QName("statusCode"));
- Element statusText = SerializerRegistry.getInstance().getSerializer(String.class).toXML(result.getStatusText(), new QName("statusText"));
-
- root.appendChild(statusCode);
- root.appendChild(statusText);
if (result.getOutputParameters() != null)
{
Element outputSection = SerializerRegistry.getInstance().getSerializer(Map.class).toXML(result.getOutputParameters(), new QName("outputParameters"));
root.appendChild(outputSection);
}
- return root;
-
+ return root;
}
}
\ No newline at end of file diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java index 1d0d02c669..07e1dfdc56 100644 --- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java +++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java @@ -62,25 +62,29 @@ public class MapSerializer implements Serializer public Object fromXML(Element xml) throws SoapFault
{
Map<Object,Object> result = new HashMap<Object,Object>();
- Element[] children = XmlUtils.getAllElements(xml);
- Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class);
- for (Element entry : children)
+ if (xml != null)
{
- Element[] keysAndValues = XmlUtils.getAllElements(entry);
- Object key = null;
- Object value = null;
- for (Element element : keysAndValues)
+ Element[] children = XmlUtils.getAllElements(xml);
+ Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+
+ for (Element entry : children)
{
- if (Names.KEY.equals(element.getLocalName()))
- {
- key = _stringSerializer.fromXML(element);
- } else if (Names.VALUE.equals(element.getLocalName()))
+ Element[] keysAndValues = XmlUtils.getAllElements(entry);
+ Object key = null;
+ Object value = null;
+ for (Element element : keysAndValues)
{
- value = objectDeserializer.fromXML(element);
+ if (Names.KEY.equals(element.getLocalName()))
+ {
+ key = _stringSerializer.fromXML(element);
+ } else if (Names.VALUE.equals(element.getLocalName()))
+ {
+ value = objectDeserializer.fromXML(element);
+ }
}
+ result.put(key, value);
}
- result.put(key, value);
}
return result;
}
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl index 69647521ba..16169c9b78 100644 --- a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl +++ b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl @@ -93,7 +93,33 @@ </xsd:complexContent>
</xsd:complexType>
</xsd:element>
- </xsd:schema>
+
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="key" type="xsd:string"/>
+ <xsd:element name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="outputParameters" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ </xsd:schema>
</wsdl:types>
<wsdl:message name="GetMetadataMsg">
<wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl index 8764c18fc9..d53bf60f3a 100644 --- a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl +++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl @@ -424,23 +424,22 @@ This document and the information contained herein is provided on an "AS IS" bas <wsdl:fault name="InvalidResourcePropertyQNameFault" message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
</wsdl:operation>
- </wsdl:portType>
+<!-- </wsdl:portType>
-<!-- ====== PausableSubscriptionManager PortType Definition ======= -->
<wsdl:portType name="PausableSubscriptionManager">
-
+-->
<!-- === PausableSubscriptionManager specific operations === -->
<wsdl:operation name="PauseSubscription">
- <wsdl:input message="wsntw:PauseSubscriptionRequest"/>
- <wsdl:output message="wsntw:PauseSubscriptionResponse"/>
+ <wsdl:input message="wsntw:PauseSubscriptionRequest" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionRequest"/>
+ <wsdl:output message="wsntw:PauseSubscriptionResponse" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionResponse"/>
<wsdl:fault name="ResourceUnknownFault"
message="wsrf-rw:ResourceUnknownFault" />
<wsdl:fault name="PauseFailedFault"
message="wsntw:PauseFailedFault" />
</wsdl:operation>
<wsdl:operation name="ResumeSubscription">
- <wsdl:input message="wsntw:ResumeSubscriptionRequest"/>
- <wsdl:output message="wsntw:ResumeSubscriptionResponse"/>
+ <wsdl:input message="wsntw:ResumeSubscriptionRequest" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionRequest"/>
+ <wsdl:output message="wsntw:ResumeSubscriptionResponse" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionResponse"/>
<wsdl:fault name="ResourceUnknownFault"
message="wsrf-rw:ResourceUnknownFault" />
<wsdl:fault name="ResumeFailedFault"
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl index dc4581d8a8..379382c18d 100644 --- a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl +++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl @@ -200,7 +200,7 @@ </wsdl:binding>
<wsdl:service name="ServiceGroupEntryService">
<wsdl:port name="ServiceGroupEntryPort" binding="tns:ServiceGroupEntryBinding">
- <wsdl-soap:address location="http://romagazzarini:8080/wsrf/services/ServiceGroupEntry"/>
+ <wsdl-soap:address location="http://localhost:8080/wsrf/services/ServiceGroupEntry"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java index 12ba1fab73..9abcd08eef 100644 --- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java @@ -63,5 +63,5 @@ public interface TestConstants int SAMPLE_ACCESS_CODE = 1; String YEARS = "years"; int SAMPLE_MIN_VALUE = 1; - int SAMPLE_MAX_VALUE = 120; + int SAMPLE_MAX_VALUE = 120; }
\ No newline at end of file diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java index 8e9c3ccd6b..72bd45f70f 100644 --- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java @@ -23,16 +23,13 @@ package org.apache.qpid.management.configuration; import java.util.Map; import java.util.UUID; +import junit.framework.TestCase; + import org.apache.qpid.management.TestConstants; import org.apache.qpid.management.domain.handler.base.IMessageHandler; import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler; import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler; import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler; -import org.apache.qpid.management.domain.model.AccessMode; -import org.apache.qpid.management.domain.model.type.Type; -import org.apache.qpid.management.domain.model.type.Uint8; - -import junit.framework.TestCase; /** * Test case for Configuration singleton. @@ -46,22 +43,7 @@ public class ConfigurationTest extends TestCase { assertSame(Configuration.getInstance(),Configuration.getInstance()); } - - /** - * Tests the execution of getType() method when a valid code is supplied. - * - * <br>precondition : the requested type already exist on the configuration. - * <br>postcondition : the requested type is returned and no exception is thrown. - */ - public void testGetTypeOk() throws UnknownTypeCodeException - { - TypeMapping mapping = new TypeMapping(TestConstants.VALID_CODE,new Uint8()); - Configuration.getInstance().addTypeMapping(mapping); - Type type = Configuration.getInstance().getType(TestConstants.VALID_CODE); - assertTrue(type instanceof Uint8); - } - /** * Tests the execution of getType() method when a unknown code is supplied. * @@ -79,22 +61,7 @@ public class ConfigurationTest extends TestCase assertEquals(TestConstants.VALID_CODE*10001,expected.getCode()); } } - - /** - * Tests the execution of getAccessMode() method when a valid code is supplied. - * - * <br>precondition : the requested access mode already exist on the configuration. - * <br>postcondition : the requested access mode is returned and no exception is thrown. - */ - public void testGetAccessModeOk() throws UnknownAccessCodeException - { - AccessModeMapping mapping = new AccessModeMapping(TestConstants.VALID_CODE,AccessMode.RW); - Configuration.getInstance().addAccessModeMapping(mapping); - AccessMode accessMode = Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE); - - assertSame(AccessMode.RW,accessMode); - } - + /** * Tests the execution of getAccessMode() method when a unknown code is supplied. * diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java new file mode 100644 index 0000000000..900d14c72e --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java @@ -0,0 +1,143 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.UUID;
+
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for WS-Resource lifecycle management.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseWsDmAdapterTestCase extends TestCase implements TestConstants{
+
+ protected MBeanServer _managementServer;
+ protected ObjectName _resourceObjectName;
+
+ protected WsResourceClient _resourceClient;
+ protected MBeanInfo _mbeanInfo;
+
+ /**
+ * Set up fixture for this test case.
+ *
+ * @throws Exception when the test case intialization fails.
+ */
+ protected void setUp() throws Exception
+ {
+ _managementServer = ManagementFactory.getPlatformMBeanServer();
+
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is " +
+ "it possible that service group children list is not empty?",
+ 0,
+ members.length);
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "createQueue",
+ new Object[]{_resourceObjectName = createResourceName()},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+ assertEquals(
+ "One resource has just been created so " +
+ "I expect to find it on service group children list...",
+ 1,
+ members.length);
+
+ _resourceClient = members[0];
+ _mbeanInfo = _managementServer.getMBeanInfo(_resourceObjectName);
+ }
+
+ /**
+ * Shutdown procedure for this test case.
+ *
+ * @throws Exception when either the server or some resource fails to shutdown.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "unregister",
+ new Object[]{_resourceObjectName},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is it possible that service group children list is not empty?",
+ 0,
+ members.length);
+ }
+
+ /**
+ * Creates a service group client reference.
+ *
+ * @return a service group client reference.
+ */
+ private ServiceGroupClient getServiceGroupClient()
+ {
+ URI address = URI.create(
+ Protocol.DEFAULT_ENDPOINT_URI.replaceFirst("8080",System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
+ return new ServiceGroupClient(new EndpointReference(address));
+ }
+
+ /**
+ * In order to test the behaviour of the WS-DM adapter, at
+ * least one resource must be created. This is the method that
+ * returns the name (ObjectName on JMX side, Resource-ID on WSDM side)
+ * of that resource
+ *
+ * @return the name of the MBean instance that will be created.
+ * @throws Exception when the name if malformed. Practically never.
+ */
+ private ObjectName createResourceName() throws Exception
+ {
+ return new ObjectName(
+ "Q-MAN:objectId="+UUID.randomUUID()+
+ ", brokerID="+UUID.randomUUID()+
+ ",class=queue"+
+ ",package=org.apache.qpid"+
+ ",name="+System.currentTimeMillis());
+ }
+}
\ No newline at end of file diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java new file mode 100644 index 0000000000..d59e7a39e5 --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java @@ -0,0 +1,125 @@ +/*
+ *
+ * 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.management.wsdm;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetMultipleResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Tests the GetMultipleResourceProperties interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetMultipleResourceProperties request contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetMultipleResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.getMultipleResourceProperties(new QName[]{});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Test the WS-RP GetResourceProperties interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : Properties are correctly returned according to WSRP interface and they (their value)
+ * are matching with corresponding MBean properties.
+ */
+ public void testGetMultipleResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ QName[] names = new QName[attributesMetadata.length];
+
+ int index = 0;
+ for (MBeanAttributeInfo attributeMetadata : _mbeanInfo.getAttributes())
+ {
+ QName qname = new QName(Names.NAMESPACE_URI,attributeMetadata.getName(),Names.PREFIX);
+ names[index++] = qname;
+ }
+
+ Element[] properties =_resourceClient.getMultipleResourceProperties(names);
+ for (Element element : properties)
+ {
+ String name = element.getLocalName();
+ Object value = _managementServer.getAttribute(_resourceObjectName, name);
+ if ("Name".equals(name))
+ {
+ assertEquals(
+ value,
+ element.getTextContent());
+ } else if ("Durable".equals(name))
+ {
+ assertEquals(
+ value,
+ Boolean.valueOf(element.getTextContent()));
+ } else if ("ExpireTime".equals(name))
+ {
+ assertEquals(
+ value,
+ new Date(Long.valueOf(element.getTextContent())));
+ } else if ("MsgTotalEnqueues".equals(name))
+ {
+ assertEquals(
+ value,
+ Long.valueOf(element.getTextContent()));
+ } else if ("ConsumerCount".equals(name))
+ {
+ assertEquals(
+ value,
+ Integer.valueOf(element.getTextContent()));
+ }else if ("VhostRef".equals(name))
+ {
+ assertEquals(
+ value,
+ UUID.fromString(element.getTextContent()));
+ }
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java new file mode 100644 index 0000000000..e18e928cf4 --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java @@ -0,0 +1,105 @@ +/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.reflect.Array;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+
+ /**
+ * Test the WS-RP GetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : property values coming from WS-DM resource are the same of the JMX interface.
+ */
+ public void testGetResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ _managementServer.getAttribute(_resourceObjectName,name),
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ _managementServer.getAttribute(_resourceObjectName,name));
+ }
+ }
+ }
+
+ /**
+ * Tests the GetMultipleResourceProperties interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetMultipleResourceProperties request contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.getResourceProperty(new QName("a","b","c"));
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java new file mode 100644 index 0000000000..862115f841 --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java @@ -0,0 +1,134 @@ +/*
+ *
+ * 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.management.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyDocumentTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Tests the GetResourcePropertyDocument interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetResourcePropertyDocument contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetResourcePropertyDocumentKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+ _resourceClient.setTrace(true);
+
+ _resourceClient.getResourcePropertyDocument();
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : A read / write property is correctly set according to WSRP interface.
+ */
+ public void testGetAndPutResourcePropertyDocumentOK() throws Exception
+ {
+ String expectedMgmtPubIntervalValue = "4321";
+ String propertyName = "MgmtPubInterval";
+
+ Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
+ Element [] properties = XmlUtils.getAllElements(propertiesDocument);
+
+ for (Element element : properties)
+ {
+ if (propertyName.equals(element.getLocalName())) {
+ element.setTextContent(expectedMgmtPubIntervalValue);
+ } else {
+ propertiesDocument.removeChild(element);
+ }
+ }
+
+ _resourceClient.putResourcePropertyDocument(propertiesDocument);
+
+ Element newProperties = _resourceClient.getResourcePropertyDocument();
+
+ Element mgmtPubInterval = XmlUtils.getElement(
+ newProperties, new QName(
+ Names.NAMESPACE_URI,
+ propertyName,
+ Names.PREFIX));
+
+ assertEquals(expectedMgmtPubIntervalValue,mgmtPubInterval.getTextContent());
+ }
+
+ /**
+ * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
+ * Specifically it tries to update the value of a read-only property.
+ *
+ * <br>precondition : a ws resource exists, it is registered and has at least one read-only property.
+ * <br>postcondition : An exception is thrown indicating the failure.
+ */
+ public void testGetAndPutResourcePropertyDocumentKO_WithReadOnlyProperty() throws Exception
+ {
+ String propertyName = "Name";
+
+ Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
+ Element [] properties = XmlUtils.getAllElements(propertiesDocument);
+
+ for (Element element : properties)
+ {
+ if (propertyName.equals(element.getLocalName())) {
+ element.setTextContent("ThisIsTheNewValueOfNameProperty");
+ } else {
+ propertiesDocument.removeChild(element);
+ }
+ }
+
+ try
+ {
+ _resourceClient.putResourcePropertyDocument(propertiesDocument);
+ fail("It's not possible to update the value of a read-only property.");
+ } catch (SoapFault expected)
+ {
+
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java new file mode 100644 index 0000000000..046f2226e6 --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java @@ -0,0 +1,169 @@ +/*
+ *
+ * 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.management.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for QMan metadata exchange interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MetadataExchangeInterfaceTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Test the MetadataExchange interface when the corresponding
+ * request doesn't contain a dialect. According to WS-MetadataExchange specs this should be
+ * intended as a "give-me-all-metadata" for that resource.
+ *
+ * <br>precondition : the GetMetadata request doesn't contain a dialect.
+ * <br>postcondition : the whole metadata document is returned with all metadata .
+ * It will contain both WSDL and RMD.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithoutDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{""});
+
+ assertEquals(2,result.length);
+
+ Element rmdMetadataSection = result[0];
+ Element wsdlMetadataSection = result[1];
+
+ Element rmd = XmlUtils.getFirstElement(rmdMetadataSection);
+ Element wsdl = XmlUtils.getFirstElement(wsdlMetadataSection);
+
+ assertEquals("MetadataDescriptor",rmd.getLocalName());
+ assertEquals("definitions",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface when the WSDL dialect is specified on the request.
+ *
+ * <br>precondition : the GetMetadata request contains WSDL dialect.
+ * <br>postcondition : the resource WSDL metadata document is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithWSDLDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{WsxConstants.WSDL_DIALECT});
+
+ assertEquals(1,result.length);
+
+ Element wsdlMetadataSection = result[0];
+
+ Element wsdl = XmlUtils.getFirstElement(wsdlMetadataSection);
+
+ assertEquals("definitions",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface when the RMD dialect is specified on the request.
+ *
+ * <br>precondition : the GetMetadata request contains RMD dialect.
+ * <br>postcondition : the RMD metadata document is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithRMDDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{WsrmdConstants.NAMESPACE_URI});
+
+ assertEquals(1,result.length);
+
+ Element rmdMetadataSection = result[0];
+
+ Element wsdl = XmlUtils.getFirstElement(rmdMetadataSection);
+
+ assertEquals("MetadataDescriptor",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface with an unknown metadata dialect.
+ *
+ * <br>precondition : the GetMetadata request contains an unknown dialect.
+ * <br>postcondition : the returned metadata section is empty.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataKO_WithoutUnknownDialect() throws Exception
+ {
+ Element [] metadata = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{"HopeThisIsAnUnknownDialect"});
+
+ assertEquals(0,metadata.length);
+ }
+
+ /**
+ * Test the MetadataExchange interface with an unknown metadata dialect.
+ *
+ * <br>precondition : the GetMetadata request contains an unknown dialect.
+ * <br>postcondition : the returned metadata section is empty.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataKO_WithoutUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.invoke(getProxyHandler(), new Object[]{""});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Returns a proxy handler used for working with metadata exchange
+ * interface.
+ *
+ * @return a metadata proxy handler.
+ */
+ private ProxyHandler getProxyHandler()
+ {
+ ProxyHandler getMetadataHandler = new ReflectionProxyHandler();
+ getMetadataHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ getMetadataHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", "wsx"));
+ getMetadataHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", "wsx")});
+ getMetadataHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", "wsx"));
+ getMetadataHandler.setReturnType(Element[].class);
+ return getMetadataHandler;
+ }
+}
\ No newline at end of file diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java new file mode 100644 index 0000000000..afc4a62085 --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java @@ -0,0 +1,580 @@ +/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+
+/**
+ * Test case for QMan operation invocation interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class OperationInvocationInterfaceTestCase extends BaseWsDmAdapterTestCase
+{
+ private Map<String, ProxyHandler> _invocationHandlers = createInvocationHandlers();
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of a byte type array between requestor
+ * and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown
+ * and byte array are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withByteArray() throws Exception
+ {
+ byte [] expectedByteResult = {1,3,4,2,2,44,22,3,3,55,66};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithByteArray"),
+ new Object[]{expectedByteResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertArrayEquals(expectedByteResult, out.get(byte[].class.getName()));
+ }
+
+ /**
+ * Test a simple operation invocation on a WS-Resource.
+ * This method tests a simple operation without any input and output parameters.
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation
+ * is available on that.
+ * <br>postcondition : invocations are executed successfully an no exception is thrown.
+ */
+ @SuppressWarnings("unchecked")
+ public void testSimpleOperationInvocationOK() throws Exception
+ {
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("voidWithoutArguments"),
+ null);
+
+ assertNotNull(result);
+ }
+
+ /**
+ * Test a the invocation on a WS-Resource with a method that throws an exception..
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : an exception is thrown by the requested method.
+ */
+ @SuppressWarnings("unchecked")
+ public void testInvocationException_OK() throws Exception
+ {
+ try
+ {
+ _resourceClient.invoke(
+ _invocationHandlers.get("throwsException"),
+ null);
+ fail("The requested operation has thrown an exception so a Soap Fault is expected...");
+ } catch(SoapFault expected)
+ {
+ }
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of UUID type between requestor and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested operation
+ * is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown
+ * and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withUUID() throws Exception
+ {
+ UUID expectedUuid = UUID.randomUUID();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithUUID"),
+ new Object[]{expectedUuid});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertEquals(expectedUuid, out.get("uuid"));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of Map type between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is
+ * thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withMap() throws Exception
+ {
+ Map<String,Object> expectedMap = new HashMap<String, Object>();
+ expectedMap.put("p1", new Long(1));
+ expectedMap.put("p2", Boolean.TRUE);
+ expectedMap.put("p3", 1234d);
+ expectedMap.put("p4", 11.2f);
+ expectedMap.put("p5", 1272);
+ expectedMap.put("p6", (short)12);
+ expectedMap.put("p7", "aString");
+ expectedMap.put("p8", "http://qpid.apache.org");
+ expectedMap.put("p9", new Date(12383137128L));
+ expectedMap.put("p10", new byte[]{1,2,2,3,3,4});
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithMap"),
+ new Object[]{expectedMap});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) ((Map<String, Object>) getOutputParameters.invoke(result)).get("map");
+
+ assertEquals("Output parameters must be 10.",10,out.size());
+ assertEquals(expectedMap.get("p1"),out.get("p1"));
+ assertEquals(expectedMap.get("p2"),out.get("p2"));
+ assertEquals(expectedMap.get("p3"),out.get("p3"));
+ assertEquals(expectedMap.get("p4"),out.get("p4"));
+ assertEquals(expectedMap.get("p5"),out.get("p5"));
+ assertEquals(expectedMap.get("p6"),out.get("p6"));
+ assertEquals(expectedMap.get("p7"),out.get("p7"));
+ assertEquals(expectedMap.get("p8"),out.get("p8"));
+ assertEquals(expectedMap.get("p9"),out.get("p9"));
+ assertTrue( Arrays.equals((byte[])expectedMap.get("p10"),(byte[])out.get("p10")));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of simple types between requestor and
+ * service provider.
+ *
+ * With simple types we mean :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is
+ * available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and
+ * parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withSimpleTypes() throws Exception
+ {
+ Long expectedLongResult = new Long(1373);
+ Boolean expectedBooleanResult = Boolean.TRUE;
+ Double expectedDoubleResult = new Double(12763.44);
+ Float expectedFloatResult = new Float(2727.233f);
+ Integer expectedIntegerResult = new Integer(28292);
+ Short expectedShortResult = new Short((short)227);
+ String expectedStringResult = "expectedStringResult";
+ URI expectedUriResult = URI.create("http://qpid.apache.org/");
+ Date expectedDateResult = new Date();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypes"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long output parameter not found on result object.",out.containsValue(expectedLongResult));
+ assertTrue("Boolean output parameter not found on result object.",out.containsValue(expectedBooleanResult));
+ assertTrue("Double output parameter not found on result object.",out.containsValue(expectedDoubleResult));
+ assertTrue("Float output parameter not found on result object.",out.containsValue(expectedFloatResult));
+ assertTrue("Integer output parameter not found on result object.",out.containsValue(expectedIntegerResult));
+ assertTrue("Short output parameter not found on result object.",out.containsValue(expectedShortResult));
+ assertTrue("String output parameter not found on result object.",out.containsValue(expectedStringResult));
+ assertTrue("URI output parameter not found on result object.",out.containsValue(expectedUriResult));
+ assertTrue("Date output parameter not found on result object.",out.containsValue(expectedDateResult));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of arrays between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long (xsd:long)
+ * <li>java.lang.Integer (xsd:int / xsd:integer)
+ * <li>java.lang.Double (xsd:double)
+ * <li>java.lang.Float (xsd:float)
+ * <li>java.lang.Short (xsd:short)
+ * <li>java.lang.Boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withWrapperArrays() throws Exception
+ {
+ Long [] expectedLongResult = {new Long(2),new Long(1),new Long(3),new Long(4)};
+ Boolean [] expectedBooleanResult = { Boolean.TRUE,Boolean.FALSE,Boolean.FALSE};
+ Double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ Float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ Integer [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ Short [] expectedShortResult = {(short)227,(short)23,(short)9};
+ String [] expectedStringResult = {"s1","s2","s333","s4"};
+ URI [] expectedUriResult = {
+ URI.create("http://qpid.apache.org/"),
+ URI.create("http://www.apache.org"),
+ URI.create("http://projects.apache.org")};
+
+ Date [] expectedDateResult = {
+ new Date(),
+ new Date(38211897),
+ new Date(903820382)};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long array doesn't match.",Arrays.equals(expectedLongResult, (Long[])out.get(Long.class.getName())));
+ assertTrue("Boolean array doesn't match.",Arrays.equals(expectedBooleanResult, (Boolean[])out.get(Boolean.class.getName())));
+ assertTrue("Double array doesn't match.",Arrays.equals(expectedDoubleResult, (Double[])out.get(Double.class.getName())));
+ assertTrue("Float array doesn't match.",Arrays.equals(expectedFloatResult, (Float[])out.get(Float.class.getName())));
+ assertTrue("Integer array doesn't match.", Arrays.equals(expectedIntegerResult, (Integer[])out.get(Integer.class.getName())));
+ assertTrue("Short array doesn't match.",Arrays.equals(expectedShortResult, (Short[])out.get(Short.class.getName())));
+ assertTrue("String array doesn't match.",Arrays.equals(expectedStringResult, (String[])out.get(String.class.getName())));
+ assertTrue("URI array doesn't match.",Arrays.equals(expectedUriResult, (URI[])out.get(URI.class.getName())));
+ assertTrue("Date array doesn't match.",Arrays.equals(expectedDateResult, (Date[])out.get(Date.class.getName())));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of primitive type arrays between requestor and service provider.
+ * NOte that even the sent array contain primtiive type QMan deals only with objects so in the result
+ * object you will find the corresponding wrapper types.
+ *
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withPrimitiveArrays() throws Exception
+ {
+ long [] expectedLongResult = {1L,2L,3L,4L};
+ boolean [] expectedBooleanResult = { true,false,false};
+ double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ int [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ short [] expectedShortResult = {(short)227,(short)23,(short)9};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypeArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 6.",6,out.size());
+ assertArrayEquals(expectedLongResult, out.get(long.class.getName()));
+ assertArrayEquals(expectedBooleanResult, out.get(boolean.class.getName()));
+ assertArrayEquals(expectedDoubleResult, out.get(double.class.getName()));
+ assertArrayEquals(expectedFloatResult, out.get(float.class.getName()));
+ assertArrayEquals(expectedIntegerResult, out.get(int.class.getName()));
+ assertArrayEquals(expectedShortResult, out.get(short.class.getName()));
+ }
+
+ /**
+ * Internal method used for array comparison using reflection.
+ *
+ * @param expectedArray the expected array.
+ * @param resultArray the array that must match the expected one.
+ */
+ private void assertArrayEquals(Object expectedArray, Object resultArray)
+ {
+ int expectedArrayLength = Array.getLength(expectedArray);
+ int resultArrayLength = Array.getLength(resultArray);
+
+ assertEquals(expectedArrayLength,resultArrayLength);
+
+ for (int index = 0; index < expectedArrayLength; index++)
+ {
+ Object expected = Array.get(expectedArray, index);
+ Object result = Array.get(resultArray, index);
+
+ assertEquals(expected,result);
+ }
+ }
+
+ private Map<String,ProxyHandler> createInvocationHandlers()
+ {
+ Map<String, ProxyHandler> handlers = new HashMap<String, ProxyHandler>();
+
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction(Names.NAMESPACE_URI+"/"+"voidWithoutArguments");
+ handler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsRequest",
+ Names.PREFIX));
+ handler.setRequestParameterNames(new QName[]{});
+ handler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsResponse",
+ Names.PREFIX));
+ handler.setReturnType(Result.class);
+
+ ProxyHandler exceptionHandler = new ReflectionProxyHandler();
+ exceptionHandler.setAction(Names.NAMESPACE_URI+"/"+"throwsException");
+ exceptionHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionRequest",
+ Names.PREFIX));
+
+ exceptionHandler.setRequestParameterNames(new QName[]{});
+ exceptionHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionResponse",
+ Names.PREFIX));
+
+ exceptionHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithWrapperTypesHandler = new ReflectionProxyHandler();
+ echoWithWrapperTypesHandler.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypes");
+ echoWithWrapperTypesHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesRequest",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithWrapperTypesHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesResponse",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfWrapperTypes = new ReflectionProxyHandler();
+ echoWithArrayOfWrapperTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithArrays");
+ echoWithArrayOfWrapperTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithArrayOfWrapperTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfPrimitiveTypes = new ReflectionProxyHandler();
+ echoWithArrayOfPrimitiveTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypeArrays");
+ echoWithArrayOfPrimitiveTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX)});
+
+ echoWithArrayOfPrimitiveTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithByteArray = new EnhancedReflectionProxyHandler();
+ echoWithByteArray.setAction(Names.NAMESPACE_URI+"/"+"echoWithByteArray");
+ echoWithByteArray.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayRequest",
+ Names.PREFIX));
+
+ echoWithByteArray.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithByteArray.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayResponse",
+ Names.PREFIX));
+
+ echoWithByteArray.setReturnType(Result.class);
+
+ ProxyHandler echoWithUUID = new EnhancedReflectionProxyHandler();
+ echoWithUUID.setAction(Names.NAMESPACE_URI+"/"+"echoWithUUID");
+ echoWithUUID.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDRequest",
+ Names.PREFIX));
+
+ echoWithUUID.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithUUID.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDResponse",
+ Names.PREFIX));
+
+ echoWithUUID.setReturnType(Result.class);
+
+ ProxyHandler echoWithMap = new EnhancedReflectionProxyHandler();
+ echoWithMap.setAction(Names.NAMESPACE_URI+"/"+"echoWithMap");
+ echoWithMap.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapRequest",
+ Names.PREFIX));
+
+ echoWithMap.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithMap.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapResponse",
+ Names.PREFIX));
+
+ echoWithMap.setReturnType(Result.class);
+
+ handlers.put("voidWithoutArguments",handler);
+ handlers.put("echoWithSimpleTypes",echoWithWrapperTypesHandler);
+ handlers.put("echoWithArrays",echoWithArrayOfWrapperTypes);
+ handlers.put("echoWithSimpleTypeArrays", echoWithArrayOfPrimitiveTypes);
+ handlers.put("echoWithByteArray", echoWithByteArray);
+ handlers.put("echoWithUUID", echoWithUUID);
+ handlers.put("echoWithMap", echoWithMap);
+ handlers.put("throwsException",exceptionHandler);
+ return handlers;
+ }
+}
\ No newline at end of file diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java new file mode 100644 index 0000000000..87f8905e01 --- /dev/null +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java @@ -0,0 +1,219 @@ +/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.reflect.Array;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+
+/**
+ * Test case for Set Resource Properties interfaces.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SetResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a WS-Resource exists and is registered.
+ * <br>postcondition : property values are correctly updated on the target WS-Resource..
+ */
+ public void testSetResourcePropertiesOK() throws Exception
+ {
+ Map<String, Object> sampleMap = new HashMap<String, Object>();
+ sampleMap.put("Key1", "BLABALABLABALBAL");
+ sampleMap.put("Key2", 182838484l);
+ sampleMap.put("Key3", -928376362);
+ sampleMap.put("Key4", 23762736276.33D);
+ sampleMap.put("Key4", 2327363.2F);
+
+ Map<String, Object> sampleValues = new HashMap<String, Object>();
+ sampleValues.put(String.class.getName(),"SAMPLE_STRING");
+ sampleValues.put(UUID.class.getName(),UUID.randomUUID());
+ sampleValues.put(Boolean.class.getName(),Boolean.FALSE);
+ sampleValues.put(Map.class.getName(),sampleMap);
+ sampleValues.put(Long.class.getName(),283781273L);
+ sampleValues.put(Integer.class.getName(),12727);
+ sampleValues.put(Short.class.getName(),new Short((short)22));
+ sampleValues.put(Date.class.getName(),new Date());
+
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ boolean atLeastThereIsOneWritableProperty = false;
+
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+
+ if (attributeMetadata.isWritable())
+ {
+ atLeastThereIsOneWritableProperty = true;
+ Object sampleValue = sampleValues.get(attributeMetadata.getType());
+ Object []values = new Object[]{sampleValue};
+
+ Object result = _managementServer.getAttribute(_resourceObjectName, name);
+ if (result == null)
+ {
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ } else
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ }
+
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ sampleValue,
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ sampleValue);
+ }
+ }
+ }
+ assertTrue(
+ "It's not possibile to run successfully this test case if " +
+ "the target WS-Resource has no at least one writable property",
+ atLeastThereIsOneWritableProperty);
+ }
+
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter when the
+ * target property is null.
+ * According to WS-RP specs this operation is not allowed because in this case a SetResourceProperty with an "Insert"
+ * message should be sent in order to initialize the property.
+ *
+ * <br>precondition : a ws resource exists and is registered. The value of the target property is null.
+ * <br>postcondition : a Soap fault is received indicating the failuire.
+ */
+ public void testSetResourcePropertiesKO() throws Exception
+ {
+ Object typePropertyValue = _managementServer.getAttribute(_resourceObjectName, "Type");
+ assertNull(typePropertyValue);
+
+ try
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ fail(
+ "If the property is null on the target ws resource, according " +
+ "to WS-RP specs, an update of its value is not possible.");
+ } catch(SoapFault expected)
+ {
+
+ }
+ }
+
+ /**
+ * Tests the SetResourceProperties (update) interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the SetResourceProperties contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testUpdateResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Tests the SetResourceProperties (insert) interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the SetResourceProperties contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testInsertResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java index 6644b5ae25..07395b3be9 100644 --- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java +++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java @@ -21,36 +21,13 @@ package org.apache.qpid.management.wsdm;
import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
import java.net.ServerSocket;
-import java.net.URI;
-import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.xml.namespace.QName;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import org.apache.muse.core.proxy.ProxyHandler;
-import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.core.serializer.SerializerRegistry;
-import org.apache.muse.util.xml.XmlUtils;
-import org.apache.muse.ws.addressing.EndpointReference;
-import org.apache.muse.ws.addressing.soap.SoapFault;
-import org.apache.muse.ws.resource.remote.WsResourceClient;
-import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
import org.apache.qpid.management.Names;
import org.apache.qpid.management.Protocol;
import org.apache.qpid.management.wsdm.capabilities.Result;
@@ -61,26 +38,14 @@ import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer; import org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer;
import org.mortbay.component.LifeCycle;
import org.mortbay.component.LifeCycle.Listener;
-import org.w3c.dom.Element;
-/**
- * Test case for WS-Resource lifecycle management.
- *
- * @author Andrea Gazzarini
- */
-public class WsDmAdapterTest extends TestCase {
-
- private MBeanServer _managementServer;
- private ObjectName _resourceObjectName;
-
- private WsResourceClient _resourceClient;
- private MBeanInfo _mbeanInfo;
-
- private Map<String, ProxyHandler> _invocationHandlers = createInvocationHandlers();
- final Long retCodeOk = new Long(0);
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class WsDmAdapterTest
+{
- private static ServerThread _server;
-
/**
* Test case wide set up.
* Provides Server startup & shutdown global procedure.
@@ -102,6 +67,7 @@ public class WsDmAdapterTest extends TestCase { }
};
+ private ServerThread _server;
/**
* Builds a new test setup with for the given test.
@@ -153,927 +119,30 @@ public class WsDmAdapterTest extends TestCase { };
/**
- * Set up fixture for this test case.
- *
- * @throws Exception when the test case intialization fails.
- */
- protected void setUp() throws Exception
- {
- _managementServer = ManagementFactory.getPlatformMBeanServer();
-
- ServiceGroupClient serviceGroup = getServiceGroupClient();
- WsResourceClient [] members = serviceGroup.getMembers();
-
- assertEquals(
- "No resource has been yet created so how is " +
- "it possible that service group children list is not empty?",
- 0,
- members.length);
-
- _managementServer.invoke(
- Names.QPID_EMULATOR_OBJECT_NAME,
- "createQueue", new Object[]{_resourceObjectName = createResourceName()},
- new String[]{ObjectName.class.getName()});
-
- members = serviceGroup.getMembers();
- assertEquals(
- "One resource has just been created so " +
- "I expect to find it on service group children list...",
- 1,
- members.length);
-
- _resourceClient = members[0];
- _mbeanInfo = _managementServer.getMBeanInfo(_resourceObjectName);
- }
-
- /**
- * Shutdown procedure for this test case.
- *
- * @throws Exception when either the server or some resource fails to shutdown.
- */
- @Override
- protected void tearDown() throws Exception
- {
- ServiceGroupClient serviceGroup = getServiceGroupClient();
- WsResourceClient [] members = serviceGroup.getMembers();
-
- _managementServer.invoke(
- Names.QPID_EMULATOR_OBJECT_NAME,
- "unregister",
- new Object[]{_resourceObjectName},
- new String[]{ObjectName.class.getName()});
-
- members = serviceGroup.getMembers();
-
- assertEquals(
- "No resource has been yet created so how is it possible that service group children list is not empty?",
- 0,
- members.length);
- }
-
- /**
- * Test the WS-RP GetResourceProperty interface of the WS-DM adapter.
- *
- * <br>precondition : a ws resource exists and is registered.
- * <br>postcondition : property values coming from WS-DM resource are the same of the JMX interface.
- */
- public void testGetResourcePropertiesOK() throws Exception
- {
- MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
- for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
- {
- String name = attributeMetadata.getName();
- Object propertyValues = _resourceClient.getPropertyAsObject(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- Class.forName(attributeMetadata.getType()));
-
- int length = Array.getLength(propertyValues);
- if (length != 0)
- {
- Object propertyValue = Array.get(propertyValues, 0);
-
- assertEquals(
- "Comparison failed for property "+name,
- _managementServer.getAttribute(_resourceObjectName,name),
- propertyValue);
- } else {
- assertNull(
- String.format(
- "\"%s\" property value shouldn't be null. Its value is %s",
- name,
- _managementServer.getAttribute(_resourceObjectName,name)),
- _managementServer.getAttribute(_resourceObjectName,name));
- }
- }
- }
-
- /**
- * Test the WS-RP SetResourceProperty interface of the WS-DM adapter.
+ * Gets the test suite composition.
*
- * <br>precondition : a WS-Resource exists and is registered.
- * <br>postcondition : property values are correctly updated on the target WS-Resource..
+ * @return the test suite composition.
*/
- public void testSetResourcePropertiesOK() throws Exception
+ public static Test suite()
{
- Map<String, Object> sampleMap = new HashMap<String, Object>();
- sampleMap.put("Key1", "BLABALABLABALBAL");
- sampleMap.put("Key2", 182838484l);
- sampleMap.put("Key3", -928376362);
- sampleMap.put("Key4", 23762736276.33D);
- sampleMap.put("Key4", 2327363.2F);
-
- Map<String, Object> sampleValues = new HashMap<String, Object>();
- sampleValues.put(String.class.getName(),"SAMPLE_STRING");
- sampleValues.put(UUID.class.getName(),UUID.randomUUID());
- sampleValues.put(Boolean.class.getName(),Boolean.FALSE);
- sampleValues.put(Map.class.getName(),sampleMap);
- sampleValues.put(Long.class.getName(),283781273L);
- sampleValues.put(Integer.class.getName(),12727);
- sampleValues.put(Short.class.getName(),new Short((short)22));
- sampleValues.put(Date.class.getName(),new Date());
-
- MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
- boolean atLeastThereIsOneWritableProperty = false;
-
- for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
- {
- String name = attributeMetadata.getName();
-
- if (attributeMetadata.isWritable())
- {
- atLeastThereIsOneWritableProperty = true;
- Object sampleValue = sampleValues.get(attributeMetadata.getType());
- Object []values = new Object[]{sampleValue};
-
- Object result = _managementServer.getAttribute(_resourceObjectName, name);
- if (result == null)
- {
- _resourceClient.insertResourceProperty(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- values);
- } else
- {
- _resourceClient.updateResourceProperty(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- values);
- }
-
- Object propertyValues = _resourceClient.getPropertyAsObject(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- Class.forName(attributeMetadata.getType()));
- int length = Array.getLength(propertyValues);
- if (length != 0)
- {
- Object propertyValue = Array.get(propertyValues, 0);
-
- assertEquals(
- "Comparison failed for property "+name,
- sampleValue,
- propertyValue);
- } else {
- assertNull(
- String.format(
- "\"%s\" property value shouldn't be null. Its value is %s",
- name,
- _managementServer.getAttribute(_resourceObjectName,name)),
- sampleValue);
- }
- }
- }
- assertTrue(
- "It's not possibile to run successfully this test case if " +
- "the target WS-Resource has no at least one writable property",
- atLeastThereIsOneWritableProperty);
- }
-
- /**
- * Test the WS-RP SetResourceProperty interface of the WS-DM adapter when the
- * target property is null.
- * According to WS-RP specs this operation is not allowed because in this case a SetResourceProperty with an "Insert"
- * message should be sent in order to initialize the property.
- *
- * <br>precondition : a ws resource exists and is registered. The value of the target property is null.
- * <br>postcondition : a Soap fault is received indicating the failuire.
- */
- public void testSetResourcePropertiesKO() throws Exception
- {
- Object typePropertyValue = _managementServer.getAttribute(_resourceObjectName, "Type");
- assertNull(typePropertyValue);
-
- try
- {
- _resourceClient.updateResourceProperty(
- new QName(
- Names.NAMESPACE_URI,
- "Type",
- Names.PREFIX),
- new Object[]{"sampleValue"});
- fail(
- "If the property is null on the target ws resource, according " +
- "to WS-RP specs, an update of its value is not possible.");
- } catch(SoapFault expected)
- {
-
- }
- }
-
- /**
- * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
- *
- * <br>precondition : a ws resource exists and is registered.
- * <br>postcondition : A read / write property is correctly set according to WSRP interface.
- */
- public void testGetAndPutResourcePropertyDocumentOK() throws Exception
- {
- String expectedMgmtPubIntervalValue = "4321";
- String propertyName = "MgmtPubInterval";
-
- Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
- Element [] properties = XmlUtils.getAllElements(propertiesDocument);
-
- for (Element element : properties)
- {
- if (propertyName.equals(element.getLocalName())) {
- element.setTextContent(expectedMgmtPubIntervalValue);
- } else {
- propertiesDocument.removeChild(element);
- }
- }
-
- _resourceClient.putResourcePropertyDocument(propertiesDocument);
-
- Element newProperties = _resourceClient.getResourcePropertyDocument();
-
- Element mgmtPubInterval = XmlUtils.getElement(
- newProperties, new QName(
- Names.NAMESPACE_URI,
- propertyName,
- Names.PREFIX));
-
- assertEquals(expectedMgmtPubIntervalValue,mgmtPubInterval.getTextContent());
- }
-
- /**
- * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
- * Specifically it tries to update the value of a read-only property.
- *
- * <br>precondition : a ws resource exists, it is registered and has at least one read-only property.
- * <br>postcondition : An exception is thrown indicating the failure.
- */
- public void testGetAndPutResourcePropertyDocumentKO_WithReadOnlyProperty() throws Exception
- {
- String propertyName = "Name";
-
- Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
- Element [] properties = XmlUtils.getAllElements(propertiesDocument);
-
- for (Element element : properties)
- {
- if (propertyName.equals(element.getLocalName())) {
- element.setTextContent("ThisIsTheNewValueOfNameProperty");
- } else {
- propertiesDocument.removeChild(element);
- }
- }
-
- try
- {
- _resourceClient.putResourcePropertyDocument(propertiesDocument);
- fail("It's not possible to update the value of a read-only property.");
- } catch (SoapFault expected)
- {
-
- }
- }
-
- /**
- * Test the WS-RP GetResourceProperties interface of the WS-DM adapter.
- *
- * <br>precondition : a ws resource exists and is registered.
- * <br>postcondition : Properties are correctly returned according to WSRP interface and they (their value)
- * are matching with corresponding MBean properties.
- */
- public void testGetMultipleResourcePropertiesOK() throws Exception
- {
- MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
- QName[] names = new QName[attributesMetadata.length];
-
- int index = 0;
- for (MBeanAttributeInfo attributeMetadata : _mbeanInfo.getAttributes())
- {
- QName qname = new QName(Names.NAMESPACE_URI,attributeMetadata.getName(),Names.PREFIX);
- names[index++] = qname;
- }
-
- Element[] properties =_resourceClient.getMultipleResourceProperties(names);
- for (Element element : properties)
- {
- String name = element.getLocalName();
- Object value = _managementServer.getAttribute(_resourceObjectName, name);
- if ("Name".equals(name))
- {
- assertEquals(
- value,
- element.getTextContent());
- } else if ("Durable".equals(name))
- {
- assertEquals(
- value,
- Boolean.valueOf(element.getTextContent()));
- } else if ("ExpireTime".equals(name))
- {
- assertEquals(
- value,
- new Date(Long.valueOf(element.getTextContent())));
- } else if ("MsgTotalEnqueues".equals(name))
- {
- assertEquals(
- value,
- Long.valueOf(element.getTextContent()));
- } else if ("ConsumerCount".equals(name))
- {
- assertEquals(
- value,
- Integer.valueOf(element.getTextContent()));
- }else if ("VhostRef".equals(name))
- {
- assertEquals(
- value,
- UUID.fromString(element.getTextContent()));
- }
- }
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of simple types between requestor and service provider.
- * With simple types we mean :
- *
- * <ul>
- * <li>java.lang.Long / long (xsd:long)
- * <li>java.lang.Integer / int (xsd:int / xsd:integer)
- * <li>java.lang.Double/ double (xsd:double)
- * <li>java.lang.Float / float (xsd:float)
- * <li>java.lang.Short / short (xsd:short)
- * <li>java.lang.Boolean / boolean (xsd:boolean)
- * <li>java.lang.String (xsd:string)
- * <li>java.net.URI (xsd:anyURI)
- * <li>java.util.Date(xsd:dateTime)
- * </ul>
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withSimpleTypes() throws Exception
- {
- Long expectedLongResult = new Long(1373);
- Boolean expectedBooleanResult = Boolean.TRUE;
- Double expectedDoubleResult = new Double(12763.44);
- Float expectedFloatResult = new Float(2727.233f);
- Integer expectedIntegerResult = new Integer(28292);
- Short expectedShortResult = new Short((short)227);
- String expectedStringResult = "expectedStringResult";
- URI expectedUriResult = URI.create("http://qpid.apache.org/");
- Date expectedDateResult = new Date();
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithSimpleTypes"),
- new Object[]{
- expectedLongResult,
- expectedBooleanResult,
- expectedDoubleResult,
- expectedFloatResult,
- expectedIntegerResult,
- expectedShortResult,
- expectedStringResult,
- expectedUriResult,
- expectedDateResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 9.",9,out.size());
- assertTrue("Long output parameter not found on result object.",out.containsValue(expectedLongResult));
- assertTrue("Boolean output parameter not found on result object.",out.containsValue(expectedBooleanResult));
- assertTrue("Double output parameter not found on result object.",out.containsValue(expectedDoubleResult));
- assertTrue("Float output parameter not found on result object.",out.containsValue(expectedFloatResult));
- assertTrue("Integer output parameter not found on result object.",out.containsValue(expectedIntegerResult));
- assertTrue("Short output parameter not found on result object.",out.containsValue(expectedShortResult));
- assertTrue("String output parameter not found on result object.",out.containsValue(expectedStringResult));
- assertTrue("URI output parameter not found on result object.",out.containsValue(expectedUriResult));
- assertTrue("Date output parameter not found on result object.",out.containsValue(expectedDateResult));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of arrays between requestor and service provider.
- * For this test exchanged arrays contain :
- *
- * <ul>
- * <li>java.lang.Long (xsd:long)
- * <li>java.lang.Integer (xsd:int / xsd:integer)
- * <li>java.lang.Double (xsd:double)
- * <li>java.lang.Float (xsd:float)
- * <li>java.lang.Short (xsd:short)
- * <li>java.lang.Boolean (xsd:boolean)
- * <li>java.lang.String (xsd:string)
- * <li>java.net.URI (xsd:anyURI)
- * <li>java.util.Date(xsd:dateTime)
- * </ul>
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withWrapperArrays() throws Exception
- {
- Long [] expectedLongResult = {new Long(2),new Long(1),new Long(3),new Long(4)};
- Boolean [] expectedBooleanResult = { Boolean.TRUE,Boolean.FALSE,Boolean.FALSE};
- Double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
- Float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
- Integer [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
- Short [] expectedShortResult = {(short)227,(short)23,(short)9};
- String [] expectedStringResult = {"s1","s2","s333","s4"};
- URI [] expectedUriResult = {
- URI.create("http://qpid.apache.org/"),
- URI.create("http://www.apache.org"),
- URI.create("http://projects.apache.org")};
-
- Date [] expectedDateResult = {
- new Date(),
- new Date(38211897),
- new Date(903820382)};
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithArrays"),
- new Object[]{
- expectedLongResult,
- expectedBooleanResult,
- expectedDoubleResult,
- expectedFloatResult,
- expectedIntegerResult,
- expectedShortResult,
- expectedStringResult,
- expectedUriResult,
- expectedDateResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 9.",9,out.size());
- assertTrue("Long array doesn't match.",Arrays.equals(expectedLongResult, (Long[])out.get(Long.class.getName())));
- assertTrue("Boolean array doesn't match.",Arrays.equals(expectedBooleanResult, (Boolean[])out.get(Boolean.class.getName())));
- assertTrue("Double array doesn't match.",Arrays.equals(expectedDoubleResult, (Double[])out.get(Double.class.getName())));
- assertTrue("Float array doesn't match.",Arrays.equals(expectedFloatResult, (Float[])out.get(Float.class.getName())));
- assertTrue("Integer array doesn't match.", Arrays.equals(expectedIntegerResult, (Integer[])out.get(Integer.class.getName())));
- assertTrue("Short array doesn't match.",Arrays.equals(expectedShortResult, (Short[])out.get(Short.class.getName())));
- assertTrue("String array doesn't match.",Arrays.equals(expectedStringResult, (String[])out.get(String.class.getName())));
- assertTrue("URI array doesn't match.",Arrays.equals(expectedUriResult, (URI[])out.get(URI.class.getName())));
- assertTrue("Date array doesn't match.",Arrays.equals(expectedDateResult, (Date[])out.get(Date.class.getName())));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of primitive type arrays between requestor and service provider.
- * NOte that even the sent array contain primtiive type QMan deals only with objects so in the result
- * object you will find the corresponding wrapper types.
- *
- * For this test exchanged arrays contain :
- *
- * <ul>
- * <li>java.lang.Long / long (xsd:long)
- * <li>java.lang.Integer / int (xsd:int / xsd:integer)
- * <li>java.lang.Double/ double (xsd:double)
- * <li>java.lang.Float / float (xsd:float)
- * <li>java.lang.Short / short (xsd:short)
- * <li>java.lang.Boolean / boolean (xsd:boolean)
- * </ul>
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withPrimitiveArrays() throws Exception
- {
- long [] expectedLongResult = {1L,2L,3L,4L};
- boolean [] expectedBooleanResult = { true,false,false};
- double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
- float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
- int [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
- short [] expectedShortResult = {(short)227,(short)23,(short)9};
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithSimpleTypeArrays"),
- new Object[]{
- expectedLongResult,
- expectedBooleanResult,
- expectedDoubleResult,
- expectedFloatResult,
- expectedIntegerResult,
- expectedShortResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 6.",6,out.size());
- assertArrayEquals(expectedLongResult, out.get(long.class.getName()));
- assertArrayEquals(expectedBooleanResult, out.get(boolean.class.getName()));
- assertArrayEquals(expectedDoubleResult, out.get(double.class.getName()));
- assertArrayEquals(expectedFloatResult, out.get(float.class.getName()));
- assertArrayEquals(expectedIntegerResult, out.get(int.class.getName()));
- assertArrayEquals(expectedShortResult, out.get(short.class.getName()));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of a byte type array between requestor and service provider.
- *
- * <br>precondition : a WS-Resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and byte array are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withByteArray() throws Exception
- {
- byte [] expectedByteResult = {1,3,4,2,2,44,22,3,3,55,66};
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithByteArray"),
- new Object[]{expectedByteResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
-
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 1.",1,out.size());
- assertArrayEquals(expectedByteResult, out.get(byte[].class.getName()));
- }
-
- /**
- * Test a simple operation invocation on a WS-Resource.
- * This method tests a simple operation without any input and output parameters.
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully an no exception is thrown.
- */
- @SuppressWarnings("unchecked")
- public void testSimpleOperationInvocationOK() throws Exception
- {
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("voidWithoutArguments"),
- null);
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- assertEquals(
- "Something was wrong...expected return code is "+retCodeOk,
- retCodeOk,
- getStatusCode.invoke(result));
- }
-
- /**
- * Test a the invocation on a WS-Resource with a method that throws an exception..
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : an exception is thrown by the requested method.
- */
- @SuppressWarnings("unchecked")
- public void testInvocationException_OK() throws Exception
- {
- try
- {
- _resourceClient.invoke(
- _invocationHandlers.get("throwsException"),
- null);
- fail("The requested operation has thrown an exception so a Soap Fault is expected...");
- } catch(SoapFault expected)
- {
- }
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of UUID type between requestor and service provider.
- *
- * <br>precondition : a WS-Resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withUUID() throws Exception
- {
- UUID expectedUuid = UUID.randomUUID();
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithUUID"),
- new Object[]{expectedUuid});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
-
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 1.",1,out.size());
- assertEquals(expectedUuid, out.get("uuid"));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of Map type between requestor and service provider.
- * For this test exchanged arrays contain :
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withMap() throws Exception
- {
- Map<String,Object> expectedMap = new HashMap<String, Object>();
- expectedMap.put("p1", new Long(1));
- expectedMap.put("p2", Boolean.TRUE);
- expectedMap.put("p3", 1234d);
- expectedMap.put("p4", 11.2f);
- expectedMap.put("p5", 1272);
- expectedMap.put("p6", (short)12);
- expectedMap.put("p7", "aString");
- expectedMap.put("p8", "http://qpid.apache.org");
- expectedMap.put("p9", new Date(12383137128L));
- expectedMap.put("p10", new byte[]{1,2,2,3,3,4});
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithMap"),
- new Object[]{expectedMap});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
-
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) ((Map<String, Object>) getOutputParameters.invoke(result)).get("map");
-
- assertEquals("Output parameters must be 10.",10,out.size());
- assertEquals(expectedMap.get("p1"),out.get("p1"));
- assertEquals(expectedMap.get("p2"),out.get("p2"));
- assertEquals(expectedMap.get("p3"),out.get("p3"));
- assertEquals(expectedMap.get("p4"),out.get("p4"));
- assertEquals(expectedMap.get("p5"),out.get("p5"));
- assertEquals(expectedMap.get("p6"),out.get("p6"));
- assertEquals(expectedMap.get("p7"),out.get("p7"));
- assertEquals(expectedMap.get("p8"),out.get("p8"));
- assertEquals(expectedMap.get("p9"),out.get("p9"));
- assertTrue( Arrays.equals((byte[])expectedMap.get("p10"),(byte[])out.get("p10")));
- }
-
- /**
- * Main entry point for running this test case.
- *
- * @return the decorated test case.
- */
- public static Test suite() {
- TestSuite suite = new TestSuite("Test Suite for WS-DM Adapter");
- suite.addTestSuite(WsDmAdapterTest.class);
+ TestSuite suite = new TestSuite("Test suite for QMan WS-DM.");
+ suite.addTestSuite(MetadataExchangeInterfaceTestCase.class);
+ suite.addTestSuite(OperationInvocationInterfaceTestCase.class);
+ suite.addTestSuite(GetResourcePropertyDocumentTestCase.class);
+ suite.addTestSuite(SetResourcePropertiesTestCase.class);
+ suite.addTestSuite(GetMultipleResourcePropertiesTestCase.class);
+ suite.addTestSuite(GetResourcePropertiesTestCase.class);
return new WsDmAdapterTestSetup(suite);
}
/**
- * Creates a service group client reference.
- *
- * @return a service group client reference.
- */
- private ServiceGroupClient getServiceGroupClient()
- {
- URI address = URI.create(
- Protocol.DEFAULT_ENDPOINT_URI.replaceFirst("8080",System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
- return new ServiceGroupClient(new EndpointReference(address));
- }
-
- /**
- * In order to test the behaviour of the WS-DM adapter, at
- * least one resource must be created. This is the method that
- * returns the name (ObjectName on JMX side, Resource-ID on WSDM side)
- * of that resource
- *
- * @return the name of the MBean instance that will be created.
- * @throws Exception when the name if malformed. Practically never.
- */
- private ObjectName createResourceName() throws Exception
- {
- return new ObjectName(
- "Q-MAN:objectId="+UUID.randomUUID()+
- ", brokerID="+UUID.randomUUID()+
- ",class=queue"+
- ",package=org.apache.qpid"+
- ",name="+System.currentTimeMillis());
- }
-
- private Map<String,ProxyHandler> createInvocationHandlers()
- {
- Map<String, ProxyHandler> handlers = new HashMap<String, ProxyHandler>();
-
- ProxyHandler handler = new ReflectionProxyHandler();
- handler.setAction(Names.NAMESPACE_URI+"/"+"voidWithoutArguments");
- handler.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "voidWithoutArgumentsRequest",
- Names.PREFIX));
- handler.setRequestParameterNames(new QName[]{});
- handler.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "voidWithoutArgumentsResponse",
- Names.PREFIX));
- handler.setReturnType(Result.class);
-
- ProxyHandler exceptionHandler = new ReflectionProxyHandler();
- exceptionHandler.setAction(Names.NAMESPACE_URI+"/"+"throwsException");
- exceptionHandler.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "throwsExceptionRequest",
- Names.PREFIX));
-
- exceptionHandler.setRequestParameterNames(new QName[]{});
- exceptionHandler.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "throwsExceptionResponse",
- Names.PREFIX));
-
- exceptionHandler.setReturnType(Result.class);
-
- ProxyHandler echoWithWrapperTypesHandler = new ReflectionProxyHandler();
- echoWithWrapperTypesHandler.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypes");
- echoWithWrapperTypesHandler.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypesRequest",
- Names.PREFIX));
-
- echoWithWrapperTypesHandler.setRequestParameterNames(new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
- });
-
- echoWithWrapperTypesHandler.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypesResponse",
- Names.PREFIX));
-
- echoWithWrapperTypesHandler.setReturnType(Result.class);
-
- ProxyHandler echoWithArrayOfWrapperTypes = new ReflectionProxyHandler();
- echoWithArrayOfWrapperTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithArrays");
- echoWithArrayOfWrapperTypes.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithArraysRequest",
- Names.PREFIX));
-
- echoWithArrayOfWrapperTypes.setRequestParameterNames(new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
- });
-
- echoWithArrayOfWrapperTypes.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithArraysResponse",
- Names.PREFIX));
-
- echoWithArrayOfWrapperTypes.setReturnType(Result.class);
-
- ProxyHandler echoWithArrayOfPrimitiveTypes = new ReflectionProxyHandler();
- echoWithArrayOfPrimitiveTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypeArrays");
- echoWithArrayOfPrimitiveTypes.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypeArraysRequest",
- Names.PREFIX));
-
- echoWithArrayOfPrimitiveTypes.setRequestParameterNames(new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX)});
-
- echoWithArrayOfPrimitiveTypes.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypeArraysResponse",
- Names.PREFIX));
-
- echoWithArrayOfPrimitiveTypes.setReturnType(Result.class);
-
- ProxyHandler echoWithByteArray = new EnhancedReflectionProxyHandler();
- echoWithByteArray.setAction(Names.NAMESPACE_URI+"/"+"echoWithByteArray");
- echoWithByteArray.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithByteArrayRequest",
- Names.PREFIX));
-
- echoWithByteArray.setRequestParameterNames(
- new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
-
- echoWithByteArray.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithByteArrayResponse",
- Names.PREFIX));
-
- echoWithByteArray.setReturnType(Result.class);
-
- ProxyHandler echoWithUUID = new EnhancedReflectionProxyHandler();
- echoWithUUID.setAction(Names.NAMESPACE_URI+"/"+"echoWithUUID");
- echoWithUUID.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithUUIDRequest",
- Names.PREFIX));
-
- echoWithUUID.setRequestParameterNames(
- new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
-
- echoWithUUID.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithUUIDResponse",
- Names.PREFIX));
-
- echoWithUUID.setReturnType(Result.class);
-
- ProxyHandler echoWithMap = new EnhancedReflectionProxyHandler();
- echoWithMap.setAction(Names.NAMESPACE_URI+"/"+"echoWithMap");
- echoWithMap.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithMapRequest",
- Names.PREFIX));
-
- echoWithMap.setRequestParameterNames(
- new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
-
- echoWithMap.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithMapResponse",
- Names.PREFIX));
-
- echoWithMap.setReturnType(Result.class);
-
- handlers.put("voidWithoutArguments",handler);
- handlers.put("echoWithSimpleTypes",echoWithWrapperTypesHandler);
- handlers.put("echoWithArrays",echoWithArrayOfWrapperTypes);
- handlers.put("echoWithSimpleTypeArrays", echoWithArrayOfPrimitiveTypes);
- handlers.put("echoWithByteArray", echoWithByteArray);
- handlers.put("echoWithUUID", echoWithUUID);
- handlers.put("echoWithMap", echoWithMap);
- handlers.put("throwsException",exceptionHandler);
- return handlers;
- }
-
- /**
- * Internal method used for array comparison using reflection.
+ * Finds a free port that will be used to run the embedded
+ * web server.
*
- * @param expectedArray the expected array.
- * @param resultArray the array that must match the expected one.
+ * @return a free port that will be used to run the
+ * embedded web server.
*/
- private void assertArrayEquals(Object expectedArray, Object resultArray)
- {
- int expectedArrayLength = Array.getLength(expectedArray);
- int resultArrayLength = Array.getLength(resultArray);
-
- assertEquals(expectedArrayLength,resultArrayLength);
-
- for (int index = 0; index < expectedArrayLength; index++)
- {
- Object expected = Array.get(expectedArray, index);
- Object result = Array.get(resultArray, index);
-
- assertEquals(expected,result);
- }
- }
-
- public static int getFreePort() throws IOException {
+ private static int getFreePort() throws IOException {
ServerSocket server = null;
try
{
diff --git a/qpid/java/management/client/web.xml b/qpid/java/management/client/web.xml index 0f8992d1bf..29eb64a268 100644 --- a/qpid/java/management/client/web.xml +++ b/qpid/java/management/client/web.xml @@ -8,11 +8,7 @@ Java Management Extensions (JMX) and / or WS-DM. </description> <display-name>QManEE</display-name> - <context-param> - <param-name>tapestry.app-package</param-name> - <param-value>org.apache.qpid.management.web.console</param-value> - </context-param> - <listener> + <listener> <description> Provides lifecycle management for QMan module. </description> @@ -25,52 +21,52 @@ <servlet-class>org.apache.qpid.management.servlet.WSDMAdapter</servlet-class> <load-on-startup>2</load-on-startup> </servlet> - <servlet>
- <display-name>View Console (System Overview) Action</display-name>
- <servlet-name>ViewConsole</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.ConsoleAction</servlet-class>
- <load-on-startup>5</load-on-startup>
- </servlet>
- <servlet>
- <display-name>View Resources</display-name>
- <servlet-name>ResourceManagement</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.ResourcesManagementAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>JMX Perspective</display-name>
- <servlet-name>JmxPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.JmxPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM Properties Perspective</display-name>
- <servlet-name>WsdmPropertiesPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmPropertiesPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM Operations Perspective</display-name>
- <servlet-name>WsdmOperationsPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmOperationsPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM WSDL Perspective</display-name>
- <servlet-name>WsdmWsdlPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmWsdlPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM RMD Perspective</display-name>
- <servlet-name>WsdmRmdPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmRmdPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>Logging Configurator</display-name>
- <servlet-name>LoggingConfiguration</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.LoggingConfigurationAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>Brokers Management</display-name>
- <servlet-name>BrokersManagement</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.BrokersManagementAction</servlet-class>
- </servlet>
+ <servlet> + <display-name>View Console (System Overview) Action</display-name> + <servlet-name>ViewConsole</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.ConsoleAction</servlet-class> + <load-on-startup>5</load-on-startup> + </servlet> + <servlet> + <display-name>View Resources</display-name> + <servlet-name>ResourceManagement</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.ResourcesManagementAction</servlet-class> + </servlet> + <servlet> + <display-name>JMX Perspective</display-name> + <servlet-name>JmxPerspective</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.JmxPerspectiveAction</servlet-class> + </servlet> + <servlet> + <display-name>WSDM Properties Perspective</display-name> + <servlet-name>WsdmPropertiesPerspective</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.WsdmPropertiesPerspectiveAction</servlet-class> + </servlet> + <servlet> + <display-name>WSDM Operations Perspective</display-name> + <servlet-name>WsdmOperationsPerspective</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.WsdmOperationsPerspectiveAction</servlet-class> + </servlet> + <servlet> + <display-name>WSDM WSDL Perspective</display-name> + <servlet-name>WsdmWsdlPerspective</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.WsdmWsdlPerspectiveAction</servlet-class> + </servlet> + <servlet> + <display-name>WSDM RMD Perspective</display-name> + <servlet-name>WsdmRmdPerspective</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.WsdmRmdPerspectiveAction</servlet-class> + </servlet> + <servlet> + <display-name>Logging Configurator</display-name> + <servlet-name>LoggingConfiguration</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.LoggingConfigurationAction</servlet-class> + </servlet> + <servlet> + <display-name>Brokers Management</display-name> + <servlet-name>BrokersManagement</servlet-name> + <servlet-class>org.apache.qpid.management.web.action.BrokersManagementAction</servlet-class> + </servlet> <servlet> <description> Connects QMAn to one or more brokers depending from what is @@ -81,43 +77,43 @@ <servlet-name>ConnectQManToBroker</servlet-name> <servlet-class>org.apache.qpid.management.servlet.ConnectQManToBroker</servlet-class> <load-on-startup>1</load-on-startup> - </servlet>
- <servlet-mapping>
- <servlet-name>ResourceManagement</servlet-name>
- <url-pattern>/resources_management</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmWsdlPerspective</servlet-name>
- <url-pattern>/wsdm_wsdl_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmRmdPerspective</servlet-name>
- <url-pattern>/wsdm_rmd_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmOperationsPerspective</servlet-name>
- <url-pattern>/wsdm_operations_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmPropertiesPerspective</servlet-name>
- <url-pattern>/wsdm_properties_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>BrokersManagement</servlet-name>
- <url-pattern>/brokers_management</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>JmxPerspective</servlet-name>
- <url-pattern>/jmx_perspective</url-pattern>
+ </servlet> + <servlet-mapping> + <servlet-name>ResourceManagement</servlet-name> + <url-pattern>/resources_management</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>WsdmWsdlPerspective</servlet-name> + <url-pattern>/wsdm_wsdl_perspective</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>WsdmRmdPerspective</servlet-name> + <url-pattern>/wsdm_rmd_perspective</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>WsdmOperationsPerspective</servlet-name> + <url-pattern>/wsdm_operations_perspective</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>WsdmPropertiesPerspective</servlet-name> + <url-pattern>/wsdm_properties_perspective</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>BrokersManagement</servlet-name> + <url-pattern>/brokers_management</url-pattern> </servlet-mapping> - <servlet-mapping>
- <servlet-name>LoggingConfiguration</servlet-name>
- <url-pattern>/logging_configuration</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>ViewConsole</servlet-name>
- <url-pattern>/console</url-pattern>
- </servlet-mapping>
+ <servlet-mapping> + <servlet-name>JmxPerspective</servlet-name> + <url-pattern>/jmx_perspective</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>LoggingConfiguration</servlet-name> + <url-pattern>/logging_configuration</url-pattern> + </servlet-mapping> + <servlet-mapping> + <servlet-name>ViewConsole</servlet-name> + <url-pattern>/console</url-pattern> + </servlet-mapping> <servlet-mapping> <servlet-name>ConnectQManToBroker</servlet-name> <url-pattern>/test/*</url-pattern> diff --git a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF index 32d1b7a1b2..9b5a240bb6 100644 --- a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF +++ b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF @@ -10,8 +10,8 @@ Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, org.eclipse.ui.forms, - jmxremote.sasl;resolution:=optional, - qpid-management-common + qpid-management-common, + org.apache.commons.codec;bundle-version="1.3.0" Eclipse-LazyStart: true Export-Package: org.apache.qpid.management.ui, org.apache.qpid.management.ui.actions, diff --git a/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties b/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties new file mode 100644 index 0000000000..f1c35c82e8 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties @@ -0,0 +1,36 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# + +release.name=${module.namever}-linux-gtk-x86_64 + +release.subdir=${module.release.base}/${release.name} + +release.tar.gz=${module.release.base}/${release.name}.tar.gz + +qpidmc.ini=src/main/resources/linux-gtk-x86_64/qpidmc.ini + +qpidmc.executable=src/main/resources/linux-gtk-x86_64/qpidmc + +qpidmc.companion.library=src/main/resources/linux-gtk-x86_64/libcairo-swt.so + +rcp.libs=${management-eclipse-plugin-linux-gtk-x86_64.libs} + +rcp.configuration.dir=src/main/resources/linux-gtk-x86_64/Configuration diff --git a/qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties b/qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties new file mode 100644 index 0000000000..7d5b613e06 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties @@ -0,0 +1,39 @@ +# +# +# 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. +# +# + +release.name=${module.namever}-solaris-gtk-sparc + +release.subdir=${module.release.base}/${release.name} + +release.tar.gz=${module.release.base}/${release.name}.tar.gz + +qpidmc.ini=src/main/resources/solaris-gtk-sparc/qpidmc.ini + +qpidmc.solaris.xpm.files=src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm \ + src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm \ + src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm \ + src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm + +qpidmc.executable=src/main/resources/solaris-gtk-sparc/qpidmc + +rcp.libs=${management-eclipse-plugin-solaris-gtk-sparc.libs} + +rcp.configuration.dir=src/main/resources/solaris-gtk-sparc/Configuration diff --git a/qpid/java/management/eclipse-plugin/build-release.xml b/qpid/java/management/eclipse-plugin/build-release.xml index b396974c9a..3cb1af194f 100644 --- a/qpid/java/management/eclipse-plugin/build-release.xml +++ b/qpid/java/management/eclipse-plugin/build-release.xml @@ -44,6 +44,9 @@ For linux libcairo-swt.so file: qpidmc.companion.library + + For solaris .xpm files: + qpidmc.solaris.xpm.files --> </condition> @@ -86,15 +89,22 @@ <fileset file="${qpidmc.companion.library}"/> </copy> </target> + + <target name="release-bin-executable-solaris-xpm-files" if="qpidmc.solaris.xpm.files"> + <!-- Copy the solaris xpm files --> + <copy todir="${release.subdir}" flatten="true" failonerror="true"> + <fileset dir="${basedir}" includes="${qpidmc.solaris.xpm.files}"/> + </copy> + </target> <target name="release-bin-rcp-deps" description="copy eclipse-rcp dependencies into module release" - depends="release-bin-executable-companion-library"> + depends="release-bin-executable-companion-library, release-bin-executable-solaris-xpm-files"> <!-- Copy the rcp executable file --> <copy todir="${release.subdir}" flatten="true" failonerror="true"> <fileset file="${qpidmc.executable}"/> </copy> - <chmod dir="${release.subdir}" perm="u+rx" includes="**/*"/> + <chmod dir="${release.subdir}" perm="u+rx" includes="qpidmc*"/> <!-- Copy remaining startup & license files --> <copy todir="${release.subdir}" flatten="true" failonerror="true"> diff --git a/qpid/java/management/eclipse-plugin/build.xml b/qpid/java/management/eclipse-plugin/build.xml index 4dd279f721..8513c6487d 100644 --- a/qpid/java/management/eclipse-plugin/build.xml +++ b/qpid/java/management/eclipse-plugin/build.xml @@ -70,6 +70,19 @@ <property file="build-release-linux-gtk-x86.properties"/> <property file="build-release-common.properties"/> </ant> + + <!-- linux gtk x86_64 --> + <ant antfile="build-release.xml"> + <property file="build-release-linux-gtk-x86_64.properties"/> + <property file="build-release-common.properties"/> + </ant> + + <!-- solaris gtk sparc --> + <ant antfile="build-release.xml"> + <property file="build-release-solaris-gtk-sparc.properties"/> + <property file="build-release-common.properties"/> + </ant> + <!-- mac os x --> <ant antfile="build-release-macosx.xml"> <property file="build-release-macosx.properties"/> diff --git a/qpid/java/management/eclipse-plugin/icons/splash.bmp b/qpid/java/management/eclipse-plugin/icons/splash.bmp Binary files differindex b528a508c5..cf3b93d523 100644 --- a/qpid/java/management/eclipse-plugin/icons/splash.bmp +++ b/qpid/java/management/eclipse-plugin/icons/splash.bmp diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java index 5e05375e28..5a6b3f8856 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java @@ -28,12 +28,13 @@ package org.apache.qpid.management.ui; public class Constants { public final static String APPLICATION_NAME = "Qpid Management Console"; + public static final String DEFAULT_DOMAIN = "org.apache.qpid"; public final static String ACTION_REMOVE_MBEANNODE = "Remove from list"; public final static String VALUE = "value"; public final static String TYPE = "type"; + public final static String VERSION = "version"; public final static String NODE_TYPE_SERVER = "server"; - public final static String NODE_TYPE_DOMAIN = "domain"; public final static String NODE_TYPE_MBEANTYPE = "mbeantype"; // currently used only for virtual host instances, but will work as general also public final static String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance"; @@ -80,8 +81,6 @@ public class Constants public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "fanout", "headers", "topic"}; public final static String[] BOOLEAN_TYPE_VALUES = {"false", "true"}; public final static String[] ATTRIBUTE_TABLE_TITLES = {"Attribute Name", "Value"}; - public static final String[] CONNECTION_PROTOCOLS ={"RMI"}; - public static final String DEFAULT_PROTOCOL = CONNECTION_PROTOCOLS[0]; public final static String ACTION_ADDSERVER = "New Connection"; public final static String ACTION_RECONNECT = "Reconnect"; diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java index 31825e925d..ae01f30f32 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java @@ -20,13 +20,17 @@ */ package org.apache.qpid.management.ui; -import static org.apache.qpid.management.ui.Constants.*; +import static org.apache.qpid.management.ui.Constants.ADMIN_MBEAN_TYPE; +import static org.apache.qpid.management.ui.Constants.CONNECTION; +import static org.apache.qpid.management.ui.Constants.DEFAULT_VH; +import static org.apache.qpid.management.ui.Constants.EXCHANGE; +import static org.apache.qpid.management.ui.Constants.QUEUE; +import static org.apache.qpid.management.ui.Constants.VIRTUAL_HOST; + import java.util.HashMap; /** * Class representing a managed bean on the managed server - * @author Bhupendra Bhardwaj - * */ public abstract class ManagedBean extends ManagedObject { @@ -36,27 +40,50 @@ public abstract class ManagedBean extends ManagedObject private String _virtualHostName = null; private ManagedServer _server = null; private HashMap _properties = null; - + private int _version; + public String getProperty(String key) { - return (String)_properties.get(key); + return (String) _properties.get(key); } - + public HashMap getProperties() { return _properties; } + public void setProperties(HashMap properties) { this._properties = properties; setName(getProperty("name")); setType(getProperty("type")); + setVersion(getProperty("version")); _virtualHostName = getProperty(VIRTUAL_HOST); } + + public void setVersion(String version) + { + try + { + _version = Integer.parseInt(version); + } + catch (NumberFormatException nfe) + { + _version = 1; + } + + } + + public int getVersion() + { + return _version; + } + public String getDomain() { return _domain; } + public void setDomain(String domain) { this._domain = domain; @@ -66,65 +93,75 @@ public abstract class ManagedBean extends ManagedObject { return _server; } + public void setServer(ManagedServer server) { this._server = server; } + public String getType() { return _type; } + public void setType(String type) { this._type = type; } + public String getUniqueName() { return _uniqueName; } + public void setUniqueName(String uniqueName) { this._uniqueName = uniqueName; } - + public String getVirtualHostName() { // To make it work with the broker with no virtual host implementation return _virtualHostName == null ? DEFAULT_VH : _virtualHostName; } - + /** * Returns mbean instance name. MBeans which have only one instance, the type attribute will be returned + * * @return */ public String getInstanceName() { if (getName() != null) + { return getName(); + } else + { return getType(); + } } - + public boolean isQueue() { return _type.endsWith(QUEUE); } - + public boolean isConnection() { return _type.endsWith(CONNECTION); } - + public boolean isExchange() { return _type.endsWith(EXCHANGE); } - + public boolean isTempQueue() { return (isQueue() && getName().startsWith("tmp_")); } - + public boolean isAdmin() { return _type.endsWith(ADMIN_MBEAN_TYPE); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java index 480fdb429a..9ca8787bb5 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java @@ -20,20 +20,16 @@ */ package org.apache.qpid.management.ui; -import static org.apache.qpid.management.ui.Constants.DEFAULT_PROTOCOL; /** * Class representing a server being managed eg. MBeanServer - * @author Bhupendra Bhardwaj */ public class ManagedServer extends ManagedObject { private String _host; private int _port; - private String _url; private String _domain; private String _user; private String _password; - private String _protocol = DEFAULT_PROTOCOL; public ManagedServer(String host, int port, String domain) { @@ -46,7 +42,6 @@ public class ManagedServer extends ManagedObject _host = host; _port = port; _domain = domain; - _url = getRMIURL(host, port); _user = user; _password = password; } @@ -65,17 +60,7 @@ public class ManagedServer extends ManagedObject { return _port; } - - public String getUrl() - { - return _url; - } - public String getProtocol() - { - return _protocol; - } - public String getPassword() { return _password; @@ -96,8 +81,4 @@ public class ManagedServer extends ManagedObject _user = user; } - private String getRMIURL(String host, int port) - { - return "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; - } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java index ce7d8816ba..e487c02a67 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java @@ -35,7 +35,6 @@ import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; @@ -46,12 +45,9 @@ import org.eclipse.ui.IWorkbenchWindowActionDelegate; public class AddServer extends AbstractAction implements IWorkbenchWindowActionDelegate { - private static final String[] _domains ={"org.apache.qpid"}; - - private String _transport = DEFAULT_PROTOCOL; private String _host; private String _port; - private String _domain; + private String _domain = DEFAULT_DOMAIN; private String _user; private String _password; @@ -73,7 +69,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD { if (_addServer) { - getNavigationView().addNewServer(_transport, _host, Integer.parseInt(_port), _domain, _user, _password); + getNavigationView().addNewServer(_host, Integer.parseInt(_port), _domain, _user, _password); } } catch(InfoRequiredException ex) @@ -91,7 +87,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD _addServer = false; _host = null; _port = null; - _domain = null; _user = null; _password = null; } @@ -103,6 +98,8 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD */ private void createAddServerPopup() { + final Shell appShell = _window.getShell(); + Display display = Display.getCurrent(); final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE); shell.setText(ACTION_ADDSERVER); @@ -112,21 +109,23 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD createWidgets(shell); shell.pack(); - //get current size dialog, and screen size - int displayWidth = display.getBounds().width; - int displayHeight = display.getBounds().height; + //get current size dialog, and application window size and location + int appWidth = appShell.getBounds().width; + int appHeight = appShell.getBounds().height; + int appLocX = appShell.getBounds().x; + int appLocY = appShell.getBounds().y; int currentShellWidth = shell.getSize().x; int currentShellHeight = shell.getSize().y; //default sizes for the dialog int minShellWidth = 425; - int minShellHeight= 290; + int minShellHeight= 265; //ensure this is large enough, increase it if its not int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth; int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight; - //set the final size and centre the dialog - shell.setBounds((displayWidth - newShellWidth)/2 , (displayHeight - newShellHeight)/2, newShellWidth, newShellHeight); + //set the final size and centre the dialog within the app window + shell.setBounds((appWidth - newShellWidth)/2 + appLocX, (appHeight - newShellHeight)/2 + appLocY, newShellWidth, newShellHeight); shell.open(); _window.getShell().setEnabled(false); @@ -189,17 +188,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD // Verify if the value entered is numeric textPort.addVerifyListener(new NumberVerifyListener()); - - Label domain = new Label(composite, SWT.NONE); - domain.setText("Domain"); - domain.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); - - final Combo comboDomain = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); - comboDomain.setItems(_domains); - comboDomain.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - comboDomain.select(0); - - Label user = new Label(composite, SWT.NONE); user.setText(USERNAME); user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); @@ -228,7 +216,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD if (event.character == SWT.ESC) { //Escape key acts as cancel on all widgets - shell.close(); + shell.dispose(); } } }); @@ -283,7 +271,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD return; } - _domain = comboDomain.getText(); _addServer = true; shell.dispose(); } @@ -314,7 +301,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD if (event.character == SWT.ESC) { //Escape key acts as cancel on all widgets - shell.close(); + shell.dispose(); } } }); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java index ce9d80d49b..5eb9d9a168 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java @@ -99,6 +99,8 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA // Create the login popup fot th user to enter usernaem and password private void createLoginPopup() { + final Shell appShell = _window.getShell(); + Display display = Display.getCurrent(); final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE); shell.setText(_title); @@ -108,9 +110,11 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA createWidgets(shell); shell.pack(); - //get current size dialog, and screen size - int displayWidth = display.getBounds().width; - int displayHeight = display.getBounds().height; + //get current size dialog, and application window size and location + int appWidth = appShell.getBounds().width; + int appHeight = appShell.getBounds().height; + int appLocX = appShell.getBounds().x; + int appLocY = appShell.getBounds().y; int currentShellWidth = shell.getSize().x; int currentShellHeight = shell.getSize().y; @@ -121,8 +125,8 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth; int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight; - //set the final size and centre the dialog - shell.setBounds((displayWidth - newShellWidth)/2 , (displayHeight - newShellHeight)/2, newShellWidth, newShellHeight); + //set the final size and centre the dialog within the app window + shell.setBounds((appWidth - newShellWidth)/2 + appLocX, (appHeight - newShellHeight)/2 + appLocY, newShellWidth, newShellHeight); shell.open(); _window.getShell().setEnabled(false); @@ -182,7 +186,7 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA if (event.character == SWT.ESC) { //Escape key acts as cancel on all widgets - shell.close(); + shell.dispose(); } } }); @@ -248,7 +252,7 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA if (event.character == SWT.ESC) { //Escape key acts as cancel on all widgets - shell.close(); + shell.dispose(); } } }); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java index 2be0ddbebf..c3348b32f0 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java @@ -45,7 +45,6 @@ public class ClientListener implements NotificationListener { ObjectName objName = null; String type = notification.getType(); - MBeanUtility.printOutput(type + ":" + objName); if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) { @@ -60,6 +59,7 @@ public class ClientListener implements NotificationListener else if (JMXConnectionNotification.FAILED.equals(type)) { ApplicationRegistry.serverConnectionClosed(server); + MBeanUtility.printOutput("Recieved notification from " + server.getName() + ": " + type ); } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java index c6ecda4b4c..2af8e681ae 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java @@ -35,7 +35,6 @@ public class ClientNotificationListener extends ClientListener public void handleNotification(Notification notification, Object handback) { ObjectName objName = (ObjectName)notification.getSource(); - //String type = notification.getType(); getServerRegistry().addNotification(objName, notification); } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java index 945c63f19a..cf3db26f4b 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java @@ -164,7 +164,6 @@ public class JMXServerRegistry extends ServerRegistry public void removeManagedObject(ManagedBean mbean) { - MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName()); if (mbean.isQueue()) { diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java index 29d7b9c557..479f68de03 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java @@ -440,18 +440,6 @@ public class MBeanUtility return mbeans; } - /** - * Returns all the domains for the given server. This method can be removed as now this RCP is specific to - * Qpid and domain is also fixed - */ - public static List<String> getAllDomains(ManagedServer server) throws Exception - { - JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server); - MBeanServerConnection mbsc = serverRegistry.getServerConnection(); - String[] domains = mbsc.getDomains(); - return Arrays.asList(domains); - } - public static void printOutput(String statement) { if (ApplicationRegistry.debug) diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java index d4b2ed1db6..7e04e9ac7a 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java @@ -191,7 +191,7 @@ public abstract class MBeanTypeTabControl */ protected void createAddButton(Composite parentComposite) { - Button _addButton = _toolkit.createButton(parentComposite, "<- Add to Navigation", SWT.PUSH); + Button _addButton = _toolkit.createButton(parentComposite, "<- Add selected " + _type + "(s) to navigation tree", SWT.PUSH); GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); _addButton.setLayoutData(gridData); _addButton.addSelectionListener(new SelectionAdapter(){ @@ -292,7 +292,7 @@ public abstract class MBeanTypeTabControl protected void setLabelValues() { _labelName.setText("Type : " + _type); - _labelDesc.setText("Select the " + _type + "(s) to add in the Navigation View"); + _labelDesc.setText("Select the " + _type + "(s) to add to the navigation tree for further interaction."); _labelList.setText("-- List of " + _type + "s --"); } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java index 5476c27871..3c8e52f1d2 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java @@ -30,6 +30,7 @@ import org.apache.qpid.management.ui.ServerRegistry; import org.apache.qpid.management.ui.exceptions.InfoRequiredException; import org.apache.qpid.management.ui.jmx.MBeanUtility; import org.apache.qpid.management.ui.model.AttributeData; +import org.apache.qpid.management.ui.model.NotificationInfoModel; import org.apache.qpid.management.ui.model.OperationData; import org.apache.qpid.management.ui.model.OperationDataModel; import org.eclipse.jface.viewers.ISelection; @@ -135,8 +136,7 @@ public class MBeanView extends ViewPart { try { - if (_selectedNode == null || NODE_TYPE_SERVER.equals(_selectedNode.getType()) || - NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) ) + if (_selectedNode == null || NODE_TYPE_SERVER.equals(_selectedNode.getType())) { return; } @@ -176,8 +176,7 @@ public class MBeanView extends ViewPart */ private void setServer() { - if (NODE_TYPE_SERVER.equals(_selectedNode.getType()) || - NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) ) + if (NODE_TYPE_SERVER.equals(_selectedNode.getType())) { _server = (ManagedServer)_selectedNode.getManagedObject(); _virtualHostName = null; @@ -359,6 +358,13 @@ public class MBeanView extends ViewPart private void createNotificationsTab(TabFolder tabFolder) { + NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); + if (items == null || items.length == 0) + { + //the mbean has no notifications to subscribe for, do not create the tab. + return; + } + NotificationsTabControl controller = new NotificationsTabControl(tabFolder); TabItem tab = new TabItem(tabFolder, SWT.NONE); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java index ec8a612d41..b3caf5e415 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java @@ -72,7 +72,8 @@ import org.eclipse.ui.part.ViewPart; public class NavigationView extends ViewPart { public static final String ID = "org.apache.qpid.management.ui.navigationView"; - public static final String INI_FILENAME = System.getProperty("user.home") + File.separator + "qpidManagementConsole.ini"; + public static final String APP_DIR = System.getProperty("user.home") + File.separator + ".qpidmc"; + public static final String INI_FILENAME = APP_DIR + File.separator + "qpidmc_navigation.ini"; private static final String INI_SERVERS = "Servers"; private static final String INI_QUEUES = QUEUE + "s"; @@ -130,16 +131,26 @@ public class NavigationView extends ViewPart { public void treeExpanded(TreeExpansionEvent event) { - _treeViewer.setExpandedState(event.getElement(), true); - // Following will cause the selection event to be sent, so commented - // _treeViewer.setSelection(new StructuredSelection(event.getElement())); - _treeViewer.refresh(); + getSite().getShell().getDisplay().asyncExec( + new Runnable() + { + public void run() + { + _treeViewer.refresh(); + } + }); } public void treeCollapsed(TreeExpansionEvent event) { - _treeViewer.setExpandedState(event.getElement(), false); - _treeViewer.refresh(); + getSite().getShell().getDisplay().asyncExec( + new Runnable() + { + public void run() + { + _treeViewer.refresh(); + } + }); } }); @@ -201,11 +212,11 @@ public class NavigationView extends ViewPart } /** - * Creates Qpid Server connection using JMX RMI protocol + * Creates Qpid Server connection * @param server * @throws Exception */ - private void createRMIServerConnection(ManagedServer server) throws Exception + private void createJMXServerConnection(ManagedServer server) throws Exception { // Currently Qpid Management Console only supports JMX MBeanServer ServerRegistry serverRegistry = new JMXServerRegistry(server); @@ -220,42 +231,32 @@ public class NavigationView extends ViewPart * @param domain * @throws Exception */ - public void addNewServer(String transportProtocol, String host, int port, String domain, String user, String pwd) + public void addNewServer(String host, int port, String domain, String user, String pwd) throws Exception { - String serverAddress = host + ":" + port; - String url = null; ManagedServer managedServer = new ManagedServer(host, port, domain, user, pwd); - if ("RMI".equals(transportProtocol)) + String server = managedServer.getName(); + List<TreeObject> list = _serversRootNode.getChildren(); + for (TreeObject node : list) { - url = managedServer.getUrl(); - List<TreeObject> list = _serversRootNode.getChildren(); - for (TreeObject node : list) + ManagedServer nodeServer = (ManagedServer)node.getManagedObject(); + if (server.equals(nodeServer.getName())) { - ManagedServer nodeServer = (ManagedServer)node.getManagedObject(); - if (url.equals(nodeServer.getUrl())) - { - // Server is already in the list of added servers, so now connect it. - // Set the server node as selected and then connect it. - _treeViewer.setSelection(new StructuredSelection(node)); - reconnect(user, pwd); + // Server is already in the list of added servers, so now connect it. + // Set the server node as selected and then connect it. + _treeViewer.setSelection(new StructuredSelection(node)); + reconnect(user, pwd); - return; - } + return; } - - // The server is not in the list of already added servers, so now connect and add it. - managedServer.setName(serverAddress); - createRMIServerConnection(managedServer); - } - else - { - throw new InfoRequiredException(transportProtocol + " transport is not supported"); } + // The server is not in the list of already added servers, so now connect and add it. + createJMXServerConnection(managedServer); + // Server connection is successful. Now add the server in the tree - TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER); + TreeObject serverNode = new TreeObject(server, NODE_TYPE_SERVER); serverNode.setManagedObject(managedServer); _serversRootNode.addChild(serverNode); @@ -276,10 +277,12 @@ public class NavigationView extends ViewPart // Add the Queue/Exchanges/Connections from config file into the navigation tree addConfiguredItems(managedServer); + expandInitialMBeanView(serverNode); + _treeViewer.refresh(); // save server address in file - addServerInConfigFile(serverAddress); + addServerInConfigFile(server); } /** @@ -288,6 +291,16 @@ public class NavigationView extends ViewPart */ private void createConfigFile() { + File dir = new File(APP_DIR); + if (!dir.exists()) + { + if(!dir.mkdir()) + { + System.out.println("Could not create application data directory " + APP_DIR); + System.exit(1); + } + } + File file = new File(INI_FILENAME); try { @@ -405,50 +418,33 @@ public class NavigationView extends ViewPart } } - /** - * Queries the qpid server for MBeans and populates the navigation view with all MBeans for - * the given server node. - * @param serverNode - */ - private void populateServer(TreeObject serverNode) throws Exception + //check if the MBeanInfo can be retrieved. + private boolean haveAccessPermission(ManagedBean mbean) { - ManagedServer server = (ManagedServer) serverNode.getManagedObject(); - String domain = server.getDomain(); - if (!domain.equals(ALL)) - { - TreeObject domainNode = new TreeObject(domain, NODE_TYPE_DOMAIN); - domainNode.setParent(serverNode); - - populateDomain(domainNode); + try + { + MBeanUtility.getMBeanInfo(mbean); } - else + catch(Exception ex) { - List<TreeObject> domainList = new ArrayList<TreeObject>(); - List<String> domains = MBeanUtility.getAllDomains(server); - - for (String domainName : domains) - { - TreeObject domainNode = new TreeObject(domainName, NODE_TYPE_DOMAIN); - domainNode.setParent(serverNode); - - domainList.add(domainNode); - populateDomain(domainNode); - } + return false; } + + return true; } - + /** - * Queries the Qpid Server and populates the given domain node with all MBeans undser that domain. - * @param domain - * @throws IOException + * Queries the qpid server for MBeans and populates the navigation view with all MBeans for + * the given server node. + * @param serverNode * @throws Exception */ - private void populateDomain(TreeObject domain) throws IOException, Exception + private void populateServer(TreeObject serverNode) throws Exception { - ManagedServer server = (ManagedServer) domain.getParent().getManagedObject(); + ManagedServer server = (ManagedServer) serverNode.getManagedObject(); + String domain = server.getDomain(); - // Now populate the mbenas under those types - List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain.getName()); + List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain); for (ManagedBean mbean : mbeans) { mbean.setServer(server); @@ -459,13 +455,17 @@ public class NavigationView extends ViewPart // manually by selecting from MBeanView if (!(mbean.isConnection() || mbean.isExchange() || mbean.isQueue())) { - addManagedBean(domain, mbean); + //if we cant get the MBeanInfo then we cant display the mbean, so dont add it to the tree + if (haveAccessPermission(mbean)) + { + addManagedBean(serverNode, mbean); + } } } // To make it work with the broker without virtual host implementation. // This will add the default nodes to the domain node boolean hasVirtualHost = false; - for (TreeObject child : domain.getChildren()) + for (TreeObject child : serverNode.getChildren()) { if (child.getName().startsWith(VIRTUAL_HOST)) { @@ -475,7 +475,7 @@ public class NavigationView extends ViewPart } if (!hasVirtualHost){ - addDefaultNodes(domain); + addDefaultNodes(serverNode); } } @@ -540,15 +540,14 @@ public class NavigationView extends ViewPart } /** - * Adds the given MBean to the given domain node. Creates Notification node for the MBean. + * Adds the given MBean to the given domain node. * sample ObjectNames - * org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=localhost * org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping_1 - * @param domain - * @param mbean - * @throws Exception + * @param parent parent tree node to add the mbean to + * @param mbean mbean to add */ - private void addManagedBean(TreeObject domain, ManagedBean mbean) // throws Exception + private void addManagedBean(TreeObject parent, ManagedBean mbean) { String name = mbean.getName(); // Split the mbean type into array of Strings, to create hierarchy @@ -558,7 +557,7 @@ public class NavigationView extends ViewPart // test->Queue->ping String[] types = mbean.getType().split("\\."); TreeObject typeNode = null; - TreeObject parentNode = domain; + TreeObject parentNode = parent; // Run this loop till all nodes(hierarchy) for this mbean are created. This loop only creates // all the required parent nodes for the mbean @@ -638,11 +637,6 @@ public class NavigationView extends ViewPart { addItemInConfigFile(mbeanNode); } - - // Add notification node - // TODO: show this only if the mbean sends any notification - //TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION); - //notificationNode.setParent(mbeanNode); } private TreeObject createTypeNode(TreeObject parent, String name) @@ -755,7 +749,7 @@ public class NavigationView extends ViewPart managedServer.setUser(user); managedServer.setPassword(password); - createRMIServerConnection(managedServer); + createJMXServerConnection(managedServer); // put the server in the managed server map _managedServerMap.put(managedServer, selectedNode); @@ -775,8 +769,31 @@ public class NavigationView extends ViewPart // Add the Queue/Exchanges/Connections from config file into the navigation tree addConfiguredItems(managedServer); + expandInitialMBeanView(selectedNode); + _treeViewer.refresh(); } + + private void expandInitialMBeanView(TreeObject serverNode) + { + if (serverNode.getChildren().size() == 0 ) + { + return; + } + else + { + _treeViewer.setExpandedState(serverNode , true); + } + + List<TreeObject> children = serverNode.getChildren(); + for (TreeObject child : children) + { + if (child.getChildren().size() > 0) + { + _treeViewer.setExpandedState(child, true); + } + } + } /** * Adds the items(queues/exchanges/connectins) from config file to the server tree @@ -1157,25 +1174,12 @@ public class NavigationView extends ViewPart /** * Adds the mbean to the navigation tree - * @param mbean - * @throws Exception + * @param mbean mbean to add to the tree */ - public void addManagedBean(ManagedBean mbean) // throws Exception + public void addManagedBean(ManagedBean mbean) { TreeObject treeServerObject = _managedServerMap.get(mbean.getServer()); - List<TreeObject> domains = treeServerObject.getChildren(); - TreeObject domain = null; - for (TreeObject child : domains) - { - if (child.getName().equals(mbean.getDomain())) - { - domain = child; - - break; - } - } - - addManagedBean(domain, mbean); + addManagedBean(treeServerObject, mbean); _treeViewer.refresh(); } @@ -1200,20 +1204,8 @@ public class NavigationView extends ViewPart for (ManagedBean mbean : removalList) { TreeObject treeServerObject = _managedServerMap.get(mbean.getServer()); - List<TreeObject> domains = treeServerObject.getChildren(); - TreeObject domain = null; - for (TreeObject child : domains) - { - if (child.getName().equals(mbean.getDomain())) - { - domain = child; - - break; - } - } - removeManagedObject(domain, mbean); - // serverRegistry.removeManagedObject(mbean); + removeManagedObject(treeServerObject, mbean); } _treeViewer.refresh(); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java index 36ad1b4fdc..11df1b6f00 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java @@ -33,8 +33,6 @@ import static org.apache.qpid.management.ui.Constants.*; import org.apache.qpid.management.ui.ApplicationRegistry; import org.apache.qpid.management.ui.ManagedBean; -import org.apache.qpid.management.ui.ServerRegistry; -import org.apache.qpid.management.ui.jmx.JMXServerRegistry; import org.apache.qpid.management.ui.jmx.MBeanUtility; import org.apache.qpid.management.ui.model.OperationData; import org.apache.qpid.management.ui.model.ParameterData; @@ -69,8 +67,6 @@ import org.eclipse.ui.forms.widgets.FormToolkit; /** * Control class for the MBean operations tab. It creates the required widgets * for the selected MBean. - * @author Bhupendra Bhardwaj - * @author Robert Gemmell */ public class OperationTabControl extends TabControl { @@ -521,7 +517,7 @@ public class OperationTabControl extends TabControl private void populateResults(Object result) { Display display = Display.getCurrent(); - int width = 600; + int width = 610; int height = 400; Shell shell = ViewUtility.createPopupShell(RESULT, width, height); shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE)); @@ -605,23 +601,37 @@ public class OperationTabControl extends TabControl return; } - // customized for passwords - if (PASSWORD.equalsIgnoreCase(param.getName())) + //Custom handling for the PASSWORD field + if (param.getName().equalsIgnoreCase(PASSWORD)) { + //Convert the String value to a character array if that is what is required. if (param.getType().equals("[C")) { - try + // Retreive the mBean type and version. + // If we have a version 1 UserManagement class mbean then it expects the password + // to be sent as the hashed version. + if (_mbean.getType().equals("UserManagement") && _mbean.getVersion() == 1) { - param.setValue(ViewUtility.getHash((String)param.getValue())); + try + { + param.setValue(ViewUtility.getHash((String) param.getValue())); + } + catch (Exception hashException) + { + ViewUtility.popupErrorMessage(_form.getText(), + "Unable to calculate hash for Password:" + + hashException.getMessage()); + return; + } } - catch (Exception ex) + else { - MBeanUtility.handleException(_mbean, ex); - return; + param.setValue(((String) param.getValue()).toCharArray()); } } } // end of customization + } } @@ -725,7 +735,14 @@ public class OperationTabControl extends TabControl { boolean success = Boolean.parseBoolean(result.toString()); String message = success ? OPERATION_SUCCESSFUL : OPERATION_UNSUCCESSFUL; - ViewUtility.popupInfoMessage(title, message); + if(success) + { + ViewUtility.popupInfoMessage(title, message); + } + else + { + ViewUtility.popupErrorMessage(title, message); + } } else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty()) { diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java index 9fcf32abdd..6e37e96695 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java @@ -271,12 +271,50 @@ public class QueueTypeTabControl extends MBeanTypeTabControl for (AttributeData data : list) { ManagedBean mbean = _queueDepthMap.get(data); - String value = data.getValue().toString(); - items[i++] = mbean.getName() + " (" + value + " KB)"; + items[i++] = mbean.getName() + " (" + getQueueDepthString(mbean, data) + ")"; } getListWidget().setItems(items); } + private String getQueueDepthString(ManagedBean mbean, AttributeData data) + { + if (mbean.getVersion() == 1) //mbean returns KB + { + Long value = (Long)data.getValue(); + + Double mb = 1024.0; + + if(value > mb) //MB + { + return String.format("%.3f", (Double)(value / mb)) + " MB"; + } + else //KB + { + return data.getValue().toString() + " KB"; + } + } + else //mbean returns Bytes + { + Long value = (Long)data.getValue(); + + double mb = 1024.0 * 1024.0; + double kb = 1024.0; + + if(value >= mb) //MB + { + return String.format("%.3f", (Double)(value / mb)) + " MB"; + } + else if (value >= kb) //KB + { + return String.format("%.3f", (Double)(value / kb)) + " KB"; + } + else //Bytes + { + return data.getValue().toString() + " Bytes"; + } + } + } + private void sortQueuesByConsumerCount() { java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueConsumerCountMap.keySet()); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java index 5d6a03b238..16bae07e48 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java @@ -39,14 +39,15 @@ import javax.management.openmbean.OpenType; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; -import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.ErrorDialog; +import org.apache.commons.codec.binary.Hex; + import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -56,12 +57,12 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.FormToolkit; /** * Utility Class for displaying OpenMbean data types by creating required SWT widgets - * @author Bhupendra Bhardwaj */ public class ViewUtility { @@ -89,6 +90,10 @@ public class ViewUtility SUPPORTED_ARRAY_DATATYPES.add("java.util.Date"); } + private static final int DEFAULT_CONTENT_SIZE = 198; + static Button _firstButton, _nextButton, _previousButton, _lastButton; + static Text _hexNumTextToEnd, _hexNumTextToStart; + /** * Populates the composite with given openmbean data type (TabularType or CompositeType) * @param toolkit @@ -190,15 +195,15 @@ public class ViewUtility layoutData.widthHint = 80; firstRecordButton.setLayoutData(layoutData); - final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH); + final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH); layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END); layoutData.widthHint = 80; - nextRecordButton.setLayoutData(layoutData); + previousRecordButton.setLayoutData(layoutData); - final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH); + final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH); layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING); layoutData.widthHint = 80; - previousRecordButton.setLayoutData(layoutData); + nextRecordButton.setLayoutData(layoutData); final Button lastRecordButton = toolkit.createButton(dataHolder, LAST, SWT.PUSH); layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING); @@ -352,7 +357,7 @@ public class ViewUtility } else { - setNotSupportedDataType(toolkit, compositeHolder); + handleBinaryMessageContent(toolkit, compositeHolder, data, itemName, encoding); } } // If array of any other supported type, show as a list of String array @@ -436,6 +441,321 @@ public class ViewUtility return messageBox.open(); } + /** + * Creates widgets for object messages and populates the content in hexadecimal format. + * @param toolkit + * @param compositeHolder + * @param data + * @param itemName + * @param encoding + */ + private static void handleBinaryMessageContent(FormToolkit toolkit, Composite compositeHolder, CompositeData data, String itemName, String encoding) + { + final String thisEncoding = encoding; + final Byte[] arrayItems = (Byte[]) data.get(itemName); + final byte[] byteArray = new byte[arrayItems.length]; + + for (int i = 0; i < arrayItems.length; i++) + { + byteArray[i] = arrayItems[i]; + } + + try + { + //create a new composite to contain the widgets required to display object messages. + final Composite localComposite = toolkit.createComposite(compositeHolder, SWT.NONE); + localComposite.setData("currentBytePos", 0); + localComposite.setData("startingBytePos", 0); + GridLayout layout = new GridLayout(2, true); + layout.marginWidth = 0; + layout.marginHeight = 0; + localComposite.setLayout(layout); + localComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + + int startContentSize = DEFAULT_CONTENT_SIZE; + + if (byteArray.length < DEFAULT_CONTENT_SIZE) + { + startContentSize = byteArray.length; + } + + //create a text to display the hexadecimal views of object messages, it takes more space than ascii view as + //a hex uses 2 chars and 1 space, while ascii only uses 1 char and 1 space. + final Text hexText = toolkit.createText(localComposite, + new String(displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", true)), + SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + gridData.widthHint = 144; //set to 222 if not using any fonts + gridData.heightHint = 200; + hexText.setLayoutData(gridData); + + final Text asciiText = toolkit.createText(localComposite, + new String(displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", false)), + SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER); + + + gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + gridData.widthHint = 52;//set to 98 if not using any fonts + gridData.heightHint = 200; + asciiText.setLayoutData(gridData); + + //use a monospaced font for a better layout + Font font = new Font(compositeHolder.getDisplay(), "Courier", 10, SWT.NORMAL); + hexText.setFont(font); + asciiText.setFont(font); + + final ScrollBar hexScrollBar = hexText.getVerticalBar(); + final ScrollBar asciiScrollBar = asciiText.getVerticalBar(); + + //create a sub composite to contain all the buttons + final Composite buttonComposite = toolkit.createComposite(localComposite, SWT.NONE); + layout = new GridLayout(7, false); + layout.marginWidth = 0; + buttonComposite.setLayout(layout); + buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1)); + + _firstButton = toolkit.createButton(buttonComposite, "<<", SWT.PUSH); + GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + _firstButton.setLayoutData(layoutData); + _firstButton.setToolTipText("See the first n bytes"); + + _previousButton = toolkit.createButton(buttonComposite, "<", SWT.PUSH); + layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + _previousButton.setLayoutData(layoutData); + _previousButton.setToolTipText("See the previous n bytes"); + _previousButton.setEnabled(false); + + _hexNumTextToStart = toolkit.createText(buttonComposite, "0"); + layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + _hexNumTextToStart.setLayoutData(layoutData); + _hexNumTextToStart.setEditable(false); + + final Text hexNumText = toolkit.createText(buttonComposite, "" + startContentSize); + layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + hexNumText.setLayoutData(layoutData); + + _hexNumTextToEnd = toolkit.createText(buttonComposite, "" + (byteArray.length - startContentSize)); + layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + _hexNumTextToEnd.setLayoutData(layoutData); + _hexNumTextToEnd.setEditable(false); + + _nextButton = toolkit.createButton(buttonComposite, ">", SWT.PUSH); + layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + _nextButton.setLayoutData(layoutData); + _nextButton.setToolTipText("See the next n bytes"); + _nextButton.setEnabled(true); + + _lastButton = toolkit.createButton(buttonComposite, ">>", SWT.PUSH); + layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + layoutData.widthHint = 40; + _lastButton.setToolTipText("See the last n bytes"); + _lastButton.setLayoutData(layoutData); + + SelectionListener listener = new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (e.widget instanceof Button) + { + String numOfBytes = hexNumText.getText(); + try + { + int n = Integer.parseInt(numOfBytes); + + //Reset range display if user requests a large value + if (n > byteArray.length) + { + n = (byteArray.length > DEFAULT_CONTENT_SIZE) ? DEFAULT_CONTENT_SIZE : byteArray.length; + hexNumText.setText("" + n); + } + + //rest if the user requests 0 + if (n < 1) + { + n = DEFAULT_CONTENT_SIZE; + hexNumText.setText("" + n); + } + + Button button = (Button) e.widget; + hexText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding, + button.getText(), true)); + asciiText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding, + button.getText(), false)); + } + catch (NumberFormatException exp) + { + popupErrorMessage("Error", "Please input the number of bytes you wish to look at"); + } + } + if (e.widget instanceof ScrollBar) + { + //synchronize the movements of the two scrollbars + ScrollBar sb = (ScrollBar) e.widget; + if (sb.getParent().equals(hexText)) + { + asciiScrollBar.setIncrement(sb.getIncrement()); + asciiScrollBar.setSelection(sb.getSelection()); + } + else if (sb.getParent().equals(asciiText)) + { + hexScrollBar.setSelection(sb.getSelection()); + hexScrollBar.setIncrement(sb.getIncrement()); + } + } + } + }; + localComposite.addControlListener(new ControlAdapter() + { + public void controlResized(ControlEvent e) + { + //if the control is resized, set different parameters to make a single line displays the same contents. + if (((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth) + { + ((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = false; + ((GridLayout) localComposite.getLayout()).numColumns = 2; + ((GridData) hexText.getLayoutData()).horizontalSpan = 1; + ((GridData) hexText.getLayoutData()).widthHint = 144; + ((GridData) asciiText.getLayoutData()).horizontalSpan = 1; + ((GridData) asciiText.getLayoutData()).widthHint = 52; + ((GridData) buttonComposite.getLayoutData()).horizontalSpan = 2; + } + else + { + ((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = true; + ((GridLayout) localComposite.getLayout()).numColumns = 42; //set to 47 if not using any fonts + ((GridData) hexText.getLayoutData()).horizontalSpan = 25; // set to 30 if not using any fonts + ((GridData) asciiText.getLayoutData()).horizontalSpan = 17; // set to 17 if not using any fonts + ((GridData) buttonComposite.getLayoutData()).horizontalSpan = 42; + } + } + }); + + _firstButton.addSelectionListener(listener); + _previousButton.addSelectionListener(listener); + _nextButton.addSelectionListener(listener); + _lastButton.addSelectionListener(listener); + hexScrollBar.addSelectionListener(listener); + asciiScrollBar.addSelectionListener(listener); + //f.dispose(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + /** + * Format object messages to have a hexadecimal view and a ascii view. + * @param numOfBytes + * @param encoding + * @return + */ + private static String displayByteFormat(Composite localComposite, byte[] byteArray, int numOfBytes, + String encoding, String direction, boolean isHex) + { + final Hex hexeconder = new Hex(); + final byte[] encoded = hexeconder.encode(byteArray); + + int hexLength = byteArray.length * 2; + StringBuilder sb = new StringBuilder(); + int currentBytePos = (Integer) localComposite.getData("currentBytePos"); + int startingBytePos = (Integer) localComposite.getData("startingBytePos"); + + int strLength = 0; + int offset = 0; + String encStr; + if (isHex) + { + if (direction.equals("<<")) + { + strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes; + offset = 0; + } + else if (direction.equals("<")) + { + strLength = (startingBytePos - numOfBytes < 0) ? startingBytePos : numOfBytes; + offset = (startingBytePos - numOfBytes < 0) ? 0 : startingBytePos - numOfBytes; + } + else if (direction.equals(">")) + { + strLength = (numOfBytes > (hexLength - currentBytePos)) ? hexLength - currentBytePos : numOfBytes; + offset = currentBytePos; + } + else if (direction.equals(">>")) + { + strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes; + offset = (hexLength - numOfBytes > 0) ? hexLength - numOfBytes : 0; + } + else + { + strLength = hexLength; + offset = 0; + } + localComposite.setData("strLength", strLength); + localComposite.setData("currentBytePos", offset + strLength); + localComposite.setData("startingBytePos", offset); + + if (_lastButton != null && !_lastButton.isDisposed()) + { + //Set button state + _previousButton.setEnabled(offset != 0); + _nextButton.setEnabled(offset + strLength != hexLength); + + //set the text fields + _hexNumTextToStart.setText("" + offset / 2); + _hexNumTextToEnd.setText("" + (hexLength - (offset + strLength)) / 2); + } + } + + try + { + if (isHex) + { + encStr = new String(encoded, offset, strLength, encoding); + for (int c = 0; c < strLength; c++) + { + sb.append(encStr.charAt(c)); + if (c % 2 == 1) + { + sb.append(" "); + } + } + return sb.toString().toUpperCase(); + } + else + { + strLength = (Integer) localComposite.getData("strLength"); + sb = new StringBuilder(); + encStr = new String(byteArray, startingBytePos / 2, strLength / 2, encoding); + for (int c = 0; c < encStr.length(); c++) + { + char ch = encStr.charAt(c); + if (ch > 31 && ch < 127) + { + sb.append(ch); + } + else + { + sb.append("?"); + } + + sb.append(" "); + } + } + } + catch (UnsupportedEncodingException e) + { + e.printStackTrace(); + } + return sb.toString(); + } + public static int popupInfoMessage(String title, String message) { return showBox(title, message, SWT.ICON_INFORMATION | SWT.OK); @@ -448,7 +768,7 @@ public class ViewUtility public static int popupConfirmationMessage(String title, String message) { - return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL); + return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO); } diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini index be058e2ae5..dc15366740 100644 --- a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini +++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini @@ -45,4 +45,5 @@ org.eclipse.ui, \ org.eclipse.ui.forms, \ org.eclipse.ui.workbench, \ org.eclipse.equinox.launcher, \ -org.eclipse.equinox.launcher.gtk.linux.x86 +org.eclipse.equinox.launcher.gtk.linux.x86, \ +org.apache.commons.codec diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini new file mode 100644 index 0000000000..f437e830b5 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini @@ -0,0 +1,49 @@ +###############################################################################
+# 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.
+###############################################################################
+
+#Product Runtime Configuration File + +osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui +eclipse.product=org.apache.qpid.management.ui.product +osgi.bundles.defaultStartLevel=4 +osgi.bundles=jmxremote.sasl, \ +qpid-management-common, \ +org.apache.qpid.management.ui, \ +com.ibm.icu, \ +org.eclipse.core.commands, \ +org.eclipse.core.contenttype, \ +org.eclipse.core.databinding, \ +org.eclipse.core.expressions, \ +org.eclipse.core.jobs, \ +org.eclipse.core.runtime@start, \ +org.eclipse.core.runtime.compatibility.registry, \ +org.eclipse.equinox.app,org.eclipse.equinox.common, \ +org.eclipse.equinox.preferences, \ +org.eclipse.equinox.registry, \ +org.eclipse.help, \ +org.eclipse.jface, \ +org.eclipse.jface.databinding, \ +org.eclipse.swt, \ +org.eclipse.swt.gtk.linux.x86_64, \ +org.eclipse.ui, \ +org.eclipse.ui.forms, \ +org.eclipse.ui.workbench, \ +org.eclipse.equinox.launcher, \ +org.eclipse.equinox.launcher.gtk.linux.x86_64, \ +org.apache.commons.codec diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so Binary files differnew file mode 100644 index 0000000000..5734427fb8 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc Binary files differnew file mode 100644 index 0000000000..ff1f3a7507 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini new file mode 100644 index 0000000000..19ceb6f717 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini @@ -0,0 +1,37 @@ +############################################################################### +# 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. +############################################################################### + +-vmargs +-Xms40m +-Xmx256m +-XX:MaxPermSize=256m +-Dosgi.requiredJavaVersion=1.5 +-Declipse.consoleLog=true + +#=============================================== +# SSL trust store configuration options. +#=============================================== + +# Uncomment lines below to specify custom truststore for server SSL +# certificate verification, eg when using self-signed server certs. +# +#-Djavax.net.ssl.trustStore=<path.to.truststore> +#-Djavax.net.ssl.trustStorePassword=<truststore.password> + + diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini index a7c671ce2d..3ac3aa20f3 100644 --- a/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini +++ b/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini @@ -45,4 +45,5 @@ org.eclipse.ui, \ org.eclipse.ui.forms, \ org.eclipse.ui.workbench, \ org.eclipse.equinox.launcher, \ -org.eclipse.equinox.launcher.carbon.macosx +org.eclipse.equinox.launcher.carbon.macosx, \ +org.apache.commons.codec diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF b/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF index 5ef0c78606..818daef003 100644 --- a/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF +++ b/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF @@ -8,4 +8,4 @@ Export-Package: org.apache.qpid.management.common, org.apache.qpid.management.common.sasl Bundle-Vendor: Bundle-Localization: plugin -Require-Bundle: jmxremote.sasl +Require-Bundle: jmxremote.sasl;resolution:=optional diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini new file mode 100644 index 0000000000..a99a8b3f7d --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini @@ -0,0 +1,49 @@ +###############################################################################
+# 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.
+###############################################################################
+
+#Product Runtime Configuration File + +osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui +eclipse.product=org.apache.qpid.management.ui.product +osgi.bundles.defaultStartLevel=4 +osgi.bundles=jmxremote.sasl, \ +qpid-management-common, \ +org.apache.qpid.management.ui, \ +com.ibm.icu, \ +org.eclipse.core.commands, \ +org.eclipse.core.contenttype, \ +org.eclipse.core.databinding, \ +org.eclipse.core.expressions, \ +org.eclipse.core.jobs, \ +org.eclipse.core.runtime@start, \ +org.eclipse.core.runtime.compatibility.registry, \ +org.eclipse.equinox.app,org.eclipse.equinox.common, \ +org.eclipse.equinox.preferences, \ +org.eclipse.equinox.registry, \ +org.eclipse.help, \ +org.eclipse.jface, \ +org.eclipse.jface.databinding, \ +org.eclipse.swt, \ +org.eclipse.swt.gtk.solaris.sparc, \ +org.eclipse.ui, \ +org.eclipse.ui.forms, \ +org.eclipse.ui.workbench, \ +org.eclipse.equinox.launcher, \ +org.eclipse.equinox.launcher.gtk.solaris.sparc, \ +org.apache.commons.codec diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm new file mode 100644 index 0000000000..995d7c9bb0 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm @@ -0,0 +1,311 @@ +/* XPM */ +static char *ProductIcon48[] = { +/* columns rows colors chars-per-pixel */ +"48 48 257 2", +" c black", +". c gray100", +"X c #69695A5AE8E8", +"o c #494949499191", +"O c #CECE9292BFBF", +"+ c #E7E7CACAE0E0", +"@ c #C8C88C8CBBBB", +"# c #C2C28A8ABABA", +"$ c #EAEAD7D7E8E8", +"% c #CFCFA9A9CCCC", +"& c #D9D9BCBCD8D8", +"* c #B6B68787B9B9", +"= c #C3C39999C7C7", +"- c #A7A77D7DB5B5", +"; c #BDBDA3A3CDCD", +": c #D8D8CACAE3E3", +"> c #A8A88D8DC4C4", +", c #92927575B2B2", +"< c #87876C6CAAAA", +"1 c #9A9A8383BABA", +"2 c #7B7B6363A3A3", +"3 c #666654549595", +"4 c #73735F5FADAD", +"5 c #626251519292", +"6 c #7F7F7272A7A7", +"7 c #6D6D5E5E9E9E", +"8 c #64645454A9A9", +"9 c #77776969B1B1", +"0 c #49493E3E8282", +"q c #7D7D7373B6B6", +"w c #5B5B4E4EADAD", +"e c #55554949BABA", +"r c #56564949BABA", +"t c #56564A4ABABA", +"y c #56564949B9B9", +"u c #55554949B8B8", +"i c #4F4F4444ACAC", +"p c #53534848B4B4", +"a c #53534848B3B3", +"s c #54544949B5B5", +"d c #52524747B0B0", +"f c #52524747AFAF", +"g c #54544949B3B3", +"h c #DEDEDCDCEEEE", +"j c #3E3E36369898", +"k c #43433B3B9F9F", +"l c #33332C2C7777", +"z c #42423A3A9C9C", +"x c #4A4A4040A8A8", +"c c #55554A4ABABA", +"v c #55554A4AB9B9", +"b c #54544949B7B7", +"n c #52524848B1B1", +"m c #51514747AEAE", +"M c #4E4E4545A9A9", +"N c #49494141A0A0", +"B c #52524848AFAF", +"V c #51514848AEAE", +"C c #50504747ACAC", +"Z c #4F4F4646AAAA", +"A c #51514848ADAD", +"S c #50504747ABAB", +"D c #50504848ACAC", +"F c #50504747A9A9", +"G c #4E4E4646A7A7", +"H c #4E4E4545A4A4", +"J c #4D4D4545A4A4", +"K c #4F4F4747A8A8", +"L c #4E4E4646A5A5", +"P c #4D4D4545A3A3", +"I c #3B3B35357D7D", +"U c #4E4E4646A3A3", +"Y c #55554D4D9F9F", +"T c #4A4A43438989", +"R c #51514B4B9090", +"E c #67676060A5A5", +"W c #1D1D18186A6A", +"Q c #272722227D7D", +"! c #282823237D7D", +"~ c #2B2B26268181", +"^ c #33332C2C8989", +"/ c #3B3B36368E8E", +"( c #454540409797", +") c #4D4D4646A4A4", +"_ c #4C4C4545A1A1", +"` c #4D4D4646A2A2", +"' c #4B4B4545A0A0", +"] c #4D4D4646A1A1", +"[ c #4C4C45459F9F", +"{ c #4B4B45459E9E", +"} c #4A4A44449C9C", +"| c #494944449898", +" . c #484843439696", +".. c #4A4A45459999", +"X. c #4F4F4A4AA0A0", +"o. c #68686363AAAA", +"O. c #21211D1D7676", +"+. c #242420207575", +"@. c #2D2D2A2A7F7F", +"#. c #2D2D2A2A7B7B", +"$. c #3D3D39398F8F", +"%. c #484844449696", +"&. c #474743439393", +"*. c #464643439191", +"=. c #454542428E8E", +"-. c #4D4D4A4A9C9C", +";. c #57575454A3A3", +":. c #5A5A58589797", +">. c #5F5F5D5D9999", +",. c #85858282C1C1", +"<. c #95959292C9C9", +"1. c #B8B8B6B6DCDC", +"2. c #070705055353", +"3. c #080807075555", +"4. c #0A0A09095757", +"5. c #0C0C0B0B5858", +"6. c #0F0F0D0D5C5C", +"7. c #10100F0F5C5C", +"8. c #131311116464", +"9. c #141413136060", +"0. c #141413135F5F", +"q. c #171715156767", +"w. c #161615156262", +"e. c #161615156161", +"r. c #181817176464", +"t. c #1A1A19196666", +"y. c #1C1C1A1A6464", +"u. c #1D1D1C1C6868", +"i. c #1F1F1E1E6A6A", +"p. c #222221216C6C", +"a. c #242423236F6F", +"s. c #272725257171", +"d. c #272726267272", +"f. c #272726267171", +"g. c #292928287474", +"h. c #2A2A29297474", +"j. c #2C2C2B2B7777", +"k. c #2F2F2E2E7C7C", +"l. c #2E2E2D2D7979", +"z. c #343433337E7E", +"x. c #393937378686", +"c. c #373736368181", +"v. c #3A3A39398484", +"b. c #3A3A39398383", +"n. c #3D3D3B3B8686", +"m. c #424241418C8C", +"M. c #424241418B8B", +"N. c #444442428B8B", +"B. c #434341418989", +"V. c #454544448E8E", +"C. c #454544448D8D", +"Z. c #424241418787", +"A. c #434342428888", +"S. c #444442428787", +"D. c #424241418585", +"F. c #414140408383", +"G. c #484847479090", +"H. c #434342428686", +"J. c #4A4A49499393", +"K. c #464645458A8A", +"L. c #4D4D4C4C9595", +"P. c #54545252A0A0", +"I. c #50504F4F9898", +"U. c #58585757A0A0", +"Y. c #525250509393", +"T. c #5B5B5959A2A2", +"R. c #585857579F9F", +"E. c #62626161A9A9", +"W. c #64646363ACAC", +"Q. c #6B6B6A6AB2B2", +"!. c #6B6B6A6AB1B1", +"~. c #75757474B8B8", +"^. c #7F7F7D7DBDBD", +"/. c #9C9C9B9BCFCF", +"(. c #0B0B0B0B5858", +"). c #0D0D0D0D5A5A", +"_. c #111111115E5E", +"`. c #131313136060", +"'. c #212121216D6D", +"]. c #242424246F6F", +"[. c #2B2B2C2C7777", +"{. c #2B2B2B2B7777", +"}. c #2C2C2C2C7777", +"|. c #2E2E2E2E7979", +" X c #313131317C7C", +".X c #313131317B7B", +"XX c #343434347E7E", +"oX c #3C3C3C3C8686", +"OX c #3F3F3F3F8989", +"+X c #414142428B8B", +"@X c #424242428B8B", +"#X c #474747479090", +"$X c #414141418484", +"%X c #404040408181", +"&X c #4A4A4A4A9494", +"*X c #4A4A4A4A9393", +"=X c #4D4D4D4D9696", +"-X c #4F4F4F4F9898", +";X c #505050509898", +":X c #525252529B9B", +">X c #555555559E9E", +",X c #555555559D9D", +"<X c #57575858A0A0", +"1X c #58585858A0A0", +"2X c #575758589F9F", +"3X c #575757579F9F", +"4X c #5A5A5A5AA2A2", +"5X c #5D5D5D5DA5A5", +"6X c #5F5F5F5FA7A7", +"7X c #61616262AAAA", +"8X c #61616161A9A9", +"9X c #61616262A9A9", +"0X c #62626262AAAA", +"qX c #64646464ACAC", +"wX c #62626262A9A9", +"eX c #64646464ABAB", +"rX c #66666666AEAE", +"tX c #66666666ADAD", +"yX c #68686868B0B0", +"uX c #69696969AFAF", +"iX c #6D6D6D6DB4B4", +"pX c #6F6F6F6FB5B5", +"aX c #73737373BABA", +"sX c #71717171B7B7", +"dX c #76767676BCBC", +"fX c #79797979BFBF", +"gX c #77777777B9B9", +"hX c #80808080C1C1", +"jX c #8C8C8C8CC5C5", +"kX c #90909090C9C9", +"lX c #98989898CBCB", +"zX c #A0A0A0A0CFCF", +"xX c #A5A5A5A5D3D3", +"cX c #ABABABABD6D6", +"vX c #C4C4C4C4E3E3", +"bX c #D1D1D1D1E9E9", +"nX c #E5E5E5E5F3F3", +"mX c #9F9FA0A0D1D1", +"MX c #B6B6C5C5E5E5", +"NX c #8E8EA6A6D6D6", +"BX c #9090A7A7D7D7", +"VX c #9191A9A9D7D7", +"CX c #9595ABABD8D8", +"ZX c #9999AFAFDADA", +"AX c #9D9DB2B2DCDC", +"SX c #A1A1B5B5DDDD", +"DX c #A5A5B8B8DEDE", +"FX c #A9A9BBBBE0E0", +"GX c #ACACBDBDE1E1", +"HX c #B0B0C1C1E3E3", +"JX c #B4B4C4C4E4E4", +"KX c #B8B8C7C7E5E5", +"LX c #BBBBC9C9E6E6", +"PX c #AEAEC0C0E2E2", +"IX c #B2B2C3C3E3E3", +"UX c gray100", +"YX c None", +/* pixels */ +"YXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X YX", +"X %X%X%XF.F.F.F.$XD.Z.Z.Z.B.B.B.N.N.=.=.=.*.*.*.&.&. . .| ....} } { { _ _ P P H G G G K S S C o ", +"X %X%X%X%XF.F.$XD.D.Z.Z.B.A.B.N.N.N.=.=.=.*.*.&.&.%.%.%.| | ..} { { [ _ _ ` U J L G K F Z S C o ", +"X %X%X%X%XF.F.F.D.D.H.Z.Z.A.B.N.N.N.C.=.=.*.*.&.&. . .%.| | ..} } { [ [ _ P P H G G K F S S C o ", +"X %XF.%XF.F.$XF.$XZ.Z.Z.B.A.K.Y.7 , - - 1 1 ^.^.~.aX~.q 9 6XY { } { ' _ ] P P H L G K F Z S C o ", +"X %XF.F.F.F.F.D.D.Z.Z.Z.K.:.1 ; % ; <.hXfXfXdXaXaXsXpXiX!.yXrXo.;.X.[ _ _ ` H H G K K F S S C o ", +"X F.F.F.F.F.D.D.D.Z.H.Y.1 & & 1.cXmX/.kXfXdXaXaXsXpXiXQ.yXtXeXE.6X5XP.X._ ` J L G G K F Z S C o ", +"X D.$XF.$XD.D.Z.Z.S.>.% + : vX1.1.cXmX/.dXaXaXsXpXiXQ.uXrXqX8X6X5XT.R.P.X.P ) H G K K S S S m o ", +"X D.$XD.D.D.D.D.S.6 & $ h bXvXvX1.xX/.kXfXaXsXpXiXQ.yXrXW.E.6X5X4XU.,X:XI.-.` L G G K F Z C C o ", +"X D.D.D.D.D.Z.H.6 & $ h h h bXvX1.cXmXkX,.dXpXiXQ.yXtXqXwX6X5XT.U.,X:XI.=X*X..` G K K Z S S m o ", +"X Z.D.Z.H.Z.Z.7 & $ h h nXh bXvX1.cXmXkX,.gXiXQ.uXrXW.E.6X5X4XU.,X:X-XL.J.#XV. .P G F S S C m o ", +"X Z.Z.Z.H.Z.R % + : bXh h h bXvX1.cX/.kXhX~.Q.yXrXqX9X6X5X4X2X,X:X;X=X*X#XV.M.OX( K Z S S C m o ", +"X Z.Z.Z.A.A.* & & vXvXbXbXbXvXvX1.xXlXjX^.pXuXrXeXwX6X5X4XU.,X:X-XL.*XG.V.@XOXoXb.( Z S C C V o ", +"X B.B.B.A.2 % % 1.1.vXvXvXvXvX1.cXzX<.,.gXiXrXW.E.6X5X4XU.,X:XI.=X*X#XV.@XOXn.b.c.x.N S S C m o ", +"X B.B.B.S.* % ; xX1.1.1.1.1.cXcXzXlXjX^.pXrXeX7X6X5X4XR.,X:X-XL.J.#XV.@XOXn.b.c.XX X$.S C C m o ", +"X N.N.N.2 O = /.mXxXcXcXcXcXxXzXlXjXhX~.uXeXE.6X5X4XU.,X:X-XL.J.#XV.M.OXn.v.c.z. X|.k.N D V f o ", +"X N.N.N.- @ > kX<././.mXzXzXlX<.jXhXgXuXeXE.6X5X4X1X,X:XI.L.*X#XV.m.OXn.b.c.z. Xl.j.g./ C m V o ", +"X N.N.R @ # ,.,.jXkXkX<.kXkXjX,.^.~.uXwXE.6X5X4X1X,X:XI.=XJ.#XC.M.OXn.v.c.z..X|.j.g.d.#.M m B o ", +"X =.M.< @ * fXfXhXhX,.,.,.hX^.gXpXuXqX9X6X5X4XU.,X:XI.L.*XG.V.+XOXn.b.c.z..X|.[.g.d.a.p.z V B o ", +"X =.N.- @ NXNXBXBXBXVXCXCXCXCXZXZXZXZXAXAXSXSXSXDXDXDXFXFXFXGXPXPXHXHXIXJXMXMXMXKXKXLXLXLXB d o ", +"X =.=.* @ 1 dXdXaXaXsXpXiX!.yXrXeXwX6X5X4X<X,X:XI.=X*XG.V.M.OXn.v.c.XX.X|.j.g.d.a.p.i.u.@.f d o ", +"X *.=.# @ ^.dXaXaXsXpXiXQ.yXrXeXwX6X5XT.U.,X:X-XL.&XG.C.m.OXoXv.c.z..X|.j.g.f.a.p.i.u.t.+.d d o ", +"X *.*.@ @ NXNXNXBXVXVXCXCXCXCXZXZXZXZXAXAXAXSXSXDXDXDXFXFXGXGXPXPXHXHXJXJXJXMXKXKXKXLXLXLXd n o ", +"X &.*.@ @ dXaXsXpXiXQ.yXtXeXE.6X5X4XU.>X:XI.L.*XG.V.m.OXoXv.c.z. X|.j.g.d.a.'.i.u.t.r.w.9.d n o ", +"X &.&.@ @ ~.sXpXiXQ.yXtXW.E.6X5X4X1X,X:XI.=X*X#XC.m.OXn.b.c.z. X|.[.g.f.a.p.i.u.t.r.w.9.0.n a o ", +"X &.&.@ @ NXNXBXBXVXVXVXCXCXCXZXZXZXZXAXAXSXSXSXDXDXDXFXFXGXGXPXPXHXIXIXJXMXMXKXKXKXLXLXLXn n o ", +"X %. .# @ q iXQ.yXrXW.0X6X5X4XU.>X:XI.L.*X#XV.@XOXn.b.c.XX.X|.{.g.f.].'.i.u.t.r.w.0._.7.W n a o ", +"X %. .* # , Q.yXtXeX7X6X5X4XU.,X:X-XL.*X#XV.@XOXn.b.c.XX Xl.{.g.d.a.p.i.u.t.r.e.0._.7.).+.a a o ", +"X | | - # NXNXNXBXVXVXCXCXCXCXZXZXZXAXAXAXAXSXSXDXDXDXFXFXGXGXPXPXHXHXIXJXMXMXMXKXKXLXLXLXa a o ", +"X | | < # - rXeX9X6X5X4XU.,X:X-XL.*X#XC.@XOXoXb.c.z. X|.j.h.s.a.'.i.u.t.r.w.9._.7.).5.4.j a p o ", +"X | } Y # * 9 8X6X5X4X3X,X:XI.=X*XG.V.@XOXn.v.c.XX X|.j.g.f.a.p.i.u.t.r.e.0._.7.).5.4.q.i g p o ", +"X } } | - # , 6X5X4XR.,X:XI.=X*XG.V.m.OXoXb.c.XX X|.j.g.f.a.p.i.u.t.r.e.9._.7.).5.4.3.~ a s s o ", +"X } } } 4 # - E 4XU.>X:X-X=XJ.#XV.M.OXoXb.c.XX X|.{.h.d.a.'.i.u.t.r.e.9._.7.).5.4.3.6.z p s s o ", +"X { { } } - # < U.,X:XI.=X*XG.V.+XOXoXb.c.z. X|.}.g.d.a.'.i.u.t.r.w.0._.7.).5.4.3.2.! g p s s o ", +"X [ { ' [ 4 * - E :X;XL.J.#XV.m.OXoXb.c.z..X|.j.h.f.a.'.i.u.t.r.w.9._.6.).(.4.3.2.8.k p s s s o ", +"X [ [ ' _ [ , * , ;XL.J.#XV.@XOXoXv.c.z..X|.{.g.f.a.p.i.u.t.r.w.`._.7.).(.4.3.2.2.^ s p s s s o ", +"X _ _ _ _ P ] - * 2 *X#XV.m.OXn.v.c.XX X|.j.h.f.a.p.i.u.t.r.w.`._.7.).(.4.3.2.2.Q p s s s b u o ", +"X ` ` ` ` ` ` 8 - - 7 V.@XOXoXv.c.XX.X|.j.g.d.a.'.i.u.t.r.w.0._.7.).5.4.3.2.2.O.x p s s s u u o ", +"X P P ) P U U ) 8 - - 7 OXn.v.c.XX X|.j.h.f.a.p.i.u.t.r.w.0._.7.).5.4.3.2.2.O.x s s s s b u u o ", +"X L L ) H ) L L L 8 1 - 7 b.c.z. X|.j.h.f.a.'.i.u.t.r.w.0._.7.).5.4.3.2.2.Q x p s s s b b u e o ", +"X L G L G G G G G G G , * 2 T .Xl.j.h.f.a.p.i.u.t.r.e.0._.7.).5.4.3.2.8.^ p p s s s s u u e e o ", +"X G G G G G G G K K M M 4 , , 3 I g.d.a.p.i.u.t.r.e.`._.7.).5.4.3.7.! k p s p s s s u u u e v o ", +"X K G K K K K K K Z Z M F F 4 , < 3 I p.i.u.t.r.w.9._.7.).5.4.W ~ z a p p s s b s u u u e e e o ", +"X F Z F F F F Z Z F F S S S S S w 9 < 2 5 0 l p.e.9.y.a.l ^ j i a p p p s s b b b u e v y r e o ", +"X S Z Z S Z S Z S S S S S C C C A m d V f m B m B d d n d a a a p s p s s b u u u u e v e r t o ", +"X S S S S S S S S S S C C C m m A V V B B B d d d n n a a a p p s p s s b u u u e e e c t r t o ", +"X C C C C C C C C m C A m A m f V f f B d d d n n n a a a a s s s s s u b u u u u v t t r t t o ", +"YXo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o YX" +}; diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm new file mode 100644 index 0000000000..e64aa0cc06 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm @@ -0,0 +1,295 @@ +/* XPM */ +static char *ProductIcon32[] = { +/* columns rows colors chars-per-pixel */ +"32 32 257 2", +" c black", +". c gray100", +"X c #69695A5AE8E8", +"o c #494949499191", +"O c #E8E8CBCBE0E0", +"+ c #DDDDB3B3D2D2", +"@ c #F0F0DDDDEBEB", +"# c #CDCD9191BEBE", +"$ c #C8C88B8BBBBB", +"% c #CACA9898C2C2", +"& c #C3C38A8ABBBB", +"* c #BABA8787B9B9", +"= c #DCDCC4C4DEDE", +"- c #C5C5A3A3CACA", +"; c #ADAD8181B8B8", +": c #A3A37A7AB5B5", +"> c #E2E2D6D6E9E9", +", c #B3B39A9AC4C4", +"< c #EBEBE3E3F0F0", +"1 c #C9C9B6B6D6D6", +"2 c #96967676B8B8", +"3 c #8C8C7171ABAB", +"4 c #A4A49292BEBE", +"5 c #7D7D6565A6A6", +"6 c #83836D6DABAB", +"7 c #9A9A8787C2C2", +"8 c #7B7B6464B7B7", +"9 c #5E5E50509191", +"0 c #646457579A9A", +"q c #85857B7BBEBE", +"w c #7C7C7373B6B6", +"e c #62625353D5D5", +"r c #61615353D4D4", +"t c #60605252D1D1", +"y c #5F5F5252D0D0", +"u c #5F5F5151CFCF", +"i c #60605353D2D2", +"p c #5F5F5252CFCF", +"a c #5E5E5151CDCD", +"s c #5C5C4F4FC7C7", +"d c #5F5F5252CDCD", +"f c #5E5E5151CBCB", +"g c #5B5B4F4FC4C4", +"h c #5A5A4E4EC1C1", +"j c #71716969B0B0", +"k c #48483E3EADAD", +"l c #5D5D5151CDCD", +"z c #5C5C5050C9C9", +"x c #5D5D5151CBCB", +"c c #5C5C5050C7C7", +"v c #5B5B4F4FC6C6", +"b c #5B5B5050C6C6", +"n c #59594E4EC1C1", +"m c #58584D4DBFBF", +"M c #59594F4FC2C2", +"N c #5A5A4F4FC2C2", +"B c #58584D4DBCBC", +"V c #57574D4DBCBC", +"C c #59594E4EBEBE", +"Z c #58584E4EBDBD", +"A c #58584D4DBBBB", +"S c #57574D4DBABA", +"D c #56564D4DB9B9", +"F c #56564C4CB6B6", +"G c #55554C4CB6B6", +"H c #54544B4BB4B4", +"J c #54544B4BB1B1", +"K c #53534B4BB1B1", +"L c #52524A4AAEAE", +"P c #51514949ACAC", +"I c #51514949ABAB", +"U c #474741418787", +"Y c #32322C2C8F8F", +"T c #2B2B25257777", +"R c #36362F2F9696", +"E c #2B2B26266E6E", +"W c #4D4D4545ACAC", +"Q c #55554D4DB8B8", +"! c #54544C4CB4B4", +"~ c #54544C4CB3B3", +"^ c #51514A4AACAC", +"/ c #51514A4AABAB", +"( c #50504949A9A9", +") c #4F4F4949A6A6", +"_ c #4C4C4747A1A1", +"` c #4E4E4848A3A3", +"' c #4D4D4848A1A1", +"] c #4B4B46469C9C", +"[ c #4C4C47479E9E", +"{ c #51514C4CA6A6", +"} c #A9A9A6A6D5D5", +"| c #1E1E1A1A6666", +" . c #292925258181", +".. c #3D3D39399292", +"X. c #4A4A46469B9B", +"o. c #53534E4EABAB", +"O. c #494945459797", +"+. c #4A4A46469999", +"@. c #474744449494", +"#. c #484845459494", +"$. c #474744449292", +"%. c #464643439090", +"&. c #464642428D8D", +"*. c #54545050A9A9", +"=. c #474744448F8F", +"-. c #4C4C49499999", +";. c #57575454A6A6", +":. c #5B5B5757AAAA", +">. c #545451519B9B", +",. c #5A5A57579C9C", +"<. c #65656262A7A7", +"1. c #68686666A2A2", +"2. c #CACAC9C9E5E5", +"3. c #050504045151", +"4. c #080807075454", +"5. c #0A0A09095858", +"6. c #0C0C0A0A5858", +"7. c #10100E0E6262", +"8. c #0E0E0D0D5A5A", +"9. c #121211115D5D", +"0. c #131312125D5D", +"q. c #161615156161", +"w. c #171716166161", +"e. c #1A1A19196565", +"r. c #20201E1E7070", +"t. c #1E1E1D1D6969", +"y. c #2A2A29297676", +"u. c #2F2F2D2D7676", +"i. c #3A3A39398787", +"p. c #3A3A39398383", +"a. c #3F3F3E3E8888", +"s. c #414140408989", +"d. c #454543438D8D", +"f. c #444442428B8B", +"g. c #444443438C8C", +"h. c #434342428A8A", +"j. c #434341418888", +"k. c #434342428989", +"l. c #424241418787", +"z. c #434342428787", +"x. c #424241418585", +"c. c #41413F3F8181", +"v. c #414140408282", +"b. c #484846468D8D", +"n. c #494948489090", +"m. c #4B4B4A4A9191", +"M. c #4B4B49498E8E", +"N. c #525251519A9A", +"B. c #525251519999", +"V. c #565654549A9A", +"C. c #545453539494", +"Z. c #60605F5FA7A7", +"A. c #64646363ABAB", +"S. c #5A5A59599797", +"D. c #68686767ADAD", +"F. c #6C6C6B6BB2B2", +"G. c #5E5E5D5D9A9A", +"H. c #76767575BABA", +"J. c #78787777BBBB", +"K. c #76767474B5B5", +"L. c #7E7E7D7DBABA", +"P. c #A5A5A4A4D2D2", +"I. c #040404045252", +"U. c #070707075454", +"Y. c #070708085353", +"T. c #080808085454", +"R. c #0A0A0B0B5757", +"E. c #0E0E0E0E5A5A", +"W. c #111112125E5E", +"Q. c #111111115E5E", +"!. c #111111115D5D", +"~. c #111112125D5D", +"^. c #161616166868", +"/. c #151516166161", +"(. c #151515156161", +"). c #19191A1A6565", +"_. c #191919196565", +"`. c #1A1A1A1A6464", +"'. c #1D1D1E1E6969", +"]. c #1E1E1E1E6969", +"[. c #222222226D6D", +"{. c #272727277171", +"}. c #2B2B2C2C7676", +"|. c #2B2B2B2B7676", +" X c #2B2B2B2B7575", +".X c #303030307A7A", +"XX c #303030307979", +"oX c #353535357F7F", +"OX c #393939398383", +"+X c #3A3A3A3A8383", +"@X c #3F3F3F3F8787", +"#X c #434343438C8C", +"$X c #434344448C8C", +"%X c #424242428686", +"&X c #414141418484", +"*X c #484848489191", +"=X c #484849499090", +"-X c #4D4D4D4D9696", +";X c #515151519D9D", +":X c #4D4D4D4D9595", +">X c #515152529A9A", +",X c #515152529999", +"<X c #525252529A9A", +"1X c #525252529999", +"2X c #565657579E9E", +"3X c #575757579D9D", +"4X c #5B5B5B5BA2A2", +"5X c #5F5F6060A6A6", +"6X c #5F5F5F5FA6A6", +"7X c #63636464AAAA", +"8X c #64646464AAAA", +"9X c #67676767AEAE", +"0X c #67676868AEAE", +"qX c #68686868AEAE", +"wX c #6F6F6F6FB5B5", +"eX c #6C6C6C6CB1B1", +"rX c #73737373B8B8", +"tX c #82828282BEBE", +"yX c #86868686C2C2", +"uX c #89898989C4C4", +"iX c #98989898CBCB", +"pX c #A0A0A0A0CFCF", +"aX c #A9A9A9A9D5D5", +"sX c #B0B0B0B0D8D8", +"dX c #B8B8B8B8DDDD", +"fX c #BDBDBDBDE0E0", +"gX c #D9D9D9D9EDED", +"hX c #90909191C6C6", +"jX c #71718989BCBC", +"kX c #73738B8BBFBF", +"lX c #72728989BCBC", +"zX c #79799090C3C3", +"xX c #7E7E9595C7C7", +"cX c #81819898CACA", +"vX c #84849B9BCCCC", +"bX c #8C8CA3A3D4D4", +"nX c #71718A8ABCBC", +"mX c #73738B8BBDBD", +"MX c #75758D8DBFBF", +"NX c #74748C8CBEBE", +"BX c #76768E8EC0C0", +"VX c #7C7C9494C6C6", +"CX c #7B7B9393C4C4", +"ZX c #7F7F9797C9C9", +"AX c #82829A9ACBCB", +"SX c #85859E9ECECE", +"DX c #8888A0A0D1D1", +"FX c #87879F9FD0D0", +"GX c #8B8BA4A4D4D4", +"HX c #8B8BA3A3D4D4", +"JX c #8989A1A1D2D2", +"KX c #8D8DA5A5D6D6", +"LX c #8B8BA3A3D3D3", +"PX c #8E8EA6A6D6D6", +"IX c #8D8DA5A5D5D5", +"UX c gray100", +"YX c None", +/* pixels */ +"YXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X YX", +"X v.v.v.v.&Xl.z.k.&.d.%.$.@.O.+.] [ _ ` ) ( ^ L K ! G D V m m o ", +"X c.c.c.v.&Xx.z.f.f.d.%.$.#.O.+.X.[ _ ` ) ( / L K H F D V C n o ", +"X v.c.v.v.x.x.z.k.f.n.V.,.>.-.+.] [ _ ` ) ( ^ L K H G D V C h o ", +"X &Xv.&Xx.x.l.j.M.1.4 - - , 7 q J.H.K.j :.*.P L K H F S B C n o ", +"X x.&Xx.x.z.j.S., = = 1 } iXuXH.rXwXF.qX7XZ.;.o.J ! F S B m n o ", +"X x.l.z.%Xz.G.1 @ > 2.dXaXiXuXrXwXF.qX8X5X4X2X;X{ H F S V C n o ", +"X z.j.j.j.C.1 @ < gX2.fXaXpXuXwXeX9X7X5X4X2XN.:X*X_ D S Z m h o ", +"X k.k.h.b., O > gXgX2.dXaXiXyXF.D.A.Z.4X3X1X:Xn.g.a._ V B m N o ", +"X f.f.f.3 + = 2.2.2.fXsXpXhXtXD.8XZ.4X2X1X:X*X$X@Xp.i.W C n N o ", +"X d.&.%.% + 1 dXdXdXsXP.iXyXK.8X5X4X2X>X:X*Xg.a.+XoX.X..m n N o ", +"X %.=.5 % - P.} aXP.pXiXyXK.D.Z.4X3X1X-Xn.$X@X+XoX.X Xy.W h g o ", +"X $.$.: # PXIXGXGXLXJXFXFXSXvXAXcXZXxXVXCXzXzXBXMXkXmXnXjXh g o ", +"X #.@.* $ 7 yXuXyXtXL.K.D.6X4X2X1X:Xo g.a.OXoX.X|.{.[.t. .g v o ", +"X O.#.$ $ q H.rXwXF.0XA.6X4X2X1X:Xo $Xa.p.oX.X|.{.[.'.`.r.g b o ", +"X X.+.$ $ PXKXbXbXLXJXDXFXSXvXAXcXZXxXCXCXzXBXBXMXNXmXlXjXb c o ", +"X ] ] $ $ H.wXF.0X7X6X4X2X<X:Xo #Xa.+XoX.X|.{.[.].)./.~.Q.c z o ", +"X [ [ & & w F.qX7XZ.4X2X,X:Xo #Xa.+XoX.X}.{.[.'.e./.9.E.^.c z o ", +"X ' _ * & PXKXbXHXLXJXDXSXSXvXAXcXZXxXVXCXzXzXBXMXNXkXjXjXz x o ", +"X ` ` : & 2 8XZ.4X2XB.:X*Xg.@Xp.oX.X|.{.[.].).q.!.E.R.U.Y z f o ", +"X ) ) 5 & ; <.4X2X>X:Xo #Xa.+XoXXX|.{.[.t._.q.~.E.R.4.5.k x a o ", +"X ( ( I ; * 6 2X>X:X=X$X@X+XoX.X|.{.[.t.e./.W.E.R.Y.3. .z a a o ", +"X I ^ / 8 * : 0 :X*X#X@X+XoX.X|.{.[.'._.(.~.E.R.T.3.7.k x a p o ", +"X L L L ^ 2 * 3 m.$Xa.p.oX.X}.{.[.t.).(.~.E.6.T.3.I.R x a a y o ", +"X J K K K K 2 * 5 s.OXoX.X}.{.[.'._.(.9.8.R.4.3.I.Y x l a p t o ", +"X ~ H H ! ! ! 2 ; 5 U XX}.{.[.].e.(.W.E.R.U.3.7.R x l u u y t o ", +"X G F G G G Q Q 8 : 3 9 u.[.]._./.Q.E.R.T.6. .k x a a u t t t o ", +"X D S D S D S S S V 8 2 6 9 c.E w.0.| T Y k z z a a p t t i r o ", +"X A V B V V V B B m m n n h h g g g c z z z l l d p y t i r r o ", +"X m C C C C C C C n n n M N g g b c z z x a a a u y t t r r e o ", +"X n n n n n h h h N N g g v b s z z z x a p p u t t r r r e e o ", +"YXo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o YX" +}; diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm new file mode 100644 index 0000000000..e2b9379f3a --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm @@ -0,0 +1,287 @@ +/* XPM */ +static char *ProductIcon24[] = { +/* columns rows colors chars-per-pixel */ +"24 24 257 2", +" c black", +". c gray100", +"X c #69695A5AE8E8", +"o c #494949499191", +"O c #F1F1DFDFECEC", +"+ c #D7D7ACACCDCD", +"@ c #DFDFBBBBD6D6", +"# c #E2E2C4C4DBDB", +"$ c #CECE9C9CC4C4", +"% c #C4C48B8BBABA", +"& c #C2C28A8ABABA", +"* c #C4C48E8EBCBC", +"= c #BFBF8A8AB9B9", +"- c #EBEBD9D9E9E9", +"; c #BFBF8888B9B9", +": c #D8D8B9B9D6D6", +"> c #B9B98686B9B9", +", c #B8B88989B9B9", +"< c #BBBB9393BFBF", +"1 c #A9A97B7BB2B2", +"2 c #E4E4D4D4E7E7", +"3 c #C6C6AFAFCECE", +"4 c #A6A68080B6B6", +"5 c #A2A27E7EB4B4", +"6 c #9E9E7E7EB1B1", +"7 c #ABAB9090BBBB", +"8 c #B7B7A0A0C5C5", +"9 c #9D9D7C7CB2B2", +"0 c #AAAA8B8BBEBE", +"q c #AAAA9090BCBC", +"w c #8C8C6B6BABAB", +"e c #90907070B1B1", +"r c #C4C4B3B3D7D7", +"t c #CDCDBFBFDDDD", +"y c #EAEAE4E4F1F1", +"u c #88886A6AADAD", +"i c #9E9E8585C1C1", +"p c #84846A6AAFAF", +"a c #81816B6BAAAA", +"s c #D7D7CFCFE6E6", +"d c #81816969B1B1", +"f c #78786363A5A5", +"g c #6E6E5D5D9C9C", +"h c #717160609D9D", +"j c #83837474AAAA", +"k c #6A6A5757A3A3", +"l c #6E6E5E5EA0A0", +"z c #5E5E50509292", +"x c #88887B7BBCBC", +"c c #68685858ABAB", +"v c #5A5A4D4DA2A2", +"b c #7D7D7373B4B4", +"n c #5A5A4E4EA6A6", +"m c #5F5F56569595", +"M c #56564A4ABBBB", +"N c #56564949B9B9", +"B c #55554949B8B8", +"V c #53534848B3B3", +"C c #54544949B4B4", +"Z c #52524747B0B0", +"A c #52524747AFAF", +"S c #5B5B53539393", +"D c #3E3E36369797", +"F c #49494040A6A6", +"G c #48484040A5A5", +"H c #55554A4ABABA", +"J c #54544949B7B7", +"K c #53534949B4B4", +"L c #51514747AFAF", +"P c #52524848B1B1", +"I c #51514848B0B0", +"U c #51514848AEAE", +"Y c #51514747ADAD", +"T c #51514848ADAD", +"R c #4F4F4747ABAB", +"E c #50504747ABAB", +"W c #50504646A9A9", +"Q c #4F4F4646A8A8", +"! c #4E4E4646A7A7", +"~ c #4E4E4545A4A4", +"^ c #4D4D4545A4A4", +"/ c #4E4E4646A5A5", +"( c #4D4D4545A1A1", +") c #3D3D36367E7E", +"_ c #4B4B44449C9C", +"` c #2A2A25257F7F", +"' c #3E3E37379898", +"] c #474740409C9C", +"[ c #4D4D4646A4A4", +"{ c #4C4C4545A2A2", +"} c #4D4D4646A2A2", +"| c #4D4D4646A1A1", +" . c #4B4B45459F9F", +".. c #4C4C45459F9F", +"X. c #4C4C46469F9F", +"o. c #4B4B45459D9D", +"O. c #494943439898", +"+. c #494944449A9A", +"@. c #4A4A45459A9A", +"#. c #494944449898", +"$. c #484843439696", +"%. c #494944449797", +"&. c #484843439595", +"*. c #51514C4CA1A1", +"=. c #6B6B6767AEAE", +"-. c #95959191C9C9", +";. c #23231F1F7676", +":. c #21211E1E7070", +">. c #292925257F7F", +",. c #252521217070", +"<. c #242421216D6D", +"1. c #2B2B27278080", +"2. c #393935358C8C", +"3. c #444440409494", +"4. c #3B3B38388282", +"5. c #474743439494", +"6. c #484844449595", +"7. c #474743439393", +"8. c #474744449393", +"9. c #464643439191", +"0. c #454542428F8F", +"q. c #4A4A47479898", +"w. c #464643438F8F", +"e. c #454542428D8D", +"r. c #444441418B8B", +"t. c #484844449191", +"y. c #444441418989", +"u. c #494946469090", +"i. c #4C4C48489393", +"p. c #51514E4E9E9E", +"a. c #73737070B6B6", +"s. c #77777474BBBB", +"d. c #A0A09E9ED1D1", +"f. c #D6D6D5D5EBEB", +"g. c #0E0E0D0D5A5A", +"h. c #11110F0F5E5E", +"j. c #121211115E5E", +"k. c #131312125F5F", +"l. c #171716166363", +"z. c #1D1D1B1B6868", +"x. c #1D1D1C1C6868", +"c. c #222221216E6E", +"v. c #222221216D6D", +"b. c #282827277474", +"n. c #282827277373", +"m. c #292928287373", +"M. c #2F2F2E2E7979", +"N. c #353534347F7F", +"B. c #363635358181", +"V. c #3C3C3B3B8585", +"C. c #424241418C8C", +"Z. c #424241418B8B", +"A. c #444442428B8B", +"S. c #434341418989", +"D. c #434342428989", +"F. c #424241418787", +"G. c #414140408484", +"H. c #474745458D8D", +"J. c #434342428787", +"K. c #424241418585", +"L. c #414140408282", +"P. c #494948489191", +"I. c #4F4F4E4E9797", +"U. c #59595757A6A6", +"Y. c #5F5F5D5DA4A4", +"T. c #6C6C6B6BB3B3", +"R. c #7C7C7B7BB9B9", +"E. c #A8A8A7A7D3D3", +"W. c #0D0D0D0D5A5A", +"Q. c #1F1F1F1F6C6C", +"!. c #222222226E6E", +"~. c #3B3B3B3B8585", +"^. c #414141418C8C", +"/. c #414141418B8B", +"(. c #424242428B8B", +"). c #484848489292", +"_. c #404040408181", +"`. c #4E4E4E4E9898", +"'. c #555555559E9E", +"]. c #555555559D9D", +"[. c #5B5B5B5BA3A3", +"{. c #5C5C5C5CA3A3", +"}. c #61616161A9A9", +"|. c #66666666AEAE", +" X c #66666666ADAD", +".X c #6B6B6B6BB2B2", +"XX c #70707070B7B7", +"oX c #6A6A6A6AADAD", +"OX c #74747474BBBB", +"+X c #89898989C2C2", +"@X c #90909090C8C8", +"#X c #8F8F8F8FC6C6", +"$X c #92929292C6C6", +"%X c #9F9F9F9FCFCF", +"&X c #A5A5A5A5D2D2", +"*X c #B5B5B5B5DBDB", +"=X c #B8B8B8B8DEDE", +"-X c #B7B7B7B7DCDC", +";X c #BBBBBBBBDEDE", +":X c #BDBDBDBDDFDF", +">X c #C9C9C9C9E5E5", +",X c #D1D1D1D1EAEA", +"<X c #7C7C7D7DBABA", +"1X c #89898A8AC7C7", +"2X c #8F8F9090C7C7", +"3X c #A3A3A4A4D3D3", +"4X c #A2A2B5B5DEDE", +"5X c #ADADBDBDE1E1", +"6X c #B9B9C7C7E5E5", +"7X c #BABAC8C8E6E6", +"8X c #8E8EA6A6D6D6", +"9X c #9090A7A7D7D7", +"0X c #9191A9A9D7D7", +"qX c #9292A9A9D8D8", +"wX c #9494ABABD8D8", +"eX c #9898AEAED9D9", +"rX c #9B9BB0B0DADA", +"tX c #9E9EB3B3DCDC", +"yX c #A1A1B5B5DDDD", +"uX c #A5A5B8B8DEDE", +"iX c #A8A8BBBBE0E0", +"pX c #ACACBEBEE1E1", +"aX c #AFAFC0C0E3E3", +"sX c #B3B3C3C3E4E4", +"dX c #B2B2C2C2E3E3", +"fX c #B5B5C5C5E5E5", +"gX c #B8B8C7C7E6E6", +"hX c #B6B6C5C5E4E4", +"jX c #9797AEAED9D9", +"kX c #A1A1B6B6DDDD", +"lX c #A8A8BBBBDFDF", +"zX c gray100", +"xX c black", +"cX c black", +"vX c black", +"bX c black", +"nX c black", +"mX c black", +"MX c black", +"NX c black", +"BX c black", +"VX c black", +"CX c black", +"ZX c black", +"AX c black", +"SX c black", +"DX c black", +"FX c black", +"GX c black", +"HX c black", +"JX c black", +"KX c black", +"LX c black", +"PX c black", +"IX c black", +"UX c black", +"YX c None", +/* pixels */ +"YXX X X X X X X X X X X X X X X X X X X X X X YX", +"X _._.L.G.K.F.D.A.e.0.9.&.$.%.+._ ..{ ^ ! W E o ", +"X L.L.L.G.F.F.D.r.e.0.9.7.&.O.@.o. .{ ~ ! Q E o ", +"X L.G.G.K.F.S.y.r.e.w.9.5.$.+.@.o...( ~ ! W E o ", +"X G.K.K.F.J.D.h 6 0 i x s.a.=.U.*...} ~ ! W E o ", +"X K.F.F.F.S 7 : r d.1XOXXX.X|.}.[.p.| / ! W E o ", +"X F.F.F.m 3 - s =X3X@XXXT. X}.[.].I.q.{ Q E T o ", +"X S.D.H.8 O y ,X;X&X2X.X|.}.[.].I.P.C.3.Q E Y o ", +"X A.r.j # 2 f.>X*X%X+X|.}.[.].I.P.^.~.B.] E Y o ", +"X e.u.q @ t :X-XE.$X<X}.[.].`.P.Z.V.N.M.2.Y L o ", +"X 0.i.< + 8X8XqXwXeXrXtX4XuXlXpXaXsXfXgX7XY A o ", +"X 9.t.* $ -.#X+XR.oX{.'.`.P.(.~.N.M.m.c.Q.T Z o ", +"X 8.7.; % 8X9X0XwXeXrXtXyXuXiXpXaXdXfXgX7XL Z o ", +"X 6.&.1 & b X}.[.'.I.P./.~.N.M.n.!.x.l.:.I P o ", +"X #.#.w = 8X9XqXwXjXrXtXkXuXiX5XaXsXhX6X7XP V o ", +"X +.+.k > 5 Y.].I.)./.~.N.M.b.v.x.l.k.h.' V C o ", +"X o.o.o.u , a I.).Z.V.N.M.n.c.z.l.j.W.` P V C o ", +"X .. .X.v e 4 l ^.V.N.M.m.!.x.l.j.g.;.F V C J o ", +"X ( | ( ( n p 9 g 4.M.n.c.x.l.j.h.>.G V K C J o ", +"X ~ [ [ ^ / / c d f z ) <.z.,.1.D P V C C B B o ", +"X ! Q ! Q Q Q Q W E E Y T A Z P V V K C J B B o ", +"X Q W Q W R W E E T T T L Z P V V K J J J B N o ", +"X R E E E E E Y Y U L Z P P P C V J J B B H M o ", +"YXo o o o o o o o o o o o o o o o o o o o o o YX" +}; diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm new file mode 100644 index 0000000000..3f6b21f428 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm @@ -0,0 +1,279 @@ +/* XPM */ +static char *ProductIcon16[] = { +/* columns rows colors chars-per-pixel */ +"16 16 257 2", +" c black", +". c gray100", +"X c #E2E2C0C0D9D9", +"o c #EDEDD9D9E8E8", +"O c #D5D5ABABCDCD", +"+ c #E2E2C3C3DCDC", +"@ c #C5C58E8EBCBC", +"# c #D4D4ABABCDCD", +"$ c #CACA9F9FC6C6", +"% c #D6D6B4B4D3D3", +"& c #CACAA0A0C8C8", +"* c #C6C69D9DC6C6", +"= c #C5C59F9FC8C8", +"- c #CCCCACACCECE", +"; c #CCCCB0B0D3D3", +": c #A6A68383B3B3", +"> c #BABA9A9AC6C6", +", c #B7B79A9AC2C2", +"< c #E3E3D5D5E9E9", +"1 c #B0B08E8EC0C0", +"2 c #9F9F8080B8B8", +"3 c #AFAF9898C1C1", +"4 c #DBDBCFCFE5E5", +"5 c #96967878B2B2", +"6 c #9A9A7E7EBABA", +"7 c #8E8E7878AFAF", +"8 c #91917F7FBDBD", +"9 c #D3D3CCCCE4E4", +"0 c #535348488B8B", +"q c #69695A5AE8E8", +"w c #55554949B9B9", +"e c #55554949B8B8", +"r c #54544848B6B6", +"t c #53534848B4B4", +"y c #54544848B4B4", +"u c #53534848B3B3", +"i c #53534848B2B2", +"p c #52524747AFAF", +"a c #53534848B1B1", +"s c #54544949B8B8", +"d c #54544949B6B6", +"f c #52524848B3B3", +"g c #52524848B2B2", +"h c #53534949B3B3", +"j c #52524848B1B1", +"k c #52524848B0B0", +"l c #51514747AEAE", +"z c #52524848AFAF", +"x c #51514848AEAE", +"c c #51514747ADAD", +"v c #51514747ACAC", +"b c #4F4F4646AAAA", +"n c #51514848ADAD", +"m c #50504747ABAB", +"M c #50504747AAAA", +"N c #4F4F4646A8A8", +"B c #50504747A9A9", +"V c #4E4E4646A7A7", +"C c #4E4E4646A6A6", +"Z c #4F4F4646A6A6", +"A c #4F4F4747A7A7", +"S c #4D4D4545A3A3", +"D c #4D4D4545A2A2", +"F c #4C4C45459E9E", +"G c #74746E6EB3B3", +"H c #2E2E29298383", +"J c #383832329090", +"K c #464640409999", +"L c #4D4D4646A2A2", +"P c #4E4E4747A3A3", +"I c #4B4B45459F9F", +"U c #4B4B45459E9E", +"Y c #4C4C46469F9F", +"T c #4A4A44449B9B", +"R c #4A4A44449A9A", +"E c #494943439797", +"W c #494944449797", +"Q c #484843439494", +"! c #78787474B8B8", +"~ c #272724247878", +"^ c #2D2D2A2A7575", +"/ c #484844449797", +"( c #474743439393", +") c #454542429090", +"_ c #4B4B48489A9A", +"` c #464643438F8F", +"' c #464643438E8E", +"] c #454542428C8C", +"[ c #51514D4DA0A0", +"{ c #5C5C5959A5A5", +"} c #535350509090", +"| c #C8C8C7C7E3E3", +" . c #121211115D5D", +".. c #1A1A19196565", +"X. c #242422226D6D", +"o. c #3F3F3E3E8888", +"O. c #444442428D8D", +"+. c #444442428989", +"@. c #424241418787", +"#. c #454543438A8A", +"$. c #434342428888", +"%. c #424241418686", +"&. c #414140408484", +"*. c #414140408383", +"=. c #424240408383", +"-. c #414140408282", +";. c #474746468D8D", +":. c #464644448989", +">. c #525251519999", +",. c #64646363AAAA", +"<. c #61615F5FA2A2", +"1. c #6E6E6C6CB2B2", +"2. c #A5A5A4A4D3D3", +"3. c #B0B0AFAFD6D6", +"4. c #111112125D5D", +"5. c #19191A1A6565", +"6. c #1E1E1E1E6C6C", +"7. c #222222226D6D", +"8. c #2B2B2B2B7676", +"9. c #2B2B2B2B7575", +"0. c #2B2B2C2C7575", +"q. c #343435357F7F", +"w. c #343435357E7E", +"e. c #353535357F7F", +"r. c #3E3E3E3E8888", +"t. c #3E3E3E3E8787", +"y. c #414141418484", +"u. c #404040408282", +"i. c #484849499191", +"p. c #494949499191", +"a. c #484848489090", +"s. c #484849499090", +"d. c #404040408080", +"f. c #525252529A9A", +"g. c #525252529999", +"h. c #5B5B5B5BA3A3", +"j. c #5B5B5B5BA2A2", +"k. c #64646464ABAB", +"l. c #63636464AAAA", +"z. c #6B6B6C6CB2B2", +"x. c #72727373B9B9", +"c. c #71717171A4A4", +"v. c #78787878ABAB", +"b. c #7F7F7F7FB1B1", +"n. c #8C8C8C8CBEBE", +"m. c #A5A5A5A5D2D2", +"M. c #C9C9C9C9E5E5", +"N. c #85858686B7B7", +"B. c #91919292C4C4", +"V. c #71718989BCBC", +"C. c #73738B8BBEBE", +"Z. c #75758D8DC0C0", +"A. c #78789090C3C3", +"S. c #7A7A9292C5C5", +"D. c #71718A8ABDBD", +"F. c #76768E8EC0C0", +"G. c #78789090C2C2", +"H. c #7B7B9393C5C5", +"J. c #7D7D9595C7C7", +"K. c #80809999CACA", +"L. c #7E7E9696C7C7", +"P. c #83839B9BCDCD", +"I. c #83839B9BCCCC", +"U. c #86869E9ECFCF", +"Y. c #8888A1A1D1D1", +"T. c #8A8AA2A2D3D3", +"R. c #8989A1A1D1D1", +"E. c #8B8BA3A3D3D3", +"W. c gray100", +"Q. c black", +"!. c black", +"~. c black", +"^. c black", +"/. c black", +"(. c black", +"). c black", +"_. c black", +"`. c black", +"'. c black", +"]. c black", +"[. c black", +"{. c black", +"}. c black", +"|. c black", +" X c black", +".X c black", +"XX c black", +"oX c black", +"OX c black", +"+X c black", +"@X c black", +"#X c black", +"$X c black", +"%X c black", +"&X c black", +"*X c black", +"=X c black", +"-X c black", +";X c black", +":X c black", +">X c black", +",X c black", +"<X c black", +"1X c black", +"2X c black", +"3X c black", +"4X c black", +"5X c black", +"6X c black", +"7X c black", +"8X c black", +"9X c black", +"0X c black", +"qX c black", +"wX c black", +"eX c black", +"rX c black", +"tX c black", +"yX c black", +"uX c black", +"iX c black", +"pX c black", +"aX c black", +"sX c black", +"dX c black", +"fX c black", +"gX c black", +"hX c black", +"jX c black", +"kX c black", +"lX c black", +"zX c black", +"xX c black", +"cX c black", +"vX c black", +"bX c black", +"nX c black", +"mX c black", +"MX c black", +"NX c black", +"BX c black", +"VX c black", +"CX c black", +"ZX c black", +"AX c black", +"SX c black", +"DX c black", +"FX c black", +"GX c black", +"HX c black", +"JX c black", +"KX c black", +"LX c black", +"PX c black", +"IX c black", +"UX c black", +"YX c None", +/* pixels */ +"YXq q q q q q q q q q q q q q YX", +"q d.-.y.%.+.O.` ( E R U D C B p.", +"q u.*.&.$.#.] ) Q W T F L V M p.", +"q =.y.} , % ; 8 ! 1.{ [ S Z b p.", +"q @.:.- o 4 2.x.z.,.j.>._ A m p.", +"q +.: X < M.m.z.l.j.g.s.r.K v p.", +"q ' $ + 9 | 3.B.n.N.b.v.c.<.n p.", +"q ` O T.Y.U.P.K.L.S.G.F.C.D.l p.", +"q ( # @ G k.h.g.i.t.e.9.7.6.z p.", +"q / * E.R.U.I.K.J.H.A.Z.C.V.a p.", +"q T 2 & 5 f.a.o.q.8.7...4.J u p.", +"q I Y 1 = 7 ;.w.0.7.5. .H f y p.", +"q L D P 6 > 3 0 ^ X.~ J i t d p.", +"q C C V A N M m n p k g y r e p.", +"q M b M m m c x p j h y d s w p.", +"YXp.p.p.p.p.p.p.p.p.p.p.p.p.p.YX" +}; diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc Binary files differnew file mode 100755 index 0000000000..b88ff49e8e --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini new file mode 100644 index 0000000000..cfa715e5a8 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini @@ -0,0 +1,40 @@ +############################################################################### +# 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. +############################################################################### +-startup +plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar +--launcher.library +plugins/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731 +-vmargs +-Xms40m +-Xmx256m +-XX:MaxPermSize=256m +-Dosgi.requiredJavaVersion=1.5 +-Declipse.consoleLog=true + +#=============================================== +# SSL trust store configuration options. +#=============================================== + +# Uncomment lines below to specify custom truststore for server SSL +# certificate verification, eg when using self-signed server certs. +# +#-Djavax.net.ssl.trustStore=<path.to.truststore> +#-Djavax.net.ssl.trustStorePassword=<truststore.password> + + diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini index d00d756706..a61bea2fa8 100644 --- a/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini +++ b/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini @@ -45,4 +45,5 @@ org.eclipse.ui, \ org.eclipse.ui.forms, \
org.eclipse.ui.workbench, \
org.eclipse.equinox.launcher, \
-org.eclipse.equinox.launcher.win32.win32.x86
+org.eclipse.equinox.launcher.win32.win32.x86, \ +org.apache.commons.codec
diff --git a/qpid/java/systests/build.xml b/qpid/java/systests/build.xml index 4eb7275e73..11af9c21bf 100644 --- a/qpid/java/systests/build.xml +++ b/qpid/java/systests/build.xml @@ -20,7 +20,7 @@ nn - or more contributor license agreements. See the NOTICE file --> <project name="System Tests" default="build"> - <property name="module.depends" value="client broker common junit-toolkit"/> + <property name="module.depends" value="client broker broker/test common junit-toolkit"/> <property name="module.test.src" location="src/main/java"/> <property name="module.test.excludes" value="**/TTLTest.java,**/DropInTest.java,**/TestClientControlledTest.java"/> diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java index 4c1d5ee9c1..ffec6c7a29 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java @@ -106,6 +106,14 @@ public class MessageListenerTest extends QpidTestCase implements MessageListener } } + public void testSynchronousRecieveNoWait() throws Exception + { + for (int msg = 0; msg < MSG_COUNT; msg++) + { + assertTrue(_consumer.receiveNoWait() != null); + } + } + public void testAsynchronousRecieve() throws Exception { _consumer.setMessageListener(this); diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java index ea0bae7a56..ba7a4bb19c 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java @@ -59,10 +59,6 @@ public class MultipleJCAProviderRegistrationTest extends QpidTestCase } ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(defaultaclConfigFile); - - // This is a bit evil it should be updated with QPID-1103 - config.getConfiguration().setProperty("management.enabled", "false"); - startBroker(); } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java new file mode 100644 index 0000000000..dd9b35c475 --- /dev/null +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java @@ -0,0 +1,179 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.queue; + +import org.apache.qpid.AMQException; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.test.utils.QpidTestCase; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.Session; +import javax.naming.NamingException; +import java.util.HashMap; +import java.util.Map; + +/** The purpose of this set of tests is to ensure */ +public class QueueCreateTest extends QpidTestCase +{ + private Connection _connection; + private AMQSession _session; + private int _queueCount = 0; + + public void setUp() throws Exception + { + _connection = getConnection(); + + _session = (AMQSession) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + } + + private void testQueueWithArguments(Map<String, Object> arguments) throws AMQException + { + _session.createQueue(new AMQShortString(this.getName() + (_queueCount++)), false, false, false, arguments); + } + + public void testCreateNoArguments() throws AMQException, FailoverException + { + Map<String, Object> arguments = null; + testQueueWithArguments(arguments); + } + + public void testCreatePriorityInt() throws AMQException, FailoverException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + //Ensure we can call createQueue with a priority int value + arguments.put(AMQQueueFactory.X_QPID_PRIORITIES.toString(), 7); + testQueueWithArguments(arguments); + } + + /** + * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716 + * + * @throws AMQException + * @throws FailoverException + */ + public void testCreatePriorityString() throws AMQException, FailoverException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + //Ensure we can call createQueue with a priority value that is not an int + arguments.put(AMQQueueFactory.X_QPID_PRIORITIES.toString(), "seven"); + try + { + + testQueueWithArguments(arguments); + fail("Invalid Property value still succeeds."); + } + catch (Exception e) + { + assertTrue("Incorrect error message thrown:" + e.getMessage(), + e.getMessage().startsWith("Queue create request with non integer value for :x-qpid-priorities=seven")); + } + } + + public void testCreateFlowToDiskValid() throws AMQException, FailoverException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + //Ensure we can call createQueue with a priority int value + arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK); + arguments.put(AMQQueueFactory.QPID_MAX_SIZE.toString(), 100); + testQueueWithArguments(arguments); + } + + /** + * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716 + * @throws AMQException + * @throws FailoverException + */ + public void testCreateFlowToDiskValidNoSize() throws AMQException, FailoverException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + //Ensure we can call createQueue with a priority int value + arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK); + try + { + testQueueWithArguments(arguments); + } + catch (AMQException e) + { + assertTrue("Incorrect Error throw:" + e.getMessage() + + ":expecting:Queue create request with no qpid.max_size value", + e.getMessage().contains("Queue create request with no qpid.max_size value")); + } + } + + /** + * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716 + * @throws AMQException + * @throws FailoverException + */ + public void testCreateFlowToDiskInvalid() throws AMQException, FailoverException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), "infinite"); + try + { + testQueueWithArguments(arguments); + fail("Invalid Property value still succeeds."); + } + catch (Exception e) + { + //Check error is correct + assertTrue("Incorrect error message thrown:" + e.getMessage(), + e.getMessage().startsWith("Queue create request with unknown Policy Type:infinite")); + } + + } + + /** + * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716 + * @throws AMQException + * @throws FailoverException + */ + public void testCreateFlowToDiskInvalidSize() throws AMQException, FailoverException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK); + arguments.put(AMQQueueFactory.QPID_MAX_SIZE.toString(), -1); + try + { + testQueueWithArguments(arguments); + fail("Invalid Property value still succeeds."); + } + catch (Exception e) + { + //Check error is correct + assertTrue("Incorrect error message thrown:" + e.getMessage(), + e.getMessage().startsWith("Queue create request with negative size:-1")); + } + + } + + +} diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java index 289ca0b1b0..5970d105eb 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java @@ -70,7 +70,9 @@ public class TimeToLiveTest extends QpidTestCase producerConnection.start(); - Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); + // Move to a Transacted session to ensure that all messages have been delivered to broker before + // we start waiting for TTL + Session producerSession = producerConnection.createSession(true, Session.SESSION_TRANSACTED); MessageProducer producer = producerSession.createProducer(queue); @@ -89,12 +91,15 @@ public class TimeToLiveTest extends QpidTestCase producer.setTimeToLive(0L); producer.send(nextMessage(String.valueOf(msg), false, producerSession, producer)); + producerSession.commit(); + consumer = clientSession.createConsumer(queue); // Ensure we sleep the required amount of time. ReentrantLock waitLock = new ReentrantLock(); Condition wait = waitLock.newCondition(); final long MILLIS = 1000000L; + long waitTime = TIME_TO_LIVE * MILLIS; while (waitTime > 0) { diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java index e6c9f43ffb..5d0e7f9186 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java @@ -61,12 +61,7 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener } ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(defaultaclConfigFile); - - // This is a bit evil it should be updated with QPID-1103 - config.getConfiguration().setProperty("management.enabled", "false"); - ApplicationRegistry.initialise(config, 1); - TransportConnection.createVMBroker(1); } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java index 256491194d..c7c2c8b292 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java @@ -27,6 +27,7 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.MessageMetaData; @@ -49,38 +50,38 @@ public class SlowMessageStore implements TransactionLog, RoutingTable private static final String POST = "post"; private String DEFAULT_DELAY = "default"; - public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception + public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception { - _logger.info("Starting SlowMessageStore on Virtualhost:" + virtualHost.getName()); - Configuration delays = config.subset(base + "." + DELAYS); + _logger.warn("Starting SlowMessageStore on Virtualhost:" + virtualHost.getName()); + Configuration delays = config.getStoreConfiguration().subset(DELAYS); configureDelays(delays); - String transactionLogClass = config.getString(base + ".store.class"); + String transactionLogClass = config.getTransactionLogClass(); if (delays.containsKey(DEFAULT_DELAY)) { _defaultDelay = delays.getLong(DEFAULT_DELAY); + _logger.warn("Delay is:" + _defaultDelay); } if (transactionLogClass != null) { Class clazz = Class.forName(transactionLogClass); + if (clazz != this.getClass()) + { - Object o = clazz.newInstance(); + Object o = clazz.newInstance(); - if (!(o instanceof TransactionLog)) - { - throw new ClassCastException("TransactionLog class must implement " + TransactionLog.class + ". Class " + clazz + - " does not."); + if (!(o instanceof TransactionLog)) + { + throw new ClassCastException("TransactionLog class must implement " + TransactionLog.class + ". Class " + clazz + + " does not."); + } + _realTransactionLog = (TransactionLog) o; } - _realTransactionLog = (TransactionLog) o; - _realTransactionLog.configure(virtualHost, base , config); - } - else - { - _realTransactionLog.configure(virtualHost, base , config); } + _realTransactionLog.configure(virtualHost, base , config); } private void configureDelays(Configuration config) @@ -157,13 +158,6 @@ public class SlowMessageStore implements TransactionLog, RoutingTable doPostDelay("close"); } - public void removeMessage(StoreContext storeContext, Long messageId) throws AMQException - { - doPreDelay("removeMessage"); - _realTransactionLog.removeMessage(storeContext, messageId); - doPostDelay("removeMessage"); - } - public void createExchange(Exchange exchange) throws AMQException { doPreDelay("createExchange"); diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java new file mode 100644 index 0000000000..02965b5ab7 --- /dev/null +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java @@ -0,0 +1,69 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.test.client; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.server.queue.AMQQueueFactory; + +import javax.jms.JMSException; +import javax.jms.Connection; +import javax.jms.Session; +import java.util.Map; +import java.util.HashMap; + +public class QueueBrowsingFlowToDiskTest extends QueueBrowserAutoAckTest +{ + @Override + protected void sendMessages(Connection producerConnection, int messageSendCount) throws JMSException + { + try + { + setupFlowToDisk(producerConnection, messageSendCount , this.getName()); + } + catch (AMQException e) + { + fail("Unable to setup Flow to disk:"+e.getMessage()); + } + + super.sendMessages(producerConnection,messageSendCount); + } + + private void setupFlowToDisk(Connection producerConnection, int messages, String name) + throws AMQException, JMSException + { + Map<String, Object> arguments = new HashMap<String, Object>(); + + //Ensure we can call createQueue with a priority int value + arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK); + // each message in the QBAAT is around 9-10 bytes each so only give space for half + arguments.put(AMQQueueFactory.QPID_MAX_SIZE.toString(), 5 * messages); + + //Create the FlowToDisk Queue + ((AMQSession) producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE)). + createQueue(new AMQShortString(name), false, false, false, arguments); + + // Get a JMS reference to the new queue + _queue = _clientSession.createQueue(name); + } + +} diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java index 3a1fb50725..b7ae911a49 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java @@ -21,36 +21,37 @@ package org.apache.qpid.test.client.failover; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQConnectionFactory; -import org.apache.qpid.client.AMQConnectionURL; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.jms.ConnectionListener; -import org.apache.qpid.jms.ConnectionURL; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.test.utils.FailoverBaseCase; -import org.apache.log4j.Logger; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; +import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; -import javax.jms.Queue; import javax.naming.NamingException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; + +import org.apache.log4j.Logger; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQSession_0_10; +import org.apache.qpid.jms.BrokerDetails; +import org.apache.qpid.jms.ConnectionListener; +import org.apache.qpid.jms.ConnectionURL; +import org.apache.qpid.test.utils.FailoverBaseCase; public class FailoverTest extends FailoverBaseCase implements ConnectionListener { private static final Logger _logger = Logger.getLogger(FailoverTest.class); private static final String QUEUE = "queue"; - private static final int NUM_MESSAGES = 10; - private Connection connnection; + private static final int DEFAULT_NUM_MESSAGES = 10; + private static final int DEFAULT_SEED = 20080921; + protected int numMessages = 0; + protected Connection connection; private Session producerSession; private Queue queue; private MessageProducer producer; @@ -61,26 +62,32 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener private CountDownLatch failoverComplete; private static final long DEFAULT_FAILOVER_TIME = 10000L; private boolean CLUSTERED = Boolean.getBoolean("profile.clustered"); - + private int seed; + private Random rand; + @Override protected void setUp() throws Exception { super.setUp(); - - connnection = getConnection(); - ((AMQConnection) connnection).setConnectionListener(this); - connnection.start(); + + numMessages = Integer.getInteger("profile.failoverMsgCount",DEFAULT_NUM_MESSAGES); + seed = Integer.getInteger("profile.failoverRandomSeed",DEFAULT_SEED); + rand = new Random(seed); + + connection = getConnection(); + ((AMQConnection) connection).setConnectionListener(this); + connection.start(); failoverComplete = new CountDownLatch(1); } - private void init(boolean transacted, int mode) throws JMSException, NamingException + protected void init(boolean transacted, int mode) throws JMSException, NamingException { queue = (Queue) getInitialContext().lookup(QUEUE); - consumerSession = connnection.createSession(transacted, mode); + consumerSession = connection.createSession(transacted, mode); consumer = consumerSession.createConsumer(queue); - producerSession = connnection.createSession(transacted, mode); + producerSession = connection.createSession(transacted, mode); producer = producerSession.createProducer(queue); } @@ -89,7 +96,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener { try { - connnection.close(); + connection.close(); } catch (Exception e) { @@ -99,26 +106,46 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener super.tearDown(); } - private void consumeMessages(int toConsume, boolean transacted) throws JMSException + private void consumeMessages(int startIndex,int endIndex, boolean transacted) throws JMSException { Message msg; - for (int i = 0; i < toConsume; i++) + _logger.debug("**************** Receive (Start: " + startIndex + ", End:" + endIndex + ")***********************"); + + for (int i = startIndex; i < endIndex; i++) { - msg = consumer.receive(1000); + msg = consumer.receive(1000); assertNotNull("Message " + i + " was null!", msg); - assertEquals("message " + i, ((TextMessage) msg).getText()); + + _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + _logger.debug("Received : " + ((TextMessage) msg).getText()); + _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + + assertEquals("Invalid message order","message " + i, ((TextMessage) msg).getText()); + } - if (transacted) { + _logger.debug("***********************************************************"); + + if (transacted) + { consumerSession.commit(); } } - private void sendMessages(int totalMessages, boolean transacted) throws JMSException + private void sendMessages(int startIndex,int endIndex, boolean transacted) throws JMSException { - for (int i = 0; i < totalMessages; i++) - { + _logger.debug("**************** Send (Start: " + startIndex + ", End:" + endIndex + ")***********************"); + + for (int i = startIndex; i < endIndex; i++) + { producer.send(producerSession.createTextMessage("message " + i)); + + _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + _logger.debug("Sending message"+i); + _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); } + + _logger.debug("***********************************************************"); + if (transacted) { producerSession.commit(); @@ -127,47 +154,93 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener public void testP2PFailover() throws Exception { - testP2PFailover(NUM_MESSAGES, true, false); + testP2PFailover(numMessages, true,true, false); } - public void testP2PFailoverWithMessagesLeft() throws Exception + public void testP2PFailoverWithMessagesLeftToConsumeAndProduce() throws Exception { - testP2PFailover(NUM_MESSAGES, false, false); + if (CLUSTERED) + { + testP2PFailover(numMessages, false,false, false); + } } - + + public void testP2PFailoverWithMessagesLeftToConsume() throws Exception + { + if (CLUSTERED) + { + testP2PFailover(numMessages, false,true, false); + } + } + public void testP2PFailoverTransacted() throws Exception { - testP2PFailover(NUM_MESSAGES, true, false); + testP2PFailover(numMessages, true,true, false); } - private void testP2PFailover(int totalMessages, boolean consumeAll, boolean transacted) throws JMSException, NamingException + public void testP2PFailoverTransactedWithMessagesLeftToConsumeAndProduce() throws Exception { - Message msg = null; + // Currently the cluster does not support transactions that span a failover + if (CLUSTERED) + { + testP2PFailover(numMessages, false,false, false); + } + } + + private void testP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException + { init(transacted, Session.AUTO_ACKNOWLEDGE); - sendMessages(totalMessages, transacted); + runP2PFailover(totalMessages,consumeAll, produceAll , transacted); + } + + protected void runP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException + { + Message msg = null; + int toProduce = totalMessages; + + _logger.debug("==================================================================="); + _logger.debug("Total messages used for the test " + totalMessages + " messages"); + _logger.debug("==================================================================="); + + if (!produceAll) + { + toProduce = totalMessages - rand.nextInt(totalMessages); + } + + _logger.debug("=================="); + _logger.debug("Sending " + toProduce + " messages"); + _logger.debug("=================="); + + sendMessages(0,toProduce, transacted); // Consume some messages - int toConsume = totalMessages; + int toConsume = toProduce; if (!consumeAll) { - toConsume = totalMessages / 2; + toConsume = toProduce - rand.nextInt(toProduce); } + + consumeMessages(0,toConsume, transacted); - consumeMessages(toConsume, transacted); - + _logger.debug("=================="); + _logger.debug("Consuming " + toConsume + " messages"); + _logger.debug("=================="); + _logger.info("Failing over"); causeFailure(DEFAULT_FAILOVER_TIME); - if (!CLUSTERED) - { - msg = consumer.receive(500); - assertNull("Should not have received message from new broker!", msg); - } - - // Check that messages still sent / received - sendMessages(totalMessages, transacted); - consumeMessages(totalMessages, transacted); + // Check that you produce and consume the rest of messages. + _logger.debug("=================="); + _logger.debug("Sending " + (totalMessages-toProduce) + " messages"); + _logger.debug("=================="); + + sendMessages(toProduce,totalMessages, transacted); + consumeMessages(toConsume,totalMessages, transacted); + + _logger.debug("=================="); + _logger.debug("Consuming " + (totalMessages-toConsume) + " messages"); + _logger.debug("=================="); } private void causeFailure(long delay) @@ -188,11 +261,11 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener //evil ignore IE. } } - + public void testClientAckFailover() throws Exception { init(false, Session.CLIENT_ACKNOWLEDGE); - sendMessages(1, false); + sendMessages(0,1, false); Message msg = consumer.receive(); assertNotNull("Expected msgs not received", msg); @@ -208,7 +281,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener failure = e; } assertNotNull("Exception should be thrown", failure); - } + } /** * The client used to have a fixed timeout of 4 minutes after which failover would no longer work. @@ -216,6 +289,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener * * @throws Exception if something unexpected occurs in the test. */ + public void test4MinuteFailover() throws Exception { ConnectionURL connectionURL = getConnectionFactory().getConnectionURL(); @@ -228,12 +302,12 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener details.setProperty(BrokerDetails.OPTIONS_RETRY, String.valueOf(RETRIES)); details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, String.valueOf(DELAY)); - connnection = new AMQConnection(connectionURL, null); + connection = new AMQConnection(connectionURL, null); - ((AMQConnection) connnection).setConnectionListener(this); + ((AMQConnection) connection).setConnectionListener(this); //Start the connection - connnection.start(); + connection.start(); long FAILOVER_DELAY = (RETRIES * DELAY); @@ -247,6 +321,51 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener assertTrue("Failover did not take long enough", System.nanoTime() > failTime); } + + /** + * The idea is to run a failover test in a loop by failing over + * to the other broker each time. + */ + public void testFailoverInALoop() throws Exception + { + if (!CLUSTERED) + { + return; + } + + int iterations = Integer.getInteger("profile.failoverIterations",0); + boolean b = true; + int failingPort = getFailingPort(); + init(false, Session.AUTO_ACKNOWLEDGE); + for (int i=0; i < iterations; i++) + { + _logger.debug("==================================================================="); + _logger.debug("Failover In a loop : iteration number " + i); + _logger.debug("==================================================================="); + + runP2PFailover(numMessages, false,false, false); + startBroker(failingPort); + if (b) + { + failingPort = getFailingPort()-1; + b = false; + } + else + { + failingPort = getFailingPort()+1; + b = true; + } + setFailingPort(failingPort); + } + //To prevent any failover logic being initiaed when we shutdown the brokers. + connection.close(); + + // Shutdown the brokers + stopBroker(getFailingPort()); + stopBroker(b?getFailingPort()+1 : getFailingPort()-1); + + } + public void bytesSent(long count) { } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java new file mode 100644 index 0000000000..001a40988b --- /dev/null +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java @@ -0,0 +1,136 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.test.client.message; + +import org.apache.qpid.client.AMQQueue; +import org.apache.qpid.test.utils.QpidTestCase; + +import javax.jms.Connection; +import javax.jms.JMSException; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.Session; +import java.util.UUID; + +public class ObjectMessageTest extends QpidTestCase +{ + private Connection _connection; + private Session _session; + MessageConsumer _consumer; + MessageProducer _producer; + + public void setUp() throws Exception + { + super.setUp(); + + //Create Connection + _connection = getConnection(); + + //Create Queue + Queue queue = new AMQQueue("amq.direct", "queue"); + + //Create Session + _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + //Create Consumer + _consumer = _session.createConsumer(queue); + + //Create Producer + _producer = _session.createProducer(queue); + + _connection.start(); + } + + public void tearDown() throws Exception + { + //clean up + _connection.close(); + + super.tearDown(); + } + + public void testGetAndSend() throws JMSException + { + //Create Sample Message using UUIDs + UUID test = UUID.randomUUID(); + + ObjectMessage testMessage = _session.createObjectMessage(test); + + Object o = testMessage.getObject(); + + assertNotNull("Object was null", o); + + sendAndTest(testMessage, test); + } + + public void testSend() throws JMSException + { + //Create Sample Message using UUIDs + UUID test = UUID.randomUUID(); + + ObjectMessage testMessage = _session.createObjectMessage(test); + + sendAndTest(testMessage, test); + } + + public void testTostringAndSend() throws JMSException + { + //Create Sample Message using UUIDs + UUID test = UUID.randomUUID(); + + ObjectMessage testMessage = _session.createObjectMessage(test); + + assertNotNull("Object was null", testMessage.toString()); + + sendAndTest(testMessage, test); + } + + public void testSendNull() throws JMSException + { + + ObjectMessage testMessage = _session.createObjectMessage(null); + + assertNotNull("Object was null", testMessage.toString()); + + sendAndTest(testMessage, null); + } + + //***************** Helpers + + private void sendAndTest(ObjectMessage message, Object sent) throws JMSException + { + _producer.send(message); + + ObjectMessage receivedMessage = (ObjectMessage) _consumer.receive(1000); + + assertNotNull("Message was not received.", receivedMessage); + + UUID result = (UUID) receivedMessage.getObject(); + + assertEquals("First read: UUIDs were not equal", sent, result); + + result = (UUID) receivedMessage.getObject(); + + assertEquals("Second read: UUIDs were not equal", sent, result); + } +} diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java index f2c8a5e1f5..59ee4ad511 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java @@ -20,13 +20,7 @@ */ package org.apache.qpid.test.client.timeouts; -import org.apache.commons.configuration.Configuration; -import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.test.utils.QpidTestCase; -import org.apache.qpid.client.transport.TransportConnection; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.io.File; import javax.jms.Connection; import javax.jms.JMSException; @@ -35,7 +29,13 @@ import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; -import java.io.File; + +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; +import org.apache.qpid.test.utils.QpidTestCase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This tests that when the commit takes a long time(due to POST_COMMIT_DELAY) that the commit does not timeout @@ -67,16 +67,19 @@ public class SyncWaitDelayTest extends QpidTestCase fail("Unable to test without config file:" + _configFile); } - ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(_configFile); - - //Disable management on broker. - config.getConfiguration().setProperty("management.enabled", "false"); - - Configuration testVirtualhost = config.getConfiguration().subset("virtualhosts.virtualhost." + VIRTUALHOST); - testVirtualhost.setProperty("store.class", "org.apache.qpid.server.store.SlowMessageStore"); - testVirtualhost.setProperty("store.delays.commitTran.post", POST_COMMIT_DELAY); - - startBroker(1, config); + XMLConfiguration configuration = new XMLConfiguration(_configFile); + configuration.setProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.class", "org.apache.qpid.server.store.SlowMessageStore"); + configuration.setProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.delays.commitTran.post", POST_COMMIT_DELAY); + configuration.setProperty("management.enabled", "false"); + + + File tmpFile = File.createTempFile("configFile", "test"); + tmpFile.deleteOnExit(); + configuration.save(tmpFile); + + ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(tmpFile); + + startBroker(1, reg); //Set the syncWrite timeout to be just larger than the delay on the commitTran. setSystemProperty("amqj.default_syncwrite_timeout", String.valueOf(SYNC_WRITE_TIMEOUT)); diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java index b932b1d784..5d8ee785ec 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java @@ -77,7 +77,7 @@ public class ConnectionCloseTest extends QpidTestCase // This should leave the finalizer enough time to notify those threads synchronized (this) { - this.wait(1000); + this.wait(10000); } Map<Thread,StackTraceElement[]> after = Thread.getAllStackTraces(); diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java index 2a44c444e0..b185ec60a2 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java @@ -20,30 +20,34 @@ */ package org.apache.qpid.test.utils; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.server.registry.ApplicationRegistry; - import javax.jms.Connection; public class FailoverBaseCase extends QpidTestCase { - protected int FAILING_VM_PORT = 2; - protected int FAILING_PORT = 5673; + public static int FAILING_VM_PORT = 2; + public static int FAILING_PORT = 5673; + protected int failingPort; + private boolean failedOver = false; - private int getFailingPort() + public FailoverBaseCase() { if (_broker.equals(VM)) { - return FAILING_VM_PORT; + failingPort = FAILING_VM_PORT; } else { - return FAILING_PORT; + failingPort = FAILING_PORT; } } + + protected int getFailingPort() + { + return failingPort; + } protected void setUp() throws java.lang.Exception { @@ -67,10 +71,16 @@ public class FailoverBaseCase extends QpidTestCase public void tearDown() throws Exception { - if (!failedOver) + int port; + if (_broker.equals(VM)) { - stopBroker(getFailingPort()); + port = FAILING_VM_PORT; } + else + { + port = FAILING_PORT; + } + stopBroker(port); super.tearDown(); } @@ -90,4 +100,9 @@ public class FailoverBaseCase extends QpidTestCase throw new RuntimeException(e); } } + + protected void setFailingPort(int p) + { + failingPort = p; + } } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java index d0bb265a0c..00c1da69e9 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java @@ -229,11 +229,13 @@ public class QpidTestCase extends TestCase private LineNumberReader in; private String ready; private CountDownLatch latch; + private boolean seenReady; public Piper(InputStream in, String ready) { this.in = new LineNumberReader(new InputStreamReader(in)); this.ready = ready; + this.seenReady = false; if (this.ready != null && !this.ready.equals("")) { this.latch = new CountDownLatch(1); @@ -257,7 +259,8 @@ public class QpidTestCase extends TestCase } else { - return latch.await(timeout, unit); + latch.await(timeout, unit); + return seenReady; } } @@ -271,6 +274,7 @@ public class QpidTestCase extends TestCase System.out.println(line); if (latch != null && line.contains(ready)) { + seenReady = true; latch.countDown(); } } @@ -290,7 +294,7 @@ public class QpidTestCase extends TestCase } } - public void startBroker(int port, ConfigurationFileApplicationRegistry config) throws Exception + public void startBroker(int port, ApplicationRegistry config) throws Exception { ApplicationRegistry.initialise(config, port); startBroker(port); diff --git a/qpid/java/test-provider.properties b/qpid/java/test-provider.properties index 8066256f4f..5e2ab9c9cf 100644 --- a/qpid/java/test-provider.properties +++ b/qpid/java/test-provider.properties @@ -23,7 +23,7 @@ connectionfactory.default = amqp://username:password@clientid/test?brokerlist='t connectionfactory.default.vm = amqp://username:password@clientid/test?brokerlist='vm://:1' connectionfactory.ssl = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5671?ssl='true'' -connectionfactory.failover = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5673;tcp://localhost:5672' +connectionfactory.failover = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5673;tcp://localhost:5672'&sync_ack='true'&sync_publish='all'&failover='roundrobin?cyclecount='20'' connectionfactory.failover.vm = amqp://username:password@clientid/test?brokerlist='vm://:2;vm://:1' connectionfactory.connection1 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5672' connectionfactory.connection2 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5673' diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java index 4bba7b113d..9770adceb0 100644 --- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java +++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java @@ -696,6 +696,8 @@ public class QpidBench public void opened(org.apache.qpid.transport.Session ssn) {} + public void resumed(org.apache.qpid.transport.Session ssn) {} + public void exception(org.apache.qpid.transport.Session ssn, SessionException exc) { diff --git a/qpid/python/commands/qpid-cluster b/qpid/python/commands/qpid-cluster index f2028d944b..07fa666041 100755 --- a/qpid/python/commands/qpid-cluster +++ b/qpid/python/commands/qpid-cluster @@ -23,12 +23,17 @@ import os import getopt import sys import locale +import socket +import re from qmf.console import Session _host = "localhost" _stopId = None _stopAll = False _force = False +_numeric = False +_showConn = False +_delConn = None def Usage (): print "Usage: qpid-cluster [OPTIONS] [broker-addr]" @@ -37,12 +42,43 @@ def Usage (): print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost" print print "Options:" - print " -s [--stop] ID Stop one member of the cluster by its ID" - print " -k [--all-stop] Shut down the whole cluster" - print " -f [--force] Suppress the 'are-you-sure?' prompt" + print " -C [--all-connections] View client connections to all cluster members" + print " -c [--connections] ID View client connections to specified member" + print " -d [--del-connection] HOST:PORT" + print " Disconnect a client connection" + print " -s [--stop] ID Stop one member of the cluster by its ID" + print " -k [--all-stop] Shut down the whole cluster" + print " -f [--force] Suppress the 'are-you-sure?' prompt" + print " -n [--numeric] Don't resolve names" print sys.exit (1) + +class IpAddr: + def __init__(self, text): + if text.find("@") != -1: + tokens = text.split("@") + text = tokens[1] + if text.find(":") != -1: + tokens = text.split(":") + text = tokens[0] + self.port = int(tokens[1]) + else: + self.port = 5672 + self.dottedQuad = socket.gethostbyname(text) + nums = self.dottedQuad.split(".") + self.addr = (int(nums[0]) << 24) + (int(nums[1]) << 16) + (int(nums[2]) << 8) + int(nums[3]) + + def bestAddr(self, addrPortList): + bestDiff = 0xFFFFFFFFL + bestAddr = None + for addrPort in addrPortList: + diff = IpAddr(addrPort[0]).addr ^ self.addr + if diff < bestDiff: + bestDiff = diff + bestAddr = addrPort + return bestAddr + class BrokerManager: def __init__(self): self.brokerName = None @@ -62,7 +98,7 @@ class BrokerManager: if self.broker: self.qmf.delBroker(self.broker) - def overview(self): + def _getClusters(self): packages = self.qmf.getPackages() if "org.apache.qpid.cluster" not in packages: print "Clustering is not installed on the broker." @@ -73,8 +109,35 @@ class BrokerManager: print "Clustering is installed but not enabled on the broker." sys.exit(0) + return clusters + + def _getHostList(self, urlList): + hosts = [] + hostAddr = IpAddr(_host) + for url in urlList: + if url.find("amqp:") != 0: + raise Exception("Invalid URL 1") + url = url[5:] + addrs = str(url).split(",") + addrList = [] + for addr in addrs: + tokens = addr.split(":") + if len(tokens) != 3: + raise Exception("Invalid URL 2") + addrList.append((tokens[1], tokens[2])) + + # Find the address in the list that is most likely to be in the same subnet as the address + # with which we made the original QMF connection. This increases the probability that we will + # be able to reach the cluster member. + + best = hostAddr.bestAddr(addrList) + bestUrl = best[0] + ":" + best[1] + hosts.append(bestUrl) + return hosts + + def overview(self): + clusters = self._getClusters() cluster = clusters[0] - myUrl = cluster.publishedURL memberList = cluster.members.split(";") idList = cluster.memberIDs.split(";") @@ -86,11 +149,7 @@ class BrokerManager: print " : ID=%s URL=%s" % (idList[idx], memberList[idx]) def stopMember(self, id): - clusters = self.qmf.getObjects(_class="cluster", _agent=self.brokerAgent) - if len(clusters) == 0: - print "Clustering is installed but not enabled on the broker." - sys.exit(0) - + clusters = self._getClusters() cluster = clusters[0] idList = cluster.memberIDs.split(";") if id not in idList: @@ -113,11 +172,7 @@ class BrokerManager: cluster.stopClusterNode(id) def stopAll(self): - clusters = self.qmf.getObjects(_class="cluster", _agent=self.brokerAgent) - if len(clusters) == 0: - print "Clustering is installed but not enabled on the broker." - sys.exit(0) - + clusters = self._getClusters() if not _force: prompt = "Warning: This command will shut down the entire cluster." prompt += " Are you sure? [N]: " @@ -130,15 +185,72 @@ class BrokerManager: cluster = clusters[0] cluster.stopFullCluster() + def showConnections(self): + clusters = self._getClusters() + cluster = clusters[0] + memberList = cluster.members.split(";") + idList = cluster.memberIDs.split(";") + displayList = [] + hostList = self._getHostList(memberList) + self.qmf.delBroker(self.broker) + self.broker = None + self.brokers = [] + pattern = re.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+$") + + idx = 0 + for host in hostList: + if _showConn == "all" or _showConn == idList[idx] or _delConn: + self.brokers.append(self.qmf.addBroker(host)) + displayList.append(idList[idx]) + idx += 1 + + idx = 0 + found = False + for broker in self.brokers: + if not _delConn: + print "Clients on Member: ID=%s:" % displayList[idx] + connList = self.qmf.getObjects(_class="connection", _package="org.apache.qpid.broker", _broker=broker) + for conn in connList: + if pattern.match(conn.address): + if _numeric or _delConn: + a = conn.address + else: + tokens = conn.address.split(":") + try: + hostList = socket.gethostbyaddr(tokens[0]) + host = hostList[0] + except: + host = tokens[0] + a = host + ":" + tokens[1] + if _delConn: + tokens = _delConn.split(":") + ip = socket.gethostbyname(tokens[0]) + toDelete = ip + ":" + tokens[1] + if a == toDelete: + print "Closing connection from client: %s" % a + conn.close() + found = True + else: + print " %s" % a + idx += 1 + if not _delConn: + print + if _delConn and not found: + print "Client connection '%s' not found" % _delConn + + for broker in self.brokers: + self.qmf.delBroker(broker) + + ## ## Main Program ## try: - longOpts = ("stop=", "all-stop", "force") - (optlist, encArgs) = getopt.gnu_getopt (sys.argv[1:], "s:kf", longOpts) + longOpts = ("stop=", "all-stop", "force", "connections=", "all-connections" "del-connection=", "numeric") + (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "s:kfCc:d:n", longOpts) except: - Usage () + Usage() try: encoding = locale.getpreferredencoding() @@ -146,13 +258,41 @@ try: except: cargs = encArgs +count = 0 for opt in optlist: if opt[0] == "-s" or opt[0] == "--stop": _stopId = opt[1] + if len(_stopId.split(":")) != 2: + print "Member ID must be of form: <host or ip>:<number>" + sys.exit(1) + count += 1 if opt[0] == "-k" or opt[0] == "--all-stop": _stopAll = True + count += 1 if opt[0] == "-f" or opt[0] == "--force": _force = True + if opt[0] == "-n" or opt[0] == "--numeric": + _numeric = True + if opt[0] == "-C" or opt[0] == "--all-connections": + _showConn = "all" + count += 1 + if opt[0] == "-c" or opt[0] == "--connections": + _showConn = opt[1] + if len(_showConn.split(":")) != 2: + print "Member ID must be of form: <host or ip>:<number>" + sys.exit(1) + count += 1 + if opt[0] == "-d" or opt[0] == "--del-connection": + _delConn = opt[1] + if len(_delConn.split(":")) != 2: + print "Connection must be of form: <host or ip>:<port>" + sys.exit(1) + count += 1 + +if count > 1: + print "Only one command option may be supplied" + print + Usage() nargs = len(cargs) bm = BrokerManager() @@ -166,6 +306,8 @@ try: bm.stopMember(_stopId) elif _stopAll: bm.stopAll() + elif _showConn or _delConn: + bm.showConnections() else: bm.overview() except KeyboardInterrupt: diff --git a/qpid/python/commands/qpid-config b/qpid/python/commands/qpid-config index a7d537edb5..144fe36953 100755 --- a/qpid/python/commands/qpid-config +++ b/qpid/python/commands/qpid-config @@ -27,8 +27,12 @@ from qmf.console import Session _recursive = False _host = "localhost" +_altern_ex = None +_passive = False _durable = False _clusterDurable = False +_if_empty = True +_if_unused = True _fileCount = 8 _fileSize = 24 _maxQueueSize = None @@ -58,7 +62,7 @@ def Usage (): print " qpid-config [OPTIONS] add exchange <type> <name> [AddExchangeOptions]" print " qpid-config [OPTIONS] del exchange <name>" print " qpid-config [OPTIONS] add queue <name> [AddQueueOptions]" - print " qpid-config [OPTIONS] del queue <name>" + print " qpid-config [OPTIONS] del queue <name> [DelQueueOptions]" print " qpid-config [OPTIONS] bind <exchange-name> <queue-name> [binding-key]" print " qpid-config [OPTIONS] unbind <exchange-name> <queue-name> [binding-key]" print @@ -69,6 +73,13 @@ def Usage (): print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost" print print "Add Queue Options:" + print " --altern-ex [name of the alternate exchange]" + print " The alternate-exchange field specifies how messages on this queue should" + print " be treated when they are rejected by a subscriber, or when they are" + print " orphaned by queue deletion. When present, rejected or orphaned messages" + print " MUST be routed to the alternate-exchange. In all cases the messages MUST" + print " be removed from the queue." + print " --passive Do not actually change the broker state (queue will not be created)" print " --durable Queue is durable" print " --cluster-durable Queue becomes durable if there is only one functioning cluster node" print " --file-count N (8) Number of files in queue's persistence journal" @@ -92,7 +103,20 @@ def Usage (): print " registered listeners (e.g. for replication). If set to 2, events will be" print " generated for enqueues and dequeues" print + print "Del Queue Options:" + print " --force Force delete of queue even if it's currently used or it's not empty" + print " --force-if-not-empty Force delete of queue even if it's not empty" + print " --force-if-used Force delete of queue even if it's currently used" + print print "Add Exchange Options:" + print " --altern-ex [name of the alternate exchange]" + print " In the event that a message cannot be routed, this is the name of the exchange to" + print " which the message will be sent. Messages transferred using message.transfer will" + print " be routed to the alternate-exchange only if they are sent with the \"none\"" + print " accept-mode, and the discard-unroutable delivery property is set to false, and" + print " there is no queue to route to for the given message according to the bindings" + print " on this exchange." + print " --passive Do not actually change teh broker state (exchange will not be created)" print " --durable Exchange is durable" print " --sequence Exchange will insert a 'qpid.msg_sequence' field in the message header" print " with a value that increments for each message forwarded." @@ -211,7 +235,7 @@ class BrokerManager: if POLICY_TYPE in args: print "--limit-policy=%s" % args[POLICY_TYPE].replace("_", "-"), if LVQ in args and args[LVQ] == 1: print "--order lvq", if LVQNB in args and args[LVQNB] == 1: print "--order lvq-no-browse", - if QUEUE_EVENT_GENERATION in args: print "--generate-queue-events=%d" % args[GENERATE_QUEUE_EVENTS], + if QUEUE_EVENT_GENERATION in args: print "--generate-queue-events=%d" % args[QUEUE_EVENT_GENERATION], print def QueueListRecurse (self, filter): @@ -241,7 +265,10 @@ class BrokerManager: declArgs[MSG_SEQUENCE] = 1 if _ive: declArgs[IVE] = 1 - self.broker.getAmqpSession().exchange_declare (exchange=ename, type=etype, durable=_durable, arguments=declArgs) + if _altern_ex != None: + self.broker.getAmqpSession().exchange_declare (exchange=ename, type=etype, alternate_exchange=_altern_ex, passive=_passive, durable=_durable, arguments=declArgs) + else: + self.broker.getAmqpSession().exchange_declare (exchange=ename, type=etype, passive=_passive, durable=_durable, arguments=declArgs) def DelExchange (self, args): if len (args) < 1: @@ -286,13 +313,16 @@ class BrokerManager: if _eventGeneration: declArgs[QUEUE_EVENT_GENERATION] = _eventGeneration - self.broker.getAmqpSession().queue_declare (queue=qname, durable=_durable, arguments=declArgs) + if _altern_ex != None: + self.broker.getAmqpSession().queue_declare (queue=qname, alternate_exchange=_altern_ex, passive=_passive, durable=_durable, arguments=declArgs) + else: + self.broker.getAmqpSession().queue_declare (queue=qname, passive=_passive, durable=_durable, arguments=declArgs) def DelQueue (self, args): if len (args) < 1: Usage () qname = args[0] - self.broker.getAmqpSession().queue_delete (queue=qname) + self.broker.getAmqpSession().queue_delete (queue=qname, if_empty=_if_empty, if_unused=_if_unused) def Bind (self, args): if len (args) < 2: @@ -340,7 +370,8 @@ def YN (bool): try: longOpts = ("durable", "cluster-durable", "bindings", "broker-addr=", "file-count=", "file-size=", "max-queue-size=", "max-queue-count=", "limit-policy=", - "order=", "sequence", "ive", "generate-queue-events=") + "order=", "sequence", "ive", "generate-queue-events=", "force", "force-if-not-empty", + "force_if_used", "altern_ex=", "passive") (optlist, encArgs) = getopt.gnu_getopt (sys.argv[1:], "a:b", longOpts) except: Usage () @@ -356,6 +387,10 @@ for opt in optlist: _recursive = True if opt[0] == "-a" or opt[0] == "--broker-addr": _host = opt[1] + if opt[0] == "--altern-ex": + _altern_ex = opt[1] + if opt[0] == "--passive": + _passive = True if opt[0] == "--durable": _durable = True if opt[0] == "--cluster-durable": @@ -384,6 +419,14 @@ for opt in optlist: _ive = True if opt[0] == "--generate-queue-events": _eventGeneration = int (opt[1]) + if opt[0] == "--force": + _if_empty = False + _if_unused = False + if opt[0] == "--force-if-not-empty": + _if_empty = False + if opt[0] == "--force-if-used": + _if_unused = False + nargs = len (cargs) bm = BrokerManager () diff --git a/qpid/python/commands/qpid-stat b/qpid/python/commands/qpid-stat new file mode 100755 index 0000000000..1f1d247bb1 --- /dev/null +++ b/qpid/python/commands/qpid-stat @@ -0,0 +1,449 @@ +#!/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 getopt +import sys +import locale +import socket +import re +from qmf.console import Session, Console +from qpid.disp import Display, Header, Sorter + +_host = "localhost" +_top = False +_types = "" +_limit = 50 +_increasing = False +_sortcol = None +pattern = re.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+$") + +def Usage (): + print "Usage: qpid-stat [OPTIONS] [broker-addr]" + print + print " broker-addr is in the form: [username/password@] hostname | ip-address [:<port>]" + print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost" + print +# print "General Options:" +# print " -n [--numeric] Don't resolve names" +# print " -t [--top] Repeatedly display top items" +# print + print "Display Options:" + print + print " -b Show Brokers" + print " -c Show Connections" +# print " -s Show Sessions" + print " -e Show Exchanges" + print " -q Show Queues" + print + print " -S [--sort-by] COLNAME Sort by column name" + print " -I [--increasing] Sort by increasing value (default = decreasing)" + print " -L [--limit] NUM Limit output to NUM rows (default = 50)" + print + sys.exit (1) + +class IpAddr: + def __init__(self, text): + if text.find("@") != -1: + tokens = text.split("@") + text = tokens[1] + if text.find(":") != -1: + tokens = text.split(":") + text = tokens[0] + self.port = int(tokens[1]) + else: + self.port = 5672 + self.dottedQuad = socket.gethostbyname(text) + nums = self.dottedQuad.split(".") + self.addr = (int(nums[0]) << 24) + (int(nums[1]) << 16) + (int(nums[2]) << 8) + int(nums[3]) + + def bestAddr(self, addrPortList): + bestDiff = 0xFFFFFFFFL + bestAddr = None + for addrPort in addrPortList: + diff = IpAddr(addrPort[0]).addr ^ self.addr + if diff < bestDiff: + bestDiff = diff + bestAddr = addrPort + return bestAddr + +class Broker(object): + def __init__(self, qmf, broker): + self.broker = broker + bobj = qmf.getObjects(_class="broker", _package="org.apache.qpid.broker", _broker=broker)[0] + self.currentTime = bobj.getTimestamps()[0] + try: + self.uptime = bobj.uptime + except: + self.uptime = 0 + self.connections = {} + self.sessions = {} + self.exchanges = {} + self.queues = {} + package = "org.apache.qpid.broker" + + list = qmf.getObjects(_class="connection", _package=package, _broker=broker) + for conn in list: + if pattern.match(conn.address): + self.connections[conn.getObjectId()] = conn + + list = qmf.getObjects(_class="session", _package=package, _broker=broker) + for sess in list: + if sess.connectionRef in self.connections: + self.sessions[sess.getObjectId()] = sess + + list = qmf.getObjects(_class="exchange", _package=package, _broker=broker) + for exchange in list: + self.exchanges[exchange.getObjectId()] = exchange + + list = qmf.getObjects(_class="queue", _package=package, _broker=broker) + for queue in list: + self.queues[queue.getObjectId()] = queue + + def getName(self): + return self.broker.getUrl() + + def getCurrentTime(self): + return self.currentTime + + def getUptime(self): + return self.uptime + +class BrokerManager(Console): + def __init__(self): + self.brokerName = None + self.qmf = None + self.broker = None + self.brokers = [] + self.cluster = None + + def SetBroker(self, brokerUrl): + self.url = brokerUrl + self.qmf = Session() + self.broker = self.qmf.addBroker(brokerUrl) + agents = self.qmf.getAgents() + for a in agents: + if a.getAgentBank() == 0: + self.brokerAgent = a + + def Disconnect(self): + if self.broker: + self.qmf.delBroker(self.broker) + + def _getCluster(self): + packages = self.qmf.getPackages() + if "org.apache.qpid.cluster" not in packages: + return None + + clusters = self.qmf.getObjects(_class="cluster", _agent=self.brokerAgent) + if len(clusters) == 0: + print "Clustering is installed but not enabled on the broker." + return None + + self.cluster = clusters[0] + + def _getHostList(self, urlList): + hosts = [] + hostAddr = IpAddr(_host) + for url in urlList: + if url.find("amqp:") != 0: + raise Exception("Invalid URL 1") + url = url[5:] + addrs = str(url).split(",") + addrList = [] + for addr in addrs: + tokens = addr.split(":") + if len(tokens) != 3: + raise Exception("Invalid URL 2") + addrList.append((tokens[1], tokens[2])) + + # Find the address in the list that is most likely to be in the same subnet as the address + # with which we made the original QMF connection. This increases the probability that we will + # be able to reach the cluster member. + + best = hostAddr.bestAddr(addrList) + bestUrl = best[0] + ":" + best[1] + hosts.append(bestUrl) + return hosts + + def displaySubs(self, subs, indent, broker=None, conn=None, sess=None, exchange=None, queue=None): + if len(subs) == 0: + return + this = subs[0] + remaining = subs[1:] + newindent = indent + " " + if this == 'b': + pass + elif this == 'c': + if broker: + for oid in broker.connections: + iconn = broker.connections[oid] + self.printConnSub(indent, broker.getName(), iconn) + self.displaySubs(remaining, newindent, broker=broker, conn=iconn, + sess=sess, exchange=exchange, queue=queue) + elif this == 's': + pass + elif this == 'e': + pass + elif this == 'q': + pass + print + + def displayBroker(self, subs): + disp = Display(prefix=" ") + heads = [] + heads.append(Header('broker')) + heads.append(Header('cluster')) + heads.append(Header('uptime', Header.DURATION)) + heads.append(Header('conn', Header.KMG)) + heads.append(Header('sess', Header.KMG)) + heads.append(Header('exch', Header.KMG)) + heads.append(Header('queue', Header.KMG)) + rows = [] + for broker in self.brokers: + if self.cluster: + ctext = "%s(%s)" % (self.cluster.clusterName, self.cluster.status) + else: + ctext = "<standalone>" + row = (broker.getName(), ctext, broker.getUptime(), + len(broker.connections), len(broker.sessions), + len(broker.exchanges), len(broker.queues)) + rows.append(row) + title = "Brokers" + if _sortcol: + sorter = Sorter(heads, rows, _sortcol, _limit, _increasing) + dispRows = sorter.getSorted() + else: + dispRows = rows + disp.formattedTable(title, heads, dispRows) + + def displayConn(self, subs): + disp = Display(prefix=" ") + heads = [] + if self.cluster: + heads.append(Header('broker')) + heads.append(Header('client-addr')) + heads.append(Header('cproc')) + heads.append(Header('cpid')) + heads.append(Header('auth')) + heads.append(Header('connected', Header.DURATION)) + heads.append(Header('idle', Header.DURATION)) + heads.append(Header('msgIn', Header.KMG)) + heads.append(Header('msgOut', Header.KMG)) + rows = [] + for broker in self.brokers: + for oid in broker.connections: + conn = broker.connections[oid] + row = [] + if self.cluster: + row.append(broker.getName()) + row.append(conn.address) + row.append(conn.remoteProcessName) + row.append(conn.remotePid) + row.append(conn.authIdentity) + row.append(broker.getCurrentTime() - conn.getTimestamps()[1]) + idle = broker.getCurrentTime() - conn.getTimestamps()[0] + row.append(broker.getCurrentTime() - conn.getTimestamps()[0]) + row.append(conn.framesFromClient) + row.append(conn.framesToClient) + rows.append(row) + title = "Connections" + if self.cluster: + title += " for cluster '%s'" % self.cluster.clusterName + if _sortcol: + sorter = Sorter(heads, rows, _sortcol, _limit, _increasing) + dispRows = sorter.getSorted() + else: + dispRows = rows + disp.formattedTable(title, heads, dispRows) + + def displaySession(self, subs): + disp = Display(prefix=" ") + + def displayExchange(self, subs): + disp = Display(prefix=" ") + heads = [] + if self.cluster: + heads.append(Header('broker')) + heads.append(Header("exchange")) + heads.append(Header("type")) + heads.append(Header("dur", Header.Y)) + heads.append(Header("bind", Header.KMG)) + heads.append(Header("msgIn", Header.KMG)) + heads.append(Header("msgOut", Header.KMG)) + heads.append(Header("msgDrop", Header.KMG)) + heads.append(Header("byteIn", Header.KMG)) + heads.append(Header("byteOut", Header.KMG)) + heads.append(Header("byteDrop", Header.KMG)) + rows = [] + for broker in self.brokers: + for oid in broker.exchanges: + ex = broker.exchanges[oid] + row = [] + if self.cluster: + row.append(broker.getName()) + row.append(ex.name) + row.append(ex.type) + row.append(ex.durable) + row.append(ex.bindingCount) + row.append(ex.msgReceives) + row.append(ex.msgRoutes) + row.append(ex.msgDrops) + row.append(ex.byteReceives) + row.append(ex.byteRoutes) + row.append(ex.byteDrops) + rows.append(row) + title = "Exchanges" + if self.cluster: + title += " for cluster '%s'" % self.cluster.clusterName + if _sortcol: + sorter = Sorter(heads, rows, _sortcol, _limit, _increasing) + dispRows = sorter.getSorted() + else: + dispRows = rows + disp.formattedTable(title, heads, dispRows) + + def displayQueue(self, subs): + disp = Display(prefix=" ") + heads = [] + if self.cluster: + heads.append(Header('broker')) + heads.append(Header("queue")) + heads.append(Header("dur", Header.Y)) + heads.append(Header("autoDel", Header.Y)) + heads.append(Header("excl", Header.Y)) + heads.append(Header("msg", Header.KMG)) + heads.append(Header("msgIn", Header.KMG)) + heads.append(Header("msgOut", Header.KMG)) + heads.append(Header("bytes", Header.KMG)) + heads.append(Header("bytesIn", Header.KMG)) + heads.append(Header("bytesOut", Header.KMG)) + heads.append(Header("cons", Header.KMG)) + heads.append(Header("bind", Header.KMG)) + rows = [] + for broker in self.brokers: + for oid in broker.queues: + q = broker.queues[oid] + row = [] + if self.cluster: + row.append(broker.getName()) + row.append(q.name) + row.append(q.durable) + row.append(q.autoDelete) + row.append(q.exclusive) + row.append(q.msgDepth) + row.append(q.msgTotalEnqueues) + row.append(q.msgTotalDequeues) + row.append(q.byteDepth) + row.append(q.byteTotalEnqueues) + row.append(q.byteTotalDequeues) + row.append(q.consumerCount) + row.append(q.bindingCount) + rows.append(row) + title = "Queues" + if self.cluster: + title += " for cluster '%s'" % self.cluster.clusterName + if _sortcol: + sorter = Sorter(heads, rows, _sortcol, _limit, _increasing) + dispRows = sorter.getSorted() + else: + dispRows = rows + disp.formattedTable(title, heads, dispRows) + + def displayMain(self, main, subs): + if main == 'b': self.displayBroker(subs) + elif main == 'c': self.displayConn(subs) + elif main == 's': self.displaySession(subs) + elif main == 'e': self.displayExchange(subs) + elif main == 'q': self.displayQueue(subs) + + def display(self): + self._getCluster() + if self.cluster: + memberList = self.cluster.members.split(";") + hostList = self._getHostList(memberList) + self.qmf.delBroker(self.broker) + self.broker = None + for host in hostList: + b = self.qmf.addBroker(host) + self.brokers.append(Broker(self.qmf, b)) + else: + self.brokers.append(Broker(self.qmf, self.broker)) + + self.displayMain(_types[0], _types[1:]) + + +## +## Main Program +## + +try: + longOpts = ("top", "numeric", "sort-by=", "limit=", "increasing") + (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "bceqS:L:I", longOpts) +except: + Usage() + +try: + encoding = locale.getpreferredencoding() + cargs = [a.decode(encoding) for a in encArgs] +except: + cargs = encArgs + +for opt in optlist: + if opt[0] == "-t" or opt[0] == "--top": + _top = True + elif opt[0] == "-n" or opt[0] == "--numeric": + _numeric = True + elif opt[0] == "-S" or opt[0] == "--sort-by": + _sortcol = opt[1] + elif opt[0] == "-I" or opt[0] == "--increasing": + _increasing = True + elif opt[0] == "-L" or opt[0] == "--limit": + _limit = int(opt[1]) + elif len(opt[0]) == 2: + char = opt[0][1] + if "bcseq".find(char) != -1: + _types += char + else: + Usage() + else: + Usage() + +if len(_types) == 0: + Usage() + +nargs = len(cargs) +bm = BrokerManager() + +if nargs == 1: + _host = cargs[0] + +try: + bm.SetBroker(_host) + bm.display() +except KeyboardInterrupt: + print +except Exception,e: + print "Failed:", e.args + #raise # TODO: Remove before flight + sys.exit(1) + +bm.Disconnect() diff --git a/qpid/python/examples/datatypes/client.py b/qpid/python/examples/datatypes/client.py new file mode 100755 index 0000000000..088e529909 --- /dev/null +++ b/qpid/python/examples/datatypes/client.py @@ -0,0 +1,122 @@ +#!/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. +# +""" + client.py + + Client for testing use of Unicode and datatypes. + + Both client and server will be written in C++ and Python. + Tests can run clients and servers written in different + languages, and they can be run on 32-bit and 64-bit architectures. + +""" + +import qpid +import sys +import os +from qpid.util import connect +from qpid.connection import Connection +from qpid.datatypes import Message, RangedSet, uuid4 +from qpid.queue import Empty + +import testdata + +#----- Initialization -------------------------------------- + + +# Set parameters for login + +host="127.0.0.1" +port=5672 +user="guest" +password="guest" + +# If an alternate host or port has been specified, use that instead +# (this is used in our unit tests) +if len(sys.argv) > 1 : + host=sys.argv[1] +if len(sys.argv) > 2 : + port=int(sys.argv[2]) + +# Create a connection. +socket = connect(host, port) +connection = Connection (sock=socket, username=user, password=password) +connection.start() +session = connection.session(str(uuid4())) + + +#----- Main Body -- ---------------------------------------- + +# Create a response queue for the server to send responses to. Use the +# same string as the name of the queue and the name of the routing +# key. + +reply_to = "reply_to:" + session.name +session.queue_declare(queue=reply_to, exclusive=True) +session.exchange_bind(exchange="amq.direct", queue=reply_to, binding_key=reply_to) + +# Create a local queue and subscribe it to the response queue + +local_queue_name = "local_queue" +queue = session.incoming(local_queue_name) + +# Call message_subscribe() to tell the broker to deliver messages from +# the server's reply_to queue to our local client queue. The server +# will start delivering messages as soon as message credit is +# available. + +session.message_subscribe(queue=reply_to, destination=local_queue_name) +queue.start() + +# Set up the properties. Perhaps a few application headers? + +delivery_properties = session.delivery_properties(routing_key="request") + +message_properties = session.message_properties() + +message_properties.content_encoding="text/plain; charset='utf-8'" + +testdata.set_application_headers(message_properties) +message_properties.reply_to = session.reply_to("amq.direct", reply_to) + +# deliver the message - remember to encode the Unicode string! +request = Message(message_properties, delivery_properties, testdata.String_Greek.encode("utf8")) +session.message_transfer(destination="amq.direct", message=request) + +# Now see what messages the server sent to our reply_to queue + +try: + response = queue.get(timeout=10) + content = response.body + session.message_accept(RangedSet(response.id)) + testdata.check_message(response) + print "Response: " + content +except Empty: + print "No more messages!" + exit(1) +except: + print "Unexpected exception!" + exit(1) + +#----- Cleanup ------------------------------------------------ + +# Clean up before exiting so there are no open threads. + +session.close(timeout=10) diff --git a/qpid/python/examples/datatypes/server.py b/qpid/python/examples/datatypes/server.py new file mode 100755 index 0000000000..18e6fa4ad7 --- /dev/null +++ b/qpid/python/examples/datatypes/server.py @@ -0,0 +1,124 @@ +#!/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. +# +""" + server.py + + Server for testing use of Unicode and datatypes. + + Both client and server will be written in C++ and Python. + Tests can run clients and servers written in different + languages, and they can be run on 32-bit and 64-bit architectures. +""" + +import testdata + +import qpid +import sys +import os +from qpid.util import connect +from qpid.connection import Connection +from qpid.datatypes import Message, RangedSet, uuid4 +from qpid.queue import Empty + +#----- Functions ------------------------------------------- +def respond(session, request): + + # The routing key for the response is the request's reply-to + # property. The body for the response is the request's body, + # converted to upper case. + + testdata.check_message(request) + + message_properties = request.get("message_properties") + reply_to = message_properties.reply_to + + testdata.set_application_headers(message_properties) + + if reply_to == None: + raise Exception("This message is missing the 'reply_to' property, which is required") + + delivery_properties = session.delivery_properties(routing_key=reply_to["routing_key"]) + response = Message(delivery_properties, message_properties, testdata.String_Greek.encode("utf8")) + print "Sending response ..." + session.message_transfer(destination=reply_to["exchange"], message=response) + +#----- Initialization -------------------------------------- + + +# Set parameters for login + +host="127.0.0.1" +port=5672 +user="guest" +password="guest" + +# If an alternate host or port has been specified, use that instead +# (this is used in our unit tests) +if len(sys.argv) > 1 : + host=sys.argv[1] +if len(sys.argv) > 2 : + port=int(sys.argv[2]) + +socket = connect(host, port) +connection = Connection (sock=socket, username=user, password=password) +connection.start() +session = connection.session(str(uuid4())) + +#----- Main Body -- ---------------------------------------- + +# Create a request queue and subscribe to it + +session.queue_declare(queue="request", exclusive=True) +session.exchange_bind(exchange="amq.direct", queue="request", binding_key="request") + +local_queue_name = "local_queue" + +session.message_subscribe(queue="request", destination=local_queue_name) + +queue = session.incoming(local_queue_name) +queue.start() + +# Remind the user to start the client program + +print "Request server running - run your client now." +print "(Times out after 100 seconds ...)" +sys.stdout.flush() + +# Respond to each request + +# If we get a message, send it back to the user (as indicated in the +# ReplyTo property) + +while True: + try: + request = queue.get(timeout=100) + session.message_accept(RangedSet(request.id)) + + respond(session, request) + except Empty: + print "No more messages!" + break; + + +#----- Cleanup ------------------------------------------------ + +# Clean up before exiting so there are no open threads. + +session.close(timeout=10) diff --git a/qpid/python/examples/datatypes/testdata.py b/qpid/python/examples/datatypes/testdata.py new file mode 100644 index 0000000000..cdf140d400 --- /dev/null +++ b/qpid/python/examples/datatypes/testdata.py @@ -0,0 +1,180 @@ +# -*- encoding: utf-8 -*- + +from qpid.datatypes import uuid4, timestamp + +#----- Some variables to test boundary conditions on various data types + +void = None +boolean_true = True +boolean_false = False +Uint8_0 = 0 +Uint8_max = 255 +Uint16_0 = 0 +Uint16_max = 65535 +Uint32_0 = 0 +Uint32_max = 4294967295 +Uint64_0 = 0 +Uint64_max = 18446744073709551615 +Int8_min = -128 +Int8_0 = 0 +Int8_max = 127 +Int16_min = -32768 +Int16_0 = 0 +Int16_max = 32767 +Int32_min = -2147483648 +Int32_0 = 0 +Int32_max = 2147483647 +Int64_min = -9223372036854775808 +Int64_0 = 0 +Int64_max = 9223372036854775807 + +Float_pi = 3.14159265 +Float_neg = -1E4 +Float_big = 1267.43233E12 +Float_small = 12.78e-12 +Float_neg0 = -0 +Float_pos0 = 0 +Float_INF = float('inf') +Float_Negative_INF = float('-inf') + +Double_pi = 3.1415926535897932384626433832795 +Double_neg = -1E4 +Double_big = 1267.43233E12 +Double_small = 12.78e-2 +Double_neg0 = -0 +Double_pos0 = 0 +Double_INF = float('inf') +Double_Negative_INF = float('-inf') + +char_1byte = u'0024' # $ +char_2byte = u'00A2' # ¢ +char_3byte = u'20AC' # € +char_4byte = u'10ABCD' + +timestamp = timestamp() + +UUID = uuid4() + +String_Greek = u"ἐξίσταντο δὲ πάντες καὶ διηπόρουν, ἄλλος πρὸς ἄλλον λέγοντες, Τί θέλει τοῦτο εἶναι;" + +String_Empty = "" + +#----- A few functions ---------------------------------------------------------- + +def near_enough(float1, float2, delta): + return abs(float1-float2) < delta + +def set_application_headers(message_properties): + + message_properties.application_headers = {} + message_properties.application_headers["void"] = None + message_properties.application_headers["boolean_true"] = boolean_true + message_properties.application_headers["boolean_false"] = boolean_false + message_properties.application_headers["Uint8_0"] = Uint8_0 + message_properties.application_headers["Uint8_max"] = Uint8_max + message_properties.application_headers["Uint16_0"] = Uint16_0 + message_properties.application_headers["Uint16_max"] = Uint16_max + message_properties.application_headers["Uint32_0"] = Uint32_0 + message_properties.application_headers["Uint32_max"] = Uint32_max + message_properties.application_headers["Uint64_0"] = Uint64_0 +# message_properties.application_headers["Uint64_max"] = Uint64_max + message_properties.application_headers["Int8_min"] = Int8_min + message_properties.application_headers["Int8_0"] = Int8_0 + message_properties.application_headers["Int8_max"] = Int8_max + message_properties.application_headers["Int16_min"] = Int16_min + message_properties.application_headers["Int16_0"] = Int16_0 + message_properties.application_headers["Int16_max"] = Int16_max + message_properties.application_headers["Int32_min"] = Int32_min + message_properties.application_headers["Int32_0"] = Int32_0 + message_properties.application_headers["Int32_max"] = Int32_max + message_properties.application_headers["Int64_min"] = Int64_min + message_properties.application_headers["Int64_0"] = Int64_0 + message_properties.application_headers["Int64_max"] = Int64_max + + message_properties.application_headers["Float_pi"] = Float_pi + message_properties.application_headers["Float_neg"] = Float_neg + message_properties.application_headers["Float_big"] = Float_big + message_properties.application_headers["Float_small"] = Float_small + message_properties.application_headers["Float_neg0"] = Float_neg0 + message_properties.application_headers["Float_pos0"] = Float_pos0 + message_properties.application_headers["Float_INF"] = Float_INF + message_properties.application_headers["Float_Negative_INF"] = Float_Negative_INF + + message_properties.application_headers["Double_pi"] = Double_pi + message_properties.application_headers["Double_neg"] = Double_neg + message_properties.application_headers["Double_big"] = Double_big + message_properties.application_headers["Double_small"] = Double_small + message_properties.application_headers["Double_neg0"] = Double_neg0 + message_properties.application_headers["Double_pos0"] = Double_pos0 + message_properties.application_headers["Double_INF"] = Double_INF + message_properties.application_headers["Double_Negative_INF"] = Double_Negative_INF + + message_properties.application_headers["char_1byte"] = char_1byte + message_properties.application_headers["char_2byte"] = char_2byte + message_properties.application_headers["char_3byte"] = char_3byte + message_properties.application_headers["char_4byte"] = char_4byte + + message_properties.application_headers["timestamp"] = timestamp + message_properties.application_headers["UUID"] = uuid4() + message_properties.application_headers["String_Greek"] = String_Greek + message_properties.application_headers["String_Empty"] = String_Empty + +def check_message(message): + +# message_properties = message.message_properties() + message_properties = message.get("message_properties") + assert message_properties.application_headers["void"] == None + assert message_properties.application_headers["boolean_true"] == boolean_true + assert message_properties.application_headers["boolean_false"] == boolean_false + assert message_properties.application_headers["Uint8_0"] == Uint8_0 + assert message_properties.application_headers["Uint8_max"] == Uint8_max + assert message_properties.application_headers["Uint16_0"] == Uint16_0 + assert message_properties.application_headers["Uint16_max"] == Uint16_max + assert message_properties.application_headers["Uint32_0"] == Uint32_0 + assert message_properties.application_headers["Uint32_max"] == Uint32_max + assert message_properties.application_headers["Uint64_0"] == Uint64_0 +# assert message_properties.application_headers["Uint64_max"] == Uint64_max + assert message_properties.application_headers["Int8_min"] == Int8_min + assert message_properties.application_headers["Int8_0"] == Int8_0 + assert message_properties.application_headers["Int8_max"] == Int8_max + assert message_properties.application_headers["Int16_min"] == Int16_min + assert message_properties.application_headers["Int16_0"] == Int16_0 + assert message_properties.application_headers["Int16_max"] == Int16_max + assert message_properties.application_headers["Int32_min"] == Int32_min + assert message_properties.application_headers["Int32_0"] == Int32_0 + assert message_properties.application_headers["Int32_max"] == Int32_max + assert message_properties.application_headers["Int64_min"] == Int64_min + assert message_properties.application_headers["Int64_0"] == Int64_0 + assert message_properties.application_headers["Int64_max"] == Int64_max + +# Change floating point comparisons to allow inexactness + + assert near_enough(message_properties.application_headers["Float_pi"], Float_pi, 0.00001) + assert near_enough(message_properties.application_headers["Float_neg"], Float_neg, 0.00001) + assert near_enough(message_properties.application_headers["Float_big"], Float_big, Float_big/1000000) + assert near_enough(message_properties.application_headers["Float_small"], Float_small, 0.00001) + assert message_properties.application_headers["Float_neg0"] == Float_neg0 + assert message_properties.application_headers["Float_pos0"] == Float_pos0 + assert message_properties.application_headers["Float_INF"] == Float_INF + assert message_properties.application_headers["Float_Negative_INF"] == Float_Negative_INF + + assert near_enough(message_properties.application_headers["Double_pi"], Double_pi, 0.00001) + assert near_enough(message_properties.application_headers["Double_neg"], Double_neg, 0.00001) + assert near_enough(message_properties.application_headers["Double_big"], Double_big, Double_big/1000000) + assert near_enough(message_properties.application_headers["Double_small"], Double_small, 0.00001) + assert message_properties.application_headers["Double_neg0"] == Double_neg0 + assert message_properties.application_headers["Double_pos0"] == Double_pos0 + assert message_properties.application_headers["Double_INF"] == Double_INF + assert message_properties.application_headers["Double_Negative_INF"] == Double_Negative_INF + + assert message_properties.application_headers["char_1byte"] == char_1byte + assert message_properties.application_headers["char_2byte"] == char_2byte + assert message_properties.application_headers["char_3byte"] == char_3byte + assert message_properties.application_headers["char_4byte"] == char_4byte + +# assert message_properties.application_headers["timestamp"] == timestamp +# assert message_properties.application_headers["UUID"] == UUID + assert message_properties.application_headers["String_Greek"] == String_Greek + assert message_properties.application_headers["String_Empty"] == String_Empty + + diff --git a/qpid/python/perftest b/qpid/python/perftest index f4d3c95e96..f867566fd0 100755 --- a/qpid/python/perftest +++ b/qpid/python/perftest @@ -44,8 +44,8 @@ def publisher(n): consumer = "consumer" queue = client.queue(consumer) channel.message_subscribe(queue="sync_queue", destination=consumer) - channel.message_flow(consumer, 0, 0xFFFFFFFF) - channel.message_flow(consumer, 1, 0xFFFFFFFF) + channel.message_flow(consumer, 0, 0xFFFFFFFFL) + channel.message_flow(consumer, 1, 0xFFFFFFFFL) queue.get(block = True) print "done" channel.session_close() @@ -62,8 +62,8 @@ def consumer(): consumer = "consumer" queue = client.queue(consumer) channel.message_subscribe(queue="message_queue", destination=consumer) - channel.message_flow(consumer, 0, 0xFFFFFFFF) - channel.message_flow(consumer, 1, 0xFFFFFFFF) + channel.message_flow(consumer, 0, 0xFFFFFFFFL) + channel.message_flow(consumer, 1, 0xFFFFFFFFL) final = "That's done" content = "" message = None diff --git a/qpid/python/qmf/console.py b/qpid/python/qmf/console.py index 867d707f31..3b99595f1f 100644 --- a/qpid/python/qmf/console.py +++ b/qpid/python/qmf/console.py @@ -20,6 +20,7 @@ """ Console API for Qpid Management Framework """ import os +import platform import qpid import struct import socket @@ -27,7 +28,7 @@ import re from qpid.peer import Closed from qpid.session import SessionDetached from qpid.connection import Connection, ConnectionFailed -from qpid.datatypes import UUID, uuid4, Message, RangedSet +from qpid.datatypes import Message, RangedSet from qpid.util import connect, ssl, URL from qpid.codec010 import StringCodec as Codec from threading import Lock, Condition, Thread @@ -414,7 +415,7 @@ class Session: self.console.brokerDisconnected(broker) def _handleBrokerResp(self, broker, codec, seq): - broker.brokerId = UUID(codec.read_uuid()) + broker.brokerId = codec.read_uuid() if self.console != None: self.console.brokerInfo(broker) @@ -615,7 +616,7 @@ class Session: elif typecode == 11: data = codec.read_uint8() != 0 # BOOL elif typecode == 12: data = codec.read_float() # FLOAT elif typecode == 13: data = codec.read_double() # DOUBLE - elif typecode == 14: data = UUID(codec.read_uuid()) # UUID + elif typecode == 14: data = codec.read_uuid() # UUID elif typecode == 15: data = codec.read_map() # FTABLE elif typecode == 16: data = codec.read_int8() # S8 elif typecode == 17: data = codec.read_int16() # S16 @@ -1230,6 +1231,7 @@ class ManagedConnection(Thread): class Broker: """ This object represents a connection (or potential connection) to a QMF broker. """ SYNC_TIME = 60 + nextSeq = 1 def __init__(self, session, host, port, authMech, authUser, authPass, ssl=False): self.session = session @@ -1242,7 +1244,8 @@ class Broker: self.error = None self.brokerId = None self.connected = False - self.amqpSessionId = "%s.%d" % (os.uname()[1], os.getpid()) + self.amqpSessionId = "%s.%d.%d" % (platform.uname()[1], os.getpid(), Broker.nextSeq) + Broker.nextSeq += 1 if self.session.manageConnections: self.thread = ManagedConnection(self) self.thread.start() @@ -1334,8 +1337,8 @@ class Broker: acquire_mode=self.amqpSession.acquire_mode.pre_acquired) self.amqpSession.incoming("rdest").listen(self._replyCb, self._exceptionCb) self.amqpSession.message_set_flow_mode(destination="rdest", flow_mode=1) - self.amqpSession.message_flow(destination="rdest", unit=0, value=0xFFFFFFFF) - self.amqpSession.message_flow(destination="rdest", unit=1, value=0xFFFFFFFF) + self.amqpSession.message_flow(destination="rdest", unit=0, value=0xFFFFFFFFL) + self.amqpSession.message_flow(destination="rdest", unit=1, value=0xFFFFFFFFL) self.topicName = "topic-%s" % self.amqpSessionId self.amqpSession.queue_declare(queue=self.topicName, exclusive=True, auto_delete=True) @@ -1344,8 +1347,8 @@ class Broker: acquire_mode=self.amqpSession.acquire_mode.pre_acquired) self.amqpSession.incoming("tdest").listen(self._replyCb) self.amqpSession.message_set_flow_mode(destination="tdest", flow_mode=1) - self.amqpSession.message_flow(destination="tdest", unit=0, value=0xFFFFFFFF) - self.amqpSession.message_flow(destination="tdest", unit=1, value=0xFFFFFFFF) + self.amqpSession.message_flow(destination="tdest", unit=0, value=0xFFFFFFFFL) + self.amqpSession.message_flow(destination="tdest", unit=1, value=0xFFFFFFFFL) self.connected = True self.session._handleBrokerConnect(self) diff --git a/qpid/python/qpid/codec010.py b/qpid/python/qpid/codec010.py index f34025ef17..f07362c38d 100644 --- a/qpid/python/qpid/codec010.py +++ b/qpid/python/qpid/codec010.py @@ -19,7 +19,7 @@ import datetime from packer import Packer -from datatypes import serial, timestamp, RangedSet, Struct +from datatypes import serial, timestamp, RangedSet, Struct, UUID class CodecException(Exception): pass @@ -118,6 +118,8 @@ class Codec(Packer): def read_vbin8(self): return self.read(self.read_uint8()) def write_vbin8(self, b): + if isinstance(b, buffer): + b = str(b) self.write_uint8(len(b)) self.write(b) @@ -131,10 +133,17 @@ class Codec(Packer): def write_str16(self, s): self.write_vbin16(s.encode("utf8")) + def read_str16_latin(self): + return self.read_vbin16().decode("iso-8859-15") + def write_str16_latin(self, s): + self.write_vbin16(s.encode("iso-8859-15")) + def read_vbin16(self): return self.read(self.read_uint16()) def write_vbin16(self, b): + if isinstance(b, buffer): + b = str(b) self.write_uint16(len(b)) self.write(b) @@ -158,6 +167,8 @@ class Codec(Packer): def read_vbin32(self): return self.read(self.read_uint32()) def write_vbin32(self, b): + if isinstance(b, buffer): + b = str(b) self.write_uint32(len(b)) self.write(b) @@ -166,7 +177,7 @@ class Codec(Packer): if m is not None: sc.write_uint32(len(m)) for k, v in m.items(): - type = self.spec.encoding(v.__class__) + type = self.spec.encoding(v) if type == None: raise CodecException("no encoding for %s" % v.__class__) sc.write_str8(k) @@ -191,9 +202,9 @@ class Codec(Packer): sc = StringCodec(self.spec) if a is not None: if len(a) > 0: - type = self.spec.encoding(a[0].__class__) + type = self.spec.encoding(a[0]) else: - type = self.spec.encoding(None.__class__) + type = self.spec.encoding(None) sc.write_uint8(type.code) sc.write_uint32(len(a)) for o in a: @@ -216,7 +227,7 @@ class Codec(Packer): if l is not None: sc.write_uint32(len(l)) for o in l: - type = self.spec.encoding(o.__class__) + type = self.spec.encoding(o) sc.write_uint8(type.code) type.encode(sc, o) self.write_vbin32(sc.encoded) @@ -273,9 +284,11 @@ class Codec(Packer): getattr(self, attr)(n) def read_uuid(self): - return self.unpack("16s") + return UUID(self.unpack("16s")) def write_uuid(self, s): + if isinstance(s, UUID): + s = s.bytes self.pack("16s", s) def read_bin128(self): diff --git a/qpid/python/qpid/datatypes.py b/qpid/python/qpid/datatypes.py index eb1f86b0b0..b2dcbe74ab 100644 --- a/qpid/python/qpid/datatypes.py +++ b/qpid/python/qpid/datatypes.py @@ -125,7 +125,7 @@ def serial(o): class Serial: def __init__(self, value): - self.value = value & 0xFFFFFFFF + self.value = value & 0xFFFFFFFFL def __hash__(self): return hash(self.value) @@ -136,8 +136,8 @@ class Serial: other = serial(other) - delta = (self.value - other.value) & 0xFFFFFFFF - neg = delta & 0x80000000 + delta = (self.value - other.value) & 0xFFFFFFFFL + neg = delta & 0x80000000L mag = delta & 0x7FFFFFFF if neg: @@ -289,7 +289,8 @@ class UUID: def __cmp__(self, other): if isinstance(other, UUID): return cmp(self.bytes, other.bytes) - raise NotImplemented() + else: + return -1 def __str__(self): return "%08x-%04x-%04x-%04x-%04x%08x" % struct.unpack("!LHHHHL", self.bytes) diff --git a/qpid/python/qpid/delegates.py b/qpid/python/qpid/delegates.py index 7cfd9b11db..a720e2e1c7 100644 --- a/qpid/python/qpid/delegates.py +++ b/qpid/python/qpid/delegates.py @@ -21,6 +21,7 @@ import os, connection, session from util import notify from datatypes import RangedSet from logging import getLogger +import sys log = getLogger("qpid.io.ctl") @@ -141,7 +142,10 @@ class Client(Delegate): PROPERTIES = {"product": "qpid python client", "version": "development", - "platform": os.name} + "platform": os.name, + "qpid.client_process": os.path.basename(sys.argv[0]), + "qpid.client_pid": os.getpid(), + "qpid.client_ppid": os.getppid()} def __init__(self, connection, username="guest", password="guest", mechanism="PLAIN", heartbeat=None): diff --git a/qpid/python/qpid/disp.py b/qpid/python/qpid/disp.py index e46cb33c60..1b315c9d98 100644 --- a/qpid/python/qpid/disp.py +++ b/qpid/python/qpid/disp.py @@ -21,16 +21,115 @@ from time import strftime, gmtime +class Header: + """ """ + NONE = 1 + KMG = 2 + YN = 3 + Y = 4 + TIME_LONG = 5 + TIME_SHORT = 6 + DURATION = 7 + + def __init__(self, text, format=NONE): + self.text = text + self.format = format + + def __repr__(self): + return self.text + + def __str__(self): + return self.text + + def formatted(self, value): + try: + if value == None: + return '' + if self.format == Header.NONE: + return value + if self.format == Header.KMG: + return self.num(value) + if self.format == Header.YN: + if value: + return 'Y' + return 'N' + if self.format == Header.Y: + if value: + return 'Y' + return '' + if self.format == Header.TIME_LONG: + return strftime("%c", gmtime(value / 1000000000)) + if self.format == Header.TIME_SHORT: + return strftime("%X", gmtime(value / 1000000000)) + if self.format == Header.DURATION: + if value < 0: value = 0 + sec = value / 1000000000 + min = sec / 60 + hour = min / 60 + day = hour / 24 + result = "" + if day > 0: + result = "%dd " % day + if hour > 0 or result != "": + result += "%dh " % (hour % 24) + if min > 0 or result != "": + result += "%dm " % (min % 60) + result += "%ds" % (sec % 60) + return result + except: + return "?" + + def numCell(self, value, tag): + fp = float(value) / 1000. + if fp < 10.0: + return "%1.2f%c" % (fp, tag) + if fp < 100.0: + return "%2.1f%c" % (fp, tag) + return "%4d%c" % (value / 1000, tag) + + def num(self, value): + if value < 1000: + return "%4d" % value + if value < 1000000: + return self.numCell(value, 'k') + value /= 1000 + if value < 1000000: + return self.numCell(value, 'm') + value /= 1000 + return self.numCell(value, 'g') + + class Display: """ Display formatting for QPID Management CLI """ - def __init__ (self): - self.tableSpacing = 2 - self.tablePrefix = " " + def __init__(self, spacing=2, prefix=" "): + self.tableSpacing = spacing + self.tablePrefix = prefix self.timestampFormat = "%X" - def table (self, title, heads, rows): - """ Print a formatted table with autosized columns """ + def formattedTable(self, title, heads, rows): + fRows = [] + for row in rows: + fRow = [] + col = 0 + for cell in row: + fRow.append(heads[col].formatted(cell)) + col += 1 + fRows.append(fRow) + headtext = [] + for head in heads: + headtext.append(head.text) + self.table(title, headtext, fRows) + + def table(self, title, heads, rows): + """ Print a table with autosized columns """ + + # Pad the rows to the number of heads + for row in rows: + diff = len(heads) - len(row) + for idx in range(diff): + row.append("") + print title if len (rows) == 0: return @@ -77,3 +176,59 @@ class Display: def timestamp (self, nsec): """ Format a nanosecond-since-the-epoch timestamp for printing """ return strftime (self.timestampFormat, gmtime (nsec / 1000000000)) + + def duration(self, nsec): + if nsec < 0: nsec = 0 + sec = nsec / 1000000000 + min = sec / 60 + hour = min / 60 + day = hour / 24 + result = "" + if day > 0: + result = "%dd " % day + if hour > 0 or result != "": + result += "%dh " % (hour % 24) + if min > 0 or result != "": + result += "%dm " % (min % 60) + result += "%ds" % (sec % 60) + return result + +class Sortable: + """ """ + def __init__(self, row, sortIndex): + self.row = row + self.sortIndex = sortIndex + if sortIndex >= len(row): + raise Exception("sort index exceeds row boundary") + + def __cmp__(self, other): + return cmp(self.row[self.sortIndex], other.row[self.sortIndex]) + + def getRow(self): + return self.row + +class Sorter: + """ """ + def __init__(self, heads, rows, sortCol, limit=0, inc=True): + col = 0 + for head in heads: + if head.text == sortCol: + break + col += 1 + if col == len(heads): + raise Exception("sortCol '%s', not found in headers" % sortCol) + + list = [] + for row in rows: + list.append(Sortable(row, col)) + list.sort(reverse=not inc) + count = 0 + self.sorted = [] + for row in list: + self.sorted.append(row.getRow()) + count += 1 + if count == limit: + break + + def getSorted(self): + return self.sorted diff --git a/qpid/python/qpid/management.py b/qpid/python/qpid/management.py index 477f3e8f2b..546e68ae8e 100644 --- a/qpid/python/qpid/management.py +++ b/qpid/python/qpid/management.py @@ -177,12 +177,12 @@ class managementChannel: ssn.incoming ("rdest").listen (self.replyCb) ssn.message_set_flow_mode (destination="tdest", flow_mode=1) - ssn.message_flow (destination="tdest", unit=0, value=0xFFFFFFFF) - ssn.message_flow (destination="tdest", unit=1, value=0xFFFFFFFF) + ssn.message_flow (destination="tdest", unit=0, value=0xFFFFFFFFL) + ssn.message_flow (destination="tdest", unit=1, value=0xFFFFFFFFL) ssn.message_set_flow_mode (destination="rdest", flow_mode=1) - ssn.message_flow (destination="rdest", unit=0, value=0xFFFFFFFF) - ssn.message_flow (destination="rdest", unit=1, value=0xFFFFFFFF) + ssn.message_flow (destination="rdest", unit=0, value=0xFFFFFFFFL) + ssn.message_flow (destination="rdest", unit=1, value=0xFFFFFFFFL) def setBrokerInfo (self, data): self.brokerInfo = data diff --git a/qpid/python/qpid/managementdata.py b/qpid/python/qpid/managementdata.py index 46c746c0f9..e1fd8d54eb 100644 --- a/qpid/python/qpid/managementdata.py +++ b/qpid/python/qpid/managementdata.py @@ -29,6 +29,7 @@ import re import socket import struct import os +import platform import locale from qpid.management import managementChannel, managementClient from threading import Lock @@ -202,7 +203,7 @@ class ManagementData: self.lastUnit = None self.methodSeq = 1 self.methodsPending = {} - self.sessionId = "%s.%d" % (os.uname()[1], os.getpid()) + self.sessionId = "%s.%d" % (platform.uname()[1], os.getpid()) self.broker = Broker (host) self.conn = Connection (connect (self.broker.host, self.broker.port), @@ -262,7 +263,7 @@ class ManagementData: else: return "True" elif typecode == 14: - return "%08x-%04x-%04x-%04x-%04x%08x" % struct.unpack ("!LHHHHL", value) + return str (value) elif typecode == 15: return str (value) return "*type-error*" diff --git a/qpid/python/qpid/peer.py b/qpid/python/qpid/peer.py index 648f32ceef..18d7848b8d 100644 --- a/qpid/python/qpid/peer.py +++ b/qpid/python/qpid/peer.py @@ -460,6 +460,6 @@ class IncomingCompletion: #TODO: record and manage the ranges properly range = [mark, mark] if (self.mark == -1):#hack until wraparound is implemented - self.channel.execution_complete(cumulative_execution_mark=0xFFFFFFFF, ranged_execution_set=range) + self.channel.execution_complete(cumulative_execution_mark=0xFFFFFFFFL, ranged_execution_set=range) else: self.channel.execution_complete(cumulative_execution_mark=self.mark, ranged_execution_set=range) diff --git a/qpid/python/qpid/spec010.py b/qpid/python/qpid/spec010.py index cbc85a5e8b..eabc8e2983 100644 --- a/qpid/python/qpid/spec010.py +++ b/qpid/python/qpid/spec010.py @@ -467,19 +467,31 @@ class Exception(Named, Node): node.exceptions.append(self) Node.register(self) +def direct(t): + return lambda x: t + +def map_str(s): + for c in s: + if ord(c) >= 0x80: + return "vbin16" + return "str16" + class Spec(Node): ENCODINGS = { - basestring: "vbin16", - int: "int64", - long: "int64", - float: "float", - None.__class__: "void", - list: "list", - tuple: "list", - dict: "map", - datatypes.timestamp: "datetime", - datetime.datetime: "datetime" + unicode: direct("str16"), + str: map_str, + buffer: direct("vbin32"), + int: direct("int64"), + long: direct("int64"), + float: direct("double"), + None.__class__: direct("void"), + list: direct("list"), + tuple: direct("list"), + dict: direct("map"), + datatypes.timestamp: direct("datetime"), + datetime.datetime: direct("datetime"), + datatypes.UUID: direct("uuid") } def __init__(self, major, minor, port, children): @@ -500,11 +512,14 @@ class Spec(Node): self.structs_by_name = {} self.enums = {} - def encoding(self, klass): + def encoding(self, obj): + return self._encoding(obj.__class__, obj) + + def _encoding(self, klass, obj): if Spec.ENCODINGS.has_key(klass): - return self.named[Spec.ENCODINGS[klass]] + return self.named[Spec.ENCODINGS[klass](obj)] for base in klass.__bases__: - result = self.encoding(base) + result = self._encoding(base, obj) if result != None: return result diff --git a/qpid/python/qpid/testlib.py b/qpid/python/qpid/testlib.py index 31f52169ae..7f5ac1fcd2 100644 --- a/qpid/python/qpid/testlib.py +++ b/qpid/python/qpid/testlib.py @@ -288,16 +288,16 @@ class TestBase(unittest.TestCase): else: self.uniqueTag += 1 consumer_tag = "tag" + str(self.uniqueTag) self.channel.message_subscribe(queue=queueName, destination=consumer_tag) - self.channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFF) - self.channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFF) + self.channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFFL) + self.channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFFL) return self.client.queue(consumer_tag) def subscribe(self, channel=None, **keys): channel = channel or self.channel consumer_tag = keys["destination"] channel.message_subscribe(**keys) - channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFF) - channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFF) + channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFFL) + channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFFL) def assertEmpty(self, queue): """Assert that the queue is empty""" @@ -388,5 +388,5 @@ class TestBase010(unittest.TestCase): session = session or self.session consumer_tag = keys["destination"] session.message_subscribe(**keys) - session.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFF) - session.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFF) + session.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFFL) + session.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFFL) diff --git a/qpid/python/setup.py b/qpid/python/setup.py index a49fa6ca51..069cb14a3c 100644 --- a/qpid/python/setup.py +++ b/qpid/python/setup.py @@ -19,7 +19,7 @@ # from distutils.core import setup -setup(name="qpid", version="0.1", packages=["qpid"], scripts=["amqp-doc"], - url="http://incubator.apache.org/qpid", +setup(name="qpid", version="0.5", packages=["qpid"], scripts=["amqp-doc"], + url="http://qpid.apache.org/", license="Apache Software License", description="Python language client implementation for Apache Qpid") diff --git a/qpid/python/tests/codec010.py b/qpid/python/tests/codec010.py index 1912eac591..a1f89dc3f4 100644 --- a/qpid/python/tests/codec010.py +++ b/qpid/python/tests/codec010.py @@ -23,7 +23,7 @@ from unittest import TestCase from qpid.spec010 import load from qpid.codec010 import StringCodec from qpid.testlib import testrunner -from qpid.datatypes import timestamp +from qpid.datatypes import timestamp, uuid4 class CodecTest(TestCase): @@ -42,6 +42,17 @@ class CodecTest(TestCase): def testMapString(self): self.check("map", {"string": "this is a test"}) + def testMapUnicode(self): + self.check("map", {"unicode": u"this is a unicode test"}) + + def testMapBinary(self): + self.check("map", {"binary": "\x7f\xb4R^\xe5\xf0:\x89\x96E1\xf6\xfe\xb9\x1b\xf5"}) + + def testMapBuffer(self): + s = "\x7f\xb4R^\xe5\xf0:\x89\x96E1\xf6\xfe\xb9\x1b\xf5" + dec = self.check("map", {"buffer": buffer(s)}, False) + assert dec["buffer"] == s + def testMapInt(self): self.check("map", {"int": 3}) @@ -68,14 +79,20 @@ class CodecTest(TestCase): def testMapList(self): self.check("map", {"list": [1, "two", 3.0, -4]}) + def testMapUUID(self): + self.check("map", {"uuid": uuid4()}) + def testMapAll(self): decoded = self.check("map", {"string": "this is a test", + "unicode": u"this is a unicode test", + "binary": "\x7f\xb4R^\xe5\xf0:\x89\x96E1\xf6\xfe\xb9\x1b\xf5", "int": 3, "long": 2**32, "timestamp": timestamp(0), "none": None, "map": {"string": "nested map"}, - "list": [1, "two", 3.0, -4]}) + "list": [1, "two", 3.0, -4], + "uuid": uuid4()}) assert isinstance(decoded["timestamp"], timestamp) def testMapEmpty(self): diff --git a/qpid/python/tests/datatypes.py b/qpid/python/tests/datatypes.py index 4b9e1bcc78..e9e09094fa 100644 --- a/qpid/python/tests/datatypes.py +++ b/qpid/python/tests/datatypes.py @@ -25,16 +25,16 @@ from qpid.datatypes import * class SerialTest(TestCase): def test(self): - for s in (serial(0), serial(0x8FFFFFFF), serial(0xFFFFFFFF)): + for s in (serial(0), serial(0x8FFFFFFFL), serial(0xFFFFFFFFL)): assert s + 1 > s assert s - 1 < s assert s < s + 1 assert s > s - 1 - assert serial(0xFFFFFFFF) + 1 == serial(0) + assert serial(0xFFFFFFFFL) + 1 == serial(0) - assert min(serial(0xFFFFFFFF), serial(0x0)) == serial(0xFFFFFFFF) - assert max(serial(0xFFFFFFFF), serial(0x0)) == serial(0x0) + assert min(serial(0xFFFFFFFFL), serial(0x0)) == serial(0xFFFFFFFFL) + assert max(serial(0xFFFFFFFFL), serial(0x0)) == serial(0x0) def testIncr(self): s = serial(0) @@ -44,7 +44,7 @@ class SerialTest(TestCase): def testIn(self): l = [serial(1), serial(2), serial(3), serial(4)] assert serial(1) in l - assert serial(0xFFFFFFFF + 2) in l + assert serial(0xFFFFFFFFL + 2) in l assert 4 in l def testNone(self): diff --git a/qpid/python/tests_0-10/alternate_exchange.py b/qpid/python/tests_0-10/alternate_exchange.py index aac8a5e15b..3b75145907 100644 --- a/qpid/python/tests_0-10/alternate_exchange.py +++ b/qpid/python/tests_0-10/alternate_exchange.py @@ -41,16 +41,16 @@ class AlternateExchangeTests(TestBase010): session.queue_declare(queue="returns", exclusive=True, auto_delete=True) session.exchange_bind(queue="returns", exchange="secondary") session.message_subscribe(destination="a", queue="returns") - session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL) returned = session.incoming("a") #declare, bind (to the primary exchange) and consume from a queue for 'processed' messages session.queue_declare(queue="processed", exclusive=True, auto_delete=True) session.exchange_bind(queue="processed", exchange="primary", binding_key="my-key") session.message_subscribe(destination="b", queue="processed") - session.message_flow(destination="b", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="b", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="b", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="b", unit=session.credit_unit.byte, value=0xFFFFFFFFL) processed = session.incoming("b") #publish to the primary exchange @@ -81,8 +81,8 @@ class AlternateExchangeTests(TestBase010): session.queue_declare(queue="deleted", exclusive=True, auto_delete=True) session.exchange_bind(exchange="dlq", queue="deleted") session.message_subscribe(destination="dlq", queue="deleted") - session.message_flow(destination="dlq", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="dlq", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="dlq", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="dlq", unit=session.credit_unit.byte, value=0xFFFFFFFFL) dlq = session.incoming("dlq") #create a queue using the dlq as its alternate exchange: diff --git a/qpid/python/tests_0-10/broker.py b/qpid/python/tests_0-10/broker.py index d4aa57765c..81d723e322 100644 --- a/qpid/python/tests_0-10/broker.py +++ b/qpid/python/tests_0-10/broker.py @@ -36,8 +36,8 @@ class BrokerTests(TestBase010): # No ack consumer ctag = "tag1" session.message_subscribe(queue = "myqueue", destination = ctag) - session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFFL) body = "test no-ack" session.message_transfer(message=Message(session.delivery_properties(routing_key="myqueue"), body)) msg = session.incoming(ctag).get(timeout = 5) @@ -47,8 +47,8 @@ class BrokerTests(TestBase010): session.queue_declare(queue = "otherqueue", exclusive=True, auto_delete=True) ctag = "tag2" session.message_subscribe(queue = "otherqueue", destination = ctag, accept_mode = 1) - session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFFL) body = "test ack" session.message_transfer(message=Message(session.delivery_properties(routing_key="otherqueue"), body)) msg = session.incoming(ctag).get(timeout = 5) @@ -64,8 +64,8 @@ class BrokerTests(TestBase010): session.exchange_bind(queue="test-queue", exchange="amq.fanout") consumer_tag = "tag1" session.message_subscribe(queue="test-queue", destination=consumer_tag) - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = consumer_tag) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = consumer_tag) + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = consumer_tag) + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = consumer_tag) queue = session.incoming(consumer_tag) body = "Immediate Delivery" @@ -86,8 +86,8 @@ class BrokerTests(TestBase010): consumer_tag = "tag1" session.message_subscribe(queue="test-queue", destination=consumer_tag) - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = consumer_tag) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = consumer_tag) + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = consumer_tag) + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = consumer_tag) queue = session.incoming(consumer_tag) msg = queue.get(timeout=5) self.assert_(msg.body == body) diff --git a/qpid/python/tests_0-10/dtx.py b/qpid/python/tests_0-10/dtx.py index 25c2defd3b..2823385a3b 100644 --- a/qpid/python/tests_0-10/dtx.py +++ b/qpid/python/tests_0-10/dtx.py @@ -575,7 +575,7 @@ class DtxTests(TestBase010): session2.dtx_start(xid=tx) session2.message_subscribe(queue="dummy", destination="dummy") session2.message_flow(destination="dummy", unit=session2.credit_unit.message, value=1) - session2.message_flow(destination="dummy", unit=session2.credit_unit.byte, value=0xFFFFFFFF) + session2.message_flow(destination="dummy", unit=session2.credit_unit.byte, value=0xFFFFFFFFL) msg = session2.incoming("dummy").get(timeout=1) session2.message_accept(RangedSet(msg.id)) session2.message_cancel(destination="dummy") @@ -736,7 +736,7 @@ class DtxTests(TestBase010): #consume from src: session.message_subscribe(destination="temp-swap", queue=src) session.message_flow(destination="temp-swap", unit=session.credit_unit.message, value=1) - session.message_flow(destination="temp-swap", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="temp-swap", unit=session.credit_unit.byte, value=0xFFFFFFFFL) msg = session.incoming("temp-swap").get(timeout=1) session.message_cancel(destination="temp-swap") session.message_accept(RangedSet(msg.id)) @@ -753,7 +753,7 @@ class DtxTests(TestBase010): def assertMessageId(self, expected, queue): self.session.message_subscribe(queue=queue, destination="results") self.session.message_flow(destination="results", unit=self.session.credit_unit.message, value=1) - self.session.message_flow(destination="results", unit=self.session.credit_unit.byte, value=0xFFFFFFFF) + self.session.message_flow(destination="results", unit=self.session.credit_unit.byte, value=0xFFFFFFFFL) self.assertEqual(expected, self.getMessageProperty(self.session.incoming("results").get(timeout=1), 'correlation_id')) self.session.message_cancel(destination="results") diff --git a/qpid/python/tests_0-10/example.py b/qpid/python/tests_0-10/example.py index 83d208192b..e36907d501 100644 --- a/qpid/python/tests_0-10/example.py +++ b/qpid/python/tests_0-10/example.py @@ -69,8 +69,8 @@ class ExampleTest (TestBase010): # field that is filled if the reply includes content. In this case the # interesting field is the consumer_tag. session.message_subscribe(queue="test-queue", destination="consumer_tag") - session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL) # We can use the session.incoming(...) method to access the messages # delivered for our consumer_tag. diff --git a/qpid/python/tests_0-10/exchange.py b/qpid/python/tests_0-10/exchange.py index 4b5dc78143..738e3c4def 100644 --- a/qpid/python/tests_0-10/exchange.py +++ b/qpid/python/tests_0-10/exchange.py @@ -108,8 +108,8 @@ class TestHelper(TestBase010): else: self.uniqueTag += 1 consumer_tag = "tag" + str(self.uniqueTag) self.session.message_subscribe(queue=queueName, destination=consumer_tag) - self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.message, value=0xFFFFFFFF) - self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.byte, value=0xFFFFFFFF) + self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.message, value=0xFFFFFFFFL) + self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.byte, value=0xFFFFFFFFL) return self.session.incoming(consumer_tag) diff --git a/qpid/python/tests_0-10/management.py b/qpid/python/tests_0-10/management.py index 0632d85da4..545dc3db3b 100644 --- a/qpid/python/tests_0-10/management.py +++ b/qpid/python/tests_0-10/management.py @@ -192,8 +192,8 @@ class ManagementTest (TestBase010): "Consume the messages of the queue and check they are all there in order" session.message_subscribe(queue="src-queue", destination="tag") - session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue = session.incoming("tag") for count in twenty: consumed_msg = queue.get(timeout=1) diff --git a/qpid/python/tests_0-10/message.py b/qpid/python/tests_0-10/message.py index cbcef5602f..f80eca6363 100644 --- a/qpid/python/tests_0-10/message.py +++ b/qpid/python/tests_0-10/message.py @@ -230,8 +230,8 @@ class MessageTests(TestBase010): session.message_subscribe(destination="my-consumer", queue="test-queue-4") myqueue = session.incoming("my-consumer") - session.message_flow(destination="my-consumer", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="my-consumer", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="my-consumer", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="my-consumer", unit=session.credit_unit.byte, value=0xFFFFFFFFL) #should flush here @@ -258,8 +258,8 @@ class MessageTests(TestBase010): session.queue_declare(queue="test-ack-queue", auto_delete=True) session.message_subscribe(queue = "test-ack-queue", destination = "consumer") - session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue = session.incoming("consumer") delivery_properties = session.delivery_properties(routing_key="test-ack-queue") @@ -289,8 +289,8 @@ class MessageTests(TestBase010): session.close(timeout=10) session = self.session - session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue = session.incoming("checker") msg3b = queue.get(timeout=1) @@ -311,16 +311,16 @@ class MessageTests(TestBase010): session.exchange_bind(queue = "r", exchange = "amq.fanout") session.message_subscribe(queue = "q", destination = "consumer") - session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFFL) session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "blah, blah")) msg = session.incoming("consumer").get(timeout = 1) self.assertEquals(msg.body, "blah, blah") session.message_reject(RangedSet(msg.id)) session.message_subscribe(queue = "r", destination = "checker") - session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFFL) msg = session.incoming("checker").get(timeout = 1) self.assertEquals(msg.body, "blah, blah") @@ -341,7 +341,7 @@ class MessageTests(TestBase010): #set message credit to finite amount (less than enough for all messages) session.message_flow(unit = session.credit_unit.message, value = 5, destination = "c") #set infinite byte credit - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "c") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "c") #check that expected number were received q = session.incoming("c") for i in range(1, 6): @@ -374,7 +374,7 @@ class MessageTests(TestBase010): #set byte credit to finite amount (less than enough for all messages) session.message_flow(unit = session.credit_unit.byte, value = msg_size*5, destination = "c") #set infinite message credit - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "c") + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "c") #check that expected number were received q = session.incoming("c") for i in range(5): @@ -405,7 +405,7 @@ class MessageTests(TestBase010): #set message credit to finite amount (less than enough for all messages) session.message_flow(unit = session.credit_unit.message, value = 5, destination = "c") #set infinite byte credit - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "c") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "c") #check that expected number were received q = session.incoming("c") for i in range(1, 6): @@ -443,7 +443,7 @@ class MessageTests(TestBase010): #set byte credit to finite amount (less than enough for all messages) session.message_flow(unit = session.credit_unit.byte, value = msg_size*5, destination = "c") #set infinite message credit - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "c") + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "c") #check that expected number were received q = session.incoming("c") msgs = [] @@ -462,6 +462,42 @@ class MessageTests(TestBase010): self.assertDataEquals(session, q.get(timeout = 1), "abcdefgh") self.assertEmpty(q) + def test_window_flush_ack_flow(self): + """ + Test basic window based flow control with unit = bytes + """ + #declare an exclusive queue + ssn = self.session + ssn.queue_declare(queue = "q", exclusive=True, auto_delete=True) + #create consumer + ssn.message_subscribe(queue = "q", destination = "c", + accept_mode=ssn.accept_mode.explicit) + ssn.message_set_flow_mode(flow_mode = ssn.flow_mode.window, destination = "c") + + #send message A + ssn.message_transfer(message=Message(ssn.delivery_properties(routing_key="q"), "A")) + + for unit in ssn.credit_unit.values(): + ssn.message_flow("c", unit, 0xFFFFFFFFL) + + q = ssn.incoming("c") + msgA = q.get(timeout=10) + + ssn.message_flush(destination="c") + + # XXX + ssn.receiver._completed.add(msgA.id) + ssn.channel.session_completed(ssn.receiver._completed) + ssn.message_accept(RangedSet(msgA.id)) + + for unit in ssn.credit_unit.values(): + ssn.message_flow("c", unit, 0xFFFFFFFFL) + + #send message B + ssn.message_transfer(message=Message(ssn.delivery_properties(routing_key="q"), "B")) + + msgB = q.get(timeout=10) + def test_subscribe_not_acquired(self): """ Test the not-acquired modes works as expected for a simple case @@ -472,11 +508,11 @@ class MessageTests(TestBase010): session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "Message %s" % i)) session.message_subscribe(queue = "q", destination = "a", acquire_mode = 1) - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "a") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") session.message_subscribe(queue = "q", destination = "b", acquire_mode = 1) - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "b") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b") + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "b") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b") for i in range(6, 11): session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "Message %s" % i)) @@ -508,8 +544,8 @@ class MessageTests(TestBase010): session.message_subscribe(queue = "q", destination = "a", acquire_mode = 1, accept_mode = 1) session.message_set_flow_mode(flow_mode = session.flow_mode.credit, destination = "a") - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "a") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") msg = session.incoming("a").get(timeout = 1) self.assertEquals("acquire me", msg.body) #message should still be on the queue: @@ -532,8 +568,8 @@ class MessageTests(TestBase010): session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "acquire me")) session.message_subscribe(queue = "q", destination = "a", acquire_mode = 1) - session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL) msg = session.incoming("a").get(timeout = 1) self.assertEquals("acquire me", msg.body) #message should still be on the queue: @@ -558,8 +594,8 @@ class MessageTests(TestBase010): session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "release me")) session.message_subscribe(queue = "q", destination = "a") - session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL) msg = session.incoming("a").get(timeout = 1) self.assertEquals("release me", msg.body) session.message_cancel(destination = "a") @@ -579,7 +615,7 @@ class MessageTests(TestBase010): session.message_subscribe(queue = "q", destination = "a") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") queue = session.incoming("a") first = queue.get(timeout = 1) for i in range(2, 10): @@ -612,7 +648,7 @@ class MessageTests(TestBase010): session.message_subscribe(queue = "q", destination = "a") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") queue = session.incoming("a") ids = [] for i in range (1, 11): @@ -637,8 +673,8 @@ class MessageTests(TestBase010): session.close(timeout=10) session = self.session - session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue = session.incoming("checker") self.assertEquals("message 4", queue.get(timeout = 1).body) @@ -656,7 +692,7 @@ class MessageTests(TestBase010): session.message_subscribe(queue = "q", destination = "a") session.message_set_flow_mode(flow_mode = 0, destination = "a") session.message_flow(unit = session.credit_unit.message, value = 5, destination = "a") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") queue = session.incoming("a") for i in range(1, 6): @@ -671,7 +707,7 @@ class MessageTests(TestBase010): #now create a not-acquired subscriber session.message_subscribe(queue = "q", destination = "b", acquire_mode=1) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b") #check it gets those not consumed queue = session.incoming("b") @@ -699,7 +735,7 @@ class MessageTests(TestBase010): #create a not-acquired subscriber session.message_subscribe(queue = "q", destination = "a", acquire_mode=1) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a") #browse through messages @@ -721,7 +757,7 @@ class MessageTests(TestBase010): #create a second not-acquired subscriber session.message_subscribe(queue = "q", destination = "b", acquire_mode=1) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b") session.message_flow(unit = session.credit_unit.message, value = 1, destination = "b") #check it gets those not consumed queue = session.incoming("b") @@ -748,12 +784,12 @@ class MessageTests(TestBase010): #create two 'browsers' session.message_subscribe(queue = "q", destination = "a", acquire_mode=1) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a") queueA = session.incoming("a") session.message_subscribe(queue = "q", destination = "b", acquire_mode=1) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "b") queueB = session.incoming("b") @@ -770,7 +806,7 @@ class MessageTests(TestBase010): #create consumer session.message_subscribe(queue = "q", destination = "c") - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "c") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "c") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "c") queueC = session.incoming("c") #consume the message then ack it @@ -787,8 +823,8 @@ class MessageTests(TestBase010): consumer_tag = "tag1" session.message_subscribe(queue="xyz", destination=consumer_tag) - session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = consumer_tag) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = consumer_tag) + session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = consumer_tag) + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = consumer_tag) queue = session.incoming(consumer_tag) msg = queue.get(timeout=1) self.assertEquals("", msg.body) @@ -827,7 +863,7 @@ class MessageTests(TestBase010): messages = session.incoming(d) sleep(1) session.message_flow(unit = session.credit_unit.message, value=2, destination=d) - session.message_flow(unit = session.credit_unit.byte, value=0xFFFFFFFF, destination=d) + session.message_flow(unit = session.credit_unit.byte, value=0xFFFFFFFFL, destination=d) assert messages.get(timeout=1).body == "second" self.assertEmpty(messages) diff --git a/qpid/python/tests_0-10/persistence.py b/qpid/python/tests_0-10/persistence.py index 815ad1f3dc..b93bb0bbfb 100644 --- a/qpid/python/tests_0-10/persistence.py +++ b/qpid/python/tests_0-10/persistence.py @@ -49,7 +49,7 @@ class PersistenceTests(TestBase010): #create consumer session.message_subscribe(queue = "q", destination = "a", accept_mode = 1, acquire_mode=0) - session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a") + session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a") session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a") queue = session.incoming("a") diff --git a/qpid/python/tests_0-10/queue.py b/qpid/python/tests_0-10/queue.py index 05e18081fa..eb38965190 100644 --- a/qpid/python/tests_0-10/queue.py +++ b/qpid/python/tests_0-10/queue.py @@ -49,8 +49,8 @@ class QueueTests(TestBase010): #send a further message and consume it, ensuring that the other messages are really gone session.message_transfer(message=Message(session.delivery_properties(routing_key="test-queue"), "four")) session.message_subscribe(queue="test-queue", destination="tag") - session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue = session.incoming("tag") msg = queue.get(timeout=1) self.assertEqual("four", msg.body) @@ -182,11 +182,11 @@ class QueueTests(TestBase010): session.queue_declare(queue="queue-2", exclusive=True, auto_delete=True) session.message_subscribe(queue="queue-1", destination="queue-1") - session.message_flow(destination="queue-1", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="queue-1", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="queue-1", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="queue-1", unit=session.credit_unit.byte, value=0xFFFFFFFFL) session.message_subscribe(queue="queue-2", destination="queue-2") - session.message_flow(destination="queue-2", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="queue-2", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="queue-2", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="queue-2", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue1 = session.incoming("queue-1") queue2 = session.incoming("queue-2") @@ -283,8 +283,8 @@ class QueueTests(TestBase010): #empty queue: session.message_subscribe(destination="consumer_tag", queue="delete-me-2") - session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL) queue = session.incoming("consumer_tag") msg = queue.get(timeout=1) self.assertEqual("message", msg.body) diff --git a/qpid/python/tests_0-10/tx.py b/qpid/python/tests_0-10/tx.py index da162d54ec..463fbcb888 100644 --- a/qpid/python/tests_0-10/tx.py +++ b/qpid/python/tests_0-10/tx.py @@ -251,13 +251,13 @@ class TxTests(TestBase010): session = session or self.session consumer_tag = keys["destination"] session.message_subscribe(**keys) - session.message_flow(destination=consumer_tag, unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination=consumer_tag, unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination=consumer_tag, unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination=consumer_tag, unit=session.credit_unit.byte, value=0xFFFFFFFFL) def enable_flow(self, tag, session=None): session = session or self.session - session.message_flow(destination=tag, unit=session.credit_unit.message, value=0xFFFFFFFF) - session.message_flow(destination=tag, unit=session.credit_unit.byte, value=0xFFFFFFFF) + session.message_flow(destination=tag, unit=session.credit_unit.message, value=0xFFFFFFFFL) + session.message_flow(destination=tag, unit=session.credit_unit.byte, value=0xFFFFFFFFL) def complete(self, session, msg): session.receiver._completed.add(msg.id)#TODO: this may be done automatically diff --git a/qpid/ruby/Makefile b/qpid/ruby/Makefile new file mode 100644 index 0000000000..9cac3207c0 --- /dev/null +++ b/qpid/ruby/Makefile @@ -0,0 +1,47 @@ +# +# 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. +# + +SASL_DIR = ext/sasl +SASL_MODULE = $(SASL_DIR)/sasl.so +RUBY_LIB = lib +SPEC_CACHE_SCRIPT = sc.rb + +.PHONY: spec_cache all clean distclean + +all : build + +$(SASL_MODULE) : $(SASL_DIR)/sasl.c + cd $(SASL_DIR); ruby extconf.rb + $(MAKE) -C $(SASL_DIR) + +spec_cache : + echo "require 'qpid'" > $(SPEC_CACHE_SCRIPT) + echo "Qpid::Spec010::load()" >> $(SPEC_CACHE_SCRIPT) + ruby -I $(RUBY_LIB) -I $(SASL_DIR) $(SPEC_CACHE_SCRIPT) + rm $(SPEC_CACHE_SCRIPT) + +build: $(SASL_MODULE) spec_cache + +clean: + cd $(SASL_DIR); make clean + +distclean: + cd $(SASL_DIR); make distclean + rm -rf $(RUBY_LIB)/qpid/spec_cache + diff --git a/qpid/ruby/lib/qpid/delegates.rb b/qpid/ruby/lib/qpid/delegates.rb index 9707cdbc76..171f310e48 100644 --- a/qpid/ruby/lib/qpid/delegates.rb +++ b/qpid/ruby/lib/qpid/delegates.rb @@ -168,7 +168,10 @@ module Qpid # analog in Ruby PROPERTIES = {"product" => "qpid python client", "version" => "development", - "platform" => Config::CONFIG["build_os"]} + "platform" => Config::CONFIG["build_os"], + "qpid.client_process" => File.basename($0), + "qpid.client_pid" => Process.pid, + "qpid.client_ppid" => Process.ppid} def initialize(connection, args) diff --git a/qpid/specs/management-schema.xml b/qpid/specs/management-schema.xml index 307ced1245..bc38350a45 100644 --- a/qpid/specs/management-schema.xml +++ b/qpid/specs/management-schema.xml @@ -70,6 +70,7 @@ <property name="mgmtPubInterval" type="uint16" access="RW" unit="second" min="1" desc="Interval for management broadcasts"/> <property name="version" type="sstr" access="RO" desc="Running software version"/> <property name="dataDir" type="sstr" access="RO" optional="y" desc="Persistent configuration storage location"/> + <statistic name="uptime" type="deltaTime"/> <method name="echo" desc="Request a response to test the path to the management broker"> <arg name="sequence" dir="IO" type="uint32" default="0"/> @@ -206,6 +207,9 @@ <property name="SystemConnection" type="bool" access="RC" desc="Infrastucture/ Inter-system connection (Cluster, Federation, ...)"/> <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="sstr" access="RO" optional="y" desc="Name of executable running as remote client"/> + <property name="remotePid" type="uint32" access="RO" optional="y" desc="Process ID of remote client"/> + <property name="remoteParentPid" type="uint32" access="RO" optional="y" desc="Parent Process ID of remote client"/> <statistic name="closing" type="bool" desc="This client is closing by management request"/> <statistic name="framesFromClient" type="count64"/> <statistic name="framesToClient" type="count64"/> |